From 0d172eb21605e6c477abef9c50e10122d06b509f Mon Sep 17 00:00:00 2001 From: wadzone Date: Wed, 23 Oct 2013 08:15:44 -0700 Subject: [PATCH 01/10] Initial commit --- .gitignore | 21 ++++++ LICENSE | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 4 ++ 3 files changed, 216 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e13704 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Xcode +.DS_Store +*/build/* +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +profile +*.moved-aside +DerivedData +.idea/ +*.hmap +*.xccheckout + +#CocoaPods +Pods diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a5c267a --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +oauth-ios +========= + +OAuth.io library for iOS From e1d6525bbab8273c37818aee5ff8cbed670ef5b1 Mon Sep 17 00:00:00 2001 From: Walid TERMELLIL Date: Wed, 23 Oct 2013 17:18:17 +0200 Subject: [PATCH 02/10] first commit --- Demo/oauthio.xcodeproj/project.pbxproj | 515 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + Demo/oauthio/AppDelegate.h | 18 + Demo/oauthio/AppDelegate.m | 69 +++ .../NSURLRequest+NSURLRequestAllowSSL.h | 24 + .../NSURLRequest+NSURLRequestAllowSSL.m | 27 + Demo/oauthio/OAuthIO.h | 39 ++ Demo/oauthio/OAuthIO.m | 66 +++ Demo/oauthio/OAuthIOModal.h | 52 ++ Demo/oauthio/OAuthIOModal.m | 242 ++++++++ Demo/oauthio/OAuthIOModal.xib | 32 ++ Demo/oauthio/OAuthIORequest.h | 40 ++ Demo/oauthio/OAuthIORequest.m | 111 ++++ Demo/oauthio/ViewController.h | 27 + Demo/oauthio/ViewController.m | 98 ++++ Demo/oauthio/en.lproj/InfoPlist.strings | 2 + Demo/oauthio/en.lproj/ViewController_iPad.xib | 51 ++ .../en.lproj/ViewController_iPhone.xib | 84 +++ Demo/oauthio/logo.png | Bin 0 -> 9427 bytes Demo/oauthio/main.m | 18 + Demo/oauthio/oauthio-Info.plist | 56 ++ Demo/oauthio/oauthio-Prefix.pch | 14 + Demo/oauthio/webshell-logo-rc1-2.png | Bin 0 -> 13462 bytes Demo/oauthioTests/en.lproj/InfoPlist.strings | 2 + Demo/oauthioTests/oauthioTests-Info.plist | 22 + Demo/oauthioTests/oauthioTests.h | 13 + Demo/oauthioTests/oauthioTests.m | 32 ++ README.md | 73 ++- Src/NSURLRequest+NSURLRequestAllowSSL.h | 24 + Src/NSURLRequest+NSURLRequestAllowSSL.m | 27 + Src/OAuthIO.h | 39 ++ Src/OAuthIO.m | 66 +++ Src/OAuthIOModal.h | 52 ++ Src/OAuthIOModal.m | 242 ++++++++ Src/OAuthIOModal.xib | 32 ++ Src/OAuthIORequest.h | 40 ++ Src/OAuthIORequest.m | 111 ++++ 37 files changed, 2364 insertions(+), 3 deletions(-) create mode 100644 Demo/oauthio.xcodeproj/project.pbxproj create mode 100644 Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Demo/oauthio/AppDelegate.h create mode 100644 Demo/oauthio/AppDelegate.m create mode 100644 Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.h create mode 100644 Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.m create mode 100644 Demo/oauthio/OAuthIO.h create mode 100644 Demo/oauthio/OAuthIO.m create mode 100644 Demo/oauthio/OAuthIOModal.h create mode 100644 Demo/oauthio/OAuthIOModal.m create mode 100644 Demo/oauthio/OAuthIOModal.xib create mode 100644 Demo/oauthio/OAuthIORequest.h create mode 100644 Demo/oauthio/OAuthIORequest.m create mode 100644 Demo/oauthio/ViewController.h create mode 100644 Demo/oauthio/ViewController.m create mode 100644 Demo/oauthio/en.lproj/InfoPlist.strings create mode 100644 Demo/oauthio/en.lproj/ViewController_iPad.xib create mode 100644 Demo/oauthio/en.lproj/ViewController_iPhone.xib create mode 100644 Demo/oauthio/logo.png create mode 100644 Demo/oauthio/main.m create mode 100644 Demo/oauthio/oauthio-Info.plist create mode 100644 Demo/oauthio/oauthio-Prefix.pch create mode 100644 Demo/oauthio/webshell-logo-rc1-2.png create mode 100644 Demo/oauthioTests/en.lproj/InfoPlist.strings create mode 100644 Demo/oauthioTests/oauthioTests-Info.plist create mode 100644 Demo/oauthioTests/oauthioTests.h create mode 100644 Demo/oauthioTests/oauthioTests.m create mode 100644 Src/NSURLRequest+NSURLRequestAllowSSL.h create mode 100644 Src/NSURLRequest+NSURLRequestAllowSSL.m create mode 100644 Src/OAuthIO.h create mode 100644 Src/OAuthIO.m create mode 100644 Src/OAuthIOModal.h create mode 100644 Src/OAuthIOModal.m create mode 100644 Src/OAuthIOModal.xib create mode 100644 Src/OAuthIORequest.h create mode 100644 Src/OAuthIORequest.m diff --git a/Demo/oauthio.xcodeproj/project.pbxproj b/Demo/oauthio.xcodeproj/project.pbxproj new file mode 100644 index 0000000..865b9e7 --- /dev/null +++ b/Demo/oauthio.xcodeproj/project.pbxproj @@ -0,0 +1,515 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + CF444ACF17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = CF444ACE17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m */; }; + CF79EF5D17A7C92E0015C0DE /* OAuthIORequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF79EF5C17A7C92E0015C0DE /* OAuthIORequest.m */; }; + CF79EF6417A7F7390015C0DE /* OAuthIOModal.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF79EF6317A7F7390015C0DE /* OAuthIOModal.xib */; }; + CF79EF6717A7F7870015C0DE /* OAuthIOModal.m in Sources */ = {isa = PBXBuildFile; fileRef = CF79EF6617A7F7870015C0DE /* OAuthIOModal.m */; }; + CF79EF6B17A80C9D0015C0DE /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = CF79EF6917A80C9D0015C0DE /* logo.png */; }; + CF79EF6C17A80C9D0015C0DE /* webshell-logo-rc1-2.png in Resources */ = {isa = PBXBuildFile; fileRef = CF79EF6A17A80C9D0015C0DE /* webshell-logo-rc1-2.png */; }; + CFC4318117A6A30700C828F8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318017A6A30700C828F8 /* UIKit.framework */; }; + CFC4318317A6A30700C828F8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318217A6A30700C828F8 /* Foundation.framework */; }; + CFC4318517A6A30700C828F8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318417A6A30700C828F8 /* CoreGraphics.framework */; }; + CFC4318B17A6A30700C828F8 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CFC4318917A6A30700C828F8 /* InfoPlist.strings */; }; + CFC4318D17A6A30700C828F8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC4318C17A6A30700C828F8 /* main.m */; }; + CFC4319117A6A30700C828F8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC4319017A6A30700C828F8 /* AppDelegate.m */; }; + CFC4319417A6A30700C828F8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC4319317A6A30700C828F8 /* ViewController.m */; }; + CFC4319717A6A30700C828F8 /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = CFC4319517A6A30700C828F8 /* ViewController_iPhone.xib */; }; + CFC4319A17A6A30700C828F8 /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = CFC4319817A6A30700C828F8 /* ViewController_iPad.xib */; }; + CFC431A217A6A30700C828F8 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC431A117A6A30700C828F8 /* SenTestingKit.framework */; }; + CFC431A317A6A30700C828F8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318017A6A30700C828F8 /* UIKit.framework */; }; + CFC431A417A6A30700C828F8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318217A6A30700C828F8 /* Foundation.framework */; }; + CFC431AC17A6A30700C828F8 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CFC431AA17A6A30700C828F8 /* InfoPlist.strings */; }; + CFC431AF17A6A30700C828F8 /* oauthioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC431AE17A6A30700C828F8 /* oauthioTests.m */; }; + CFC431BB17A6A32D00C828F8 /* OAuthIO.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC431BA17A6A32D00C828F8 /* OAuthIO.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + CFC431A517A6A30700C828F8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CFC4317317A6A30700C828F8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CFC4317B17A6A30700C828F8; + remoteInfo = oauthio; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + CF444ACD17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLRequest+NSURLRequestAllowSSL.h"; sourceTree = ""; }; + CF444ACE17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLRequest+NSURLRequestAllowSSL.m"; sourceTree = ""; }; + CF79EF5B17A7C92E0015C0DE /* OAuthIORequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIORequest.h; sourceTree = ""; }; + CF79EF5C17A7C92E0015C0DE /* OAuthIORequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIORequest.m; sourceTree = ""; }; + CF79EF6317A7F7390015C0DE /* OAuthIOModal.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OAuthIOModal.xib; sourceTree = ""; }; + CF79EF6517A7F7870015C0DE /* OAuthIOModal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIOModal.h; sourceTree = ""; }; + CF79EF6617A7F7870015C0DE /* OAuthIOModal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOModal.m; sourceTree = ""; }; + CF79EF6917A80C9D0015C0DE /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; + CF79EF6A17A80C9D0015C0DE /* webshell-logo-rc1-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "webshell-logo-rc1-2.png"; sourceTree = ""; }; + CFC4317C17A6A30700C828F8 /* oauthio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = oauthio.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CFC4318017A6A30700C828F8 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + CFC4318217A6A30700C828F8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + CFC4318417A6A30700C828F8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + CFC4318817A6A30700C828F8 /* oauthio-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "oauthio-Info.plist"; sourceTree = ""; }; + CFC4318A17A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + CFC4318C17A6A30700C828F8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + CFC4318E17A6A30700C828F8 /* oauthio-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "oauthio-Prefix.pch"; sourceTree = ""; }; + CFC4318F17A6A30700C828F8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + CFC4319017A6A30700C828F8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + CFC4319217A6A30700C828F8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + CFC4319317A6A30700C828F8 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + CFC4319617A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; + CFC4319917A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; + CFC431A017A6A30700C828F8 /* oauthioTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = oauthioTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; + CFC431A117A6A30700C828F8 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; + CFC431A917A6A30700C828F8 /* oauthioTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "oauthioTests-Info.plist"; sourceTree = ""; }; + CFC431AB17A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + CFC431AD17A6A30700C828F8 /* oauthioTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = oauthioTests.h; sourceTree = ""; }; + CFC431AE17A6A30700C828F8 /* oauthioTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = oauthioTests.m; sourceTree = ""; }; + CFC431B917A6A32D00C828F8 /* OAuthIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIO.h; sourceTree = ""; }; + CFC431BA17A6A32D00C828F8 /* OAuthIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIO.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + CFC4317917A6A30700C828F8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CFC4318117A6A30700C828F8 /* UIKit.framework in Frameworks */, + CFC4318317A6A30700C828F8 /* Foundation.framework in Frameworks */, + CFC4318517A6A30700C828F8 /* CoreGraphics.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFC4319C17A6A30700C828F8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CFC431A217A6A30700C828F8 /* SenTestingKit.framework in Frameworks */, + CFC431A317A6A30700C828F8 /* UIKit.framework in Frameworks */, + CFC431A417A6A30700C828F8 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + CF79EF6817A80C8E0015C0DE /* Images */ = { + isa = PBXGroup; + children = ( + CF79EF6917A80C9D0015C0DE /* logo.png */, + CF79EF6A17A80C9D0015C0DE /* webshell-logo-rc1-2.png */, + ); + name = Images; + sourceTree = ""; + }; + CFC4317117A6A30700C828F8 = { + isa = PBXGroup; + children = ( + CFC4318617A6A30700C828F8 /* oauthio */, + CFC431A717A6A30700C828F8 /* oauthioTests */, + CFC4317F17A6A30700C828F8 /* Frameworks */, + CFC4317D17A6A30700C828F8 /* Products */, + ); + sourceTree = ""; + }; + CFC4317D17A6A30700C828F8 /* Products */ = { + isa = PBXGroup; + children = ( + CFC4317C17A6A30700C828F8 /* oauthio.app */, + CFC431A017A6A30700C828F8 /* oauthioTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + CFC4317F17A6A30700C828F8 /* Frameworks */ = { + isa = PBXGroup; + children = ( + CFC4318017A6A30700C828F8 /* UIKit.framework */, + CFC4318217A6A30700C828F8 /* Foundation.framework */, + CFC4318417A6A30700C828F8 /* CoreGraphics.framework */, + CFC431A117A6A30700C828F8 /* SenTestingKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CFC4318617A6A30700C828F8 /* oauthio */ = { + isa = PBXGroup; + children = ( + CF79EF6817A80C8E0015C0DE /* Images */, + CFC431B817A6A31600C828F8 /* OAuthIOSDK */, + CFC4318F17A6A30700C828F8 /* AppDelegate.h */, + CFC4319017A6A30700C828F8 /* AppDelegate.m */, + CFC4319217A6A30700C828F8 /* ViewController.h */, + CFC4319317A6A30700C828F8 /* ViewController.m */, + CFC4319517A6A30700C828F8 /* ViewController_iPhone.xib */, + CFC4319817A6A30700C828F8 /* ViewController_iPad.xib */, + CFC4318717A6A30700C828F8 /* Supporting Files */, + ); + path = oauthio; + sourceTree = ""; + }; + CFC4318717A6A30700C828F8 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + CFC4318817A6A30700C828F8 /* oauthio-Info.plist */, + CFC4318917A6A30700C828F8 /* InfoPlist.strings */, + CFC4318C17A6A30700C828F8 /* main.m */, + CFC4318E17A6A30700C828F8 /* oauthio-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + CFC431A717A6A30700C828F8 /* oauthioTests */ = { + isa = PBXGroup; + children = ( + CFC431AD17A6A30700C828F8 /* oauthioTests.h */, + CFC431AE17A6A30700C828F8 /* oauthioTests.m */, + CFC431A817A6A30700C828F8 /* Supporting Files */, + ); + path = oauthioTests; + sourceTree = ""; + }; + CFC431A817A6A30700C828F8 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + CFC431A917A6A30700C828F8 /* oauthioTests-Info.plist */, + CFC431AA17A6A30700C828F8 /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + CFC431B817A6A31600C828F8 /* OAuthIOSDK */ = { + isa = PBXGroup; + children = ( + CF79EF6317A7F7390015C0DE /* OAuthIOModal.xib */, + CF79EF6517A7F7870015C0DE /* OAuthIOModal.h */, + CF79EF6617A7F7870015C0DE /* OAuthIOModal.m */, + CFC431B917A6A32D00C828F8 /* OAuthIO.h */, + CFC431BA17A6A32D00C828F8 /* OAuthIO.m */, + CF79EF5B17A7C92E0015C0DE /* OAuthIORequest.h */, + CF79EF5C17A7C92E0015C0DE /* OAuthIORequest.m */, + CF444ACD17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.h */, + CF444ACE17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m */, + ); + name = OAuthIOSDK; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + CFC4317B17A6A30700C828F8 /* oauthio */ = { + isa = PBXNativeTarget; + buildConfigurationList = CFC431B217A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthio" */; + buildPhases = ( + CFC4317817A6A30700C828F8 /* Sources */, + CFC4317917A6A30700C828F8 /* Frameworks */, + CFC4317A17A6A30700C828F8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = oauthio; + productName = oauthio; + productReference = CFC4317C17A6A30700C828F8 /* oauthio.app */; + productType = "com.apple.product-type.application"; + }; + CFC4319F17A6A30700C828F8 /* oauthioTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = CFC431B517A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthioTests" */; + buildPhases = ( + CFC4319B17A6A30700C828F8 /* Sources */, + CFC4319C17A6A30700C828F8 /* Frameworks */, + CFC4319D17A6A30700C828F8 /* Resources */, + CFC4319E17A6A30700C828F8 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + CFC431A617A6A30700C828F8 /* PBXTargetDependency */, + ); + name = oauthioTests; + productName = oauthioTests; + productReference = CFC431A017A6A30700C828F8 /* oauthioTests.octest */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + CFC4317317A6A30700C828F8 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = Webshell; + }; + buildConfigurationList = CFC4317617A6A30700C828F8 /* Build configuration list for PBXProject "oauthio" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = CFC4317117A6A30700C828F8; + productRefGroup = CFC4317D17A6A30700C828F8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + CFC4317B17A6A30700C828F8 /* oauthio */, + CFC4319F17A6A30700C828F8 /* oauthioTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + CFC4317A17A6A30700C828F8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFC4318B17A6A30700C828F8 /* InfoPlist.strings in Resources */, + CFC4319717A6A30700C828F8 /* ViewController_iPhone.xib in Resources */, + CFC4319A17A6A30700C828F8 /* ViewController_iPad.xib in Resources */, + CF79EF6417A7F7390015C0DE /* OAuthIOModal.xib in Resources */, + CF79EF6B17A80C9D0015C0DE /* logo.png in Resources */, + CF79EF6C17A80C9D0015C0DE /* webshell-logo-rc1-2.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFC4319D17A6A30700C828F8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFC431AC17A6A30700C828F8 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + CFC4319E17A6A30700C828F8 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CFC4317817A6A30700C828F8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFC4318D17A6A30700C828F8 /* main.m in Sources */, + CFC4319117A6A30700C828F8 /* AppDelegate.m in Sources */, + CFC4319417A6A30700C828F8 /* ViewController.m in Sources */, + CFC431BB17A6A32D00C828F8 /* OAuthIO.m in Sources */, + CF444ACF17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m in Sources */, + CF79EF5D17A7C92E0015C0DE /* OAuthIORequest.m in Sources */, + CF79EF6717A7F7870015C0DE /* OAuthIOModal.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFC4319B17A6A30700C828F8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFC431AF17A6A30700C828F8 /* oauthioTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + CFC431A617A6A30700C828F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CFC4317B17A6A30700C828F8 /* oauthio */; + targetProxy = CFC431A517A6A30700C828F8 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + CFC4318917A6A30700C828F8 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + CFC4318A17A6A30700C828F8 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + CFC4319517A6A30700C828F8 /* ViewController_iPhone.xib */ = { + isa = PBXVariantGroup; + children = ( + CFC4319617A6A30700C828F8 /* en */, + ); + name = ViewController_iPhone.xib; + sourceTree = ""; + }; + CFC4319817A6A30700C828F8 /* ViewController_iPad.xib */ = { + isa = PBXVariantGroup; + children = ( + CFC4319917A6A30700C828F8 /* en */, + ); + name = ViewController_iPad.xib; + sourceTree = ""; + }; + CFC431AA17A6A30700C828F8 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + CFC431AB17A6A30700C828F8 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + CFC431B017A6A30700C828F8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 5.1; + SDKROOT = iphoneos7.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + CFC431B117A6A30700C828F8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 5.1; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + SDKROOT = iphoneos7.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + CFC431B317A6A30700C828F8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; + INFOPLIST_FILE = "oauthio/oauthio-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + CFC431B417A6A30700C828F8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; + INFOPLIST_FILE = "oauthio/oauthio-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + CFC431B617A6A30700C828F8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/oauthio.app/oauthio"; + FRAMEWORK_SEARCH_PATHS = ( + "\"$(SDKROOT)/Developer/Library/Frameworks\"", + "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; + INFOPLIST_FILE = "oauthioTests/oauthioTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = octest; + }; + name = Debug; + }; + CFC431B717A6A30700C828F8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/oauthio.app/oauthio"; + FRAMEWORK_SEARCH_PATHS = ( + "\"$(SDKROOT)/Developer/Library/Frameworks\"", + "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; + INFOPLIST_FILE = "oauthioTests/oauthioTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = octest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + CFC4317617A6A30700C828F8 /* Build configuration list for PBXProject "oauthio" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CFC431B017A6A30700C828F8 /* Debug */, + CFC431B117A6A30700C828F8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CFC431B217A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthio" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CFC431B317A6A30700C828F8 /* Debug */, + CFC431B417A6A30700C828F8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CFC431B517A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthioTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CFC431B617A6A30700C828F8 /* Debug */, + CFC431B717A6A30700C828F8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = CFC4317317A6A30700C828F8 /* Project object */; +} diff --git a/Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b735f94 --- /dev/null +++ b/Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Demo/oauthio/AppDelegate.h b/Demo/oauthio/AppDelegate.h new file mode 100644 index 0000000..51fc915 --- /dev/null +++ b/Demo/oauthio/AppDelegate.h @@ -0,0 +1,18 @@ +// +// AppDelegate.h +// oauthio +// +// Copyright (c) 2013 Webshell. All rights reserved. +// + +#import + +@class ViewController; + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@property (strong, nonatomic) ViewController *viewController; + +@end diff --git a/Demo/oauthio/AppDelegate.m b/Demo/oauthio/AppDelegate.m new file mode 100644 index 0000000..c45b617 --- /dev/null +++ b/Demo/oauthio/AppDelegate.m @@ -0,0 +1,69 @@ +// +// AppDelegate.m +// oauthio +// +// Copyright (c) 2013 Webshell. All rights reserved. +// + +#import "AppDelegate.h" +#import "ViewController.h" + +@implementation AppDelegate + +- (void)dealloc +{ + [_window release]; + [_viewController release]; + [super dealloc]; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + // Override point for customization after application launch. + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease]; + } else { + self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease]; + } + self.window.rootViewController = self.viewController; + [self.window makeKeyAndVisible]; + + return YES; +} + +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + [OAuthIOModal handleOAuthIOResponse:url]; + + return (YES); +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.h b/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.h new file mode 100644 index 0000000..78f2684 --- /dev/null +++ b/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface NSURLRequest (NSURLRequestAllowSSL) + ++ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host; + +@end \ No newline at end of file diff --git a/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.m b/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.m new file mode 100644 index 0000000..0d7097c --- /dev/null +++ b/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.m @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "NSURLRequest+NSURLRequestAllowSSL.h" + +@implementation NSURLRequest (NSURLRequestAllowSSL) + ++ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host +{ + return YES; +} + +@end \ No newline at end of file diff --git a/Demo/oauthio/OAuthIO.h b/Demo/oauthio/OAuthIO.h new file mode 100644 index 0000000..1cb0582 --- /dev/null +++ b/Demo/oauthio/OAuthIO.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#import +#import "OAuthIORequest.h" + + +typedef void (^SuccessBlock) (NSData *data, NSURLRequest *request); +typedef void (^ErrorBlock) (NSError *error); + +@interface OAuthIO : NSObject +{ + NSString *_key; + NSMutableData *_responseData; +} + +@property (nonatomic, copy) SuccessBlock success; +@property (nonatomic, copy) ErrorBlock error; + +- (id)initWithKey:(NSString *)key; +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error; + +@end + diff --git a/Demo/oauthio/OAuthIO.m b/Demo/oauthio/OAuthIO.m new file mode 100644 index 0000000..3238b6a --- /dev/null +++ b/Demo/oauthio/OAuthIO.m @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIO.h" + +#define kOAUTHIO_URL @"https://oauth.io/auth" + +@implementation OAuthIO + +- (id)initWithKey:(NSString *)key +{ + self = [super init]; + + if (!self) + return nil; + + _key = key; + + return (self); +} + +- (void)dealloc +{ + [super dealloc]; +} + +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error +{ + _success = [success copy]; + _error = [error copy]; + + OAuthIORequest *request = [[OAuthIORequest alloc] initWithBaseUrl:kOAUTHIO_URL]; + + NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease]; + [params setValue:provider forKey:@"p"]; + [params setValue:_key forKey:@"k"]; + [params setValue:url forKey:@"redirect_uri"]; + + [request requestWithParams:params success:^(NSData *data, NSURLRequest *request) { + + _success(data, request); + + } error:^(NSError *error) { + + _error(error); + + }]; + + [request release]; +} + +@end diff --git a/Demo/oauthio/OAuthIOModal.h b/Demo/oauthio/OAuthIOModal.h new file mode 100644 index 0000000..a7f07fd --- /dev/null +++ b/Demo/oauthio/OAuthIOModal.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import "OAuthIORequest.h" +#import "OAuthIO.h" + +#define NAVIGATION_BAR_HEIGHT_IOS7_OR_LATER 64 +#define NAVIGATION_BAR_HEIGHT_IOS6_OR_EARLIER 44 + +@protocol OAuthIODelegate + +- (void)didReceiveOAuthIOResponse:(NSDictionary *)result; +- (void)didFailWithOAuthIOError:(NSError *)error; + +@end + +@interface OAuthIOModal : UIViewController +{ + NSString *_key; + NSString *_scheme; + NSString *_callback_url; + OAuthIO *_oauth; + UIViewController *_rootViewController; + NSUInteger _navigationBarHeight; +} + +@property (nonatomic, retain) id delegate; +@property (nonatomic, retain) NSString *provider; +@property (nonatomic, retain) UINavigationBar *navigationBar; +@property (nonatomic, retain) IBOutlet UIWebView *browser; + ++ (void) handleOAuthIOResponse:(NSURL *)url; + +- (id)initWithKey:(NSString *)key delegate:(id)delegate; +- (void)showWithProvider:(NSString *)provider; + +@end diff --git a/Demo/oauthio/OAuthIOModal.m b/Demo/oauthio/OAuthIOModal.m new file mode 100644 index 0000000..548d18b --- /dev/null +++ b/Demo/oauthio/OAuthIOModal.m @@ -0,0 +1,242 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIOModal.h" + +@implementation OAuthIOModal + +NSString *_host; + ++ (void) handleOAuthIOResponse:(NSURL *)url +{ + if ([url.host isEqualToString:_host]) + [[NSNotificationCenter defaultCenter] postNotificationName:@"OAuthIOGetTokens" object:self userInfo:[NSDictionary dictionaryWithObject:url forKey:@"URL"]]; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return (self); +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [_browser setFrame:CGRectMake(0, _navigationBarHeight, _browser.frame.size.width, _browser.frame.size.height - _navigationBarHeight - 1)]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTokens:) name:@"OAuthIOGetTokens" object:nil]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [_browser release]; + [_rootViewController release]; + [_navigationBar release]; + [super dealloc]; +} + +- (id)initWithKey:(NSString *)key delegate:(id)delegate +{ + self = [super init]; + + if (!self || ![self initCustomCallbackURL]) + return (nil); + + [self setDelegate:delegate]; + + _key = key; + _oauth = [[OAuthIO alloc] initWithKey:_key]; + _rootViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; + + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) + _navigationBarHeight = NAVIGATION_BAR_HEIGHT_IOS7_OR_LATER; + else + _navigationBarHeight = NAVIGATION_BAR_HEIGHT_IOS6_OR_EARLIER; + + [self initNavigationBar]; + + return (self); +} + +- (void)getTokens:(NSNotification *)notification +{ + + NSString *url = [OAuthIORequest decodeURL:[NSString stringWithFormat:@"%@", [notification.userInfo objectForKey:@"URL"]]]; + + NSUInteger start_pos = [url rangeOfString:@"="].location + 1; + NSString *json = [url substringWithRange:NSMakeRange(start_pos, [url length] - start_pos)]; + + NSError *error = nil; + NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; + NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease]; + + + if (jsonData) + { + NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; + + if (error) + { + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; + + return; + } + + NSArray *keys = [jsonObject objectForKey:@"data"]; + + for (NSString *key in keys) + { + if ([key isEqualToString:@"request"]) continue; // clean response + + [dict setValue:[keys valueForKey:key] forKey:key]; + } + + if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)]) + [self.delegate didReceiveOAuthIOResponse:dict]; + } +} + + +# pragma mark - Toolbar methods + +- (void)initNavigationBar +{ + _navigationBar = [[UINavigationBar alloc] init]; + [_navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth]; + + UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:@""] autorelease]; + UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)] autorelease]; + UIBarButtonItem *refreshButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:nil action:@selector(refreshOperation)] autorelease]; + + [navItem setRightBarButtonItem:cancelButton]; + [navItem setLeftBarButtonItem:refreshButton]; + + [_navigationBar pushNavigationItem:navItem animated:NO]; + + [self drawNavigationBar]; +} + +- (void)drawNavigationBar +{ + CGFloat width = CGRectGetWidth(self.view.bounds); + [_navigationBar setFrame:CGRectMake(0, 0, width, _navigationBarHeight)]; + [self.view addSubview:_navigationBar]; +} + +- (void)refreshOperation +{ + [_browser reload]; +} + +- (void)cancelOperation +{ + NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; + [errorDetail setValue:@"Operation canceled" forKey:NSLocalizedDescriptionKey]; + NSError *error = [[[NSError alloc] initWithDomain:@"OAuthIO" code:100 userInfo:errorDetail] autorelease]; + + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; + + [_browser loadHTMLString:nil baseURL:nil]; + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (BOOL) initCustomCallbackURL +{ + NSDictionary *customURLDict = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"] objectAtIndex:0]; + + if (customURLDict) + { + _scheme = [[customURLDict objectForKey:@"CFBundleURLSchemes"] objectAtIndex:0]; + _host = [customURLDict objectForKey:@"CFBundleURLName"]; + } + + if (_scheme && _host) + _callback_url = [[NSString alloc] initWithFormat:@"%@://%@", _scheme, _host]; + else + { + UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"OAuthIO" message:@"You must define a custom scheme and an url identifier in your plist configuration file" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease]; + [alert show]; + + return (NO); + } + + return (YES); + +} + +- (void)showWithProvider:(NSString *)provider +{ + _provider = provider; + + [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSURLRequest *request){ + + [_rootViewController presentViewController:self animated:YES completion:^{ + + [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:request.URL]; + + }]; + + } error:^(NSError *error) { + + if ([self.delegate respondsToSelector:@selector(oauth:didFailWithError:)]) + [self.delegate didFailWithOAuthIOError:error]; + }]; +} + +#pragma mark - UIWebView delegate method + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + NSURL *url = request.URL; + + if (![url.scheme isEqual:@"http"] && ![url.scheme isEqual:@"https"] && ![url.scheme isEqual:@"file"]) + { + if ([[UIApplication sharedApplication]canOpenURL:url]) + { + [[UIApplication sharedApplication]openURL:url]; + + if ([request.URL.host isEqualToString:_host]) + [self dismissViewControllerAnimated:YES completion:nil]; + + return (NO); + } + } + + return (YES); +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error +{ + if ([error.domain isEqualToString:@"NSURLErrorDomain"] && error.code == -999) + return; + + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; +} + +@end diff --git a/Demo/oauthio/OAuthIOModal.xib b/Demo/oauthio/OAuthIOModal.xib new file mode 100644 index 0000000..d9a0567 --- /dev/null +++ b/Demo/oauthio/OAuthIOModal.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo/oauthio/OAuthIORequest.h b/Demo/oauthio/OAuthIORequest.h new file mode 100644 index 0000000..7de8e87 --- /dev/null +++ b/Demo/oauthio/OAuthIORequest.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +typedef void (^RequestSuccessBlock) (NSData *data, NSURLRequest *request); +typedef void (^RequestErrorBlock) (NSError *error); + +@interface OAuthIORequest : NSObject +{ + NSURLConnection *_connection; + NSMutableURLRequest *_req; + NSMutableData *_responseData; + NSString *_baseUrl; +} + +@property (nonatomic, copy) RequestSuccessBlock success; +@property (nonatomic, copy) RequestErrorBlock error; +@property (nonatomic, copy) NSURLRequest *request; + +- (id) initWithBaseUrl:(NSString *)baseUrl; +- (void) requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error; ++ (NSString *)encodeURL:(NSString *)str; ++ (NSString*)decodeURL:(NSString *)str; + +@end diff --git a/Demo/oauthio/OAuthIORequest.m b/Demo/oauthio/OAuthIORequest.m new file mode 100644 index 0000000..51a5396 --- /dev/null +++ b/Demo/oauthio/OAuthIORequest.m @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIORequest.h" + +@implementation OAuthIORequest + ++ (NSString *)encodeURL:(NSString *)str +{ + return ([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, nil, CFSTR("&?=+/:"), kCFStringEncodingUTF8) autorelease]); +} + ++ (NSString *)decodeURL:(NSString *)str +{ + return ([(NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8) autorelease]); +} + +- (NSString *)buildQueryWithDictionnary:(NSDictionary *)params +{ + NSString *query = [[[NSString alloc] init] autorelease]; + NSUInteger i = 1; + + for (NSString *key in [params allKeys]) + { + if ([key length] != 0 && ![key isEqualToString:@"p"]) + { + if (i == 1) + query = [query stringByAppendingFormat:@"?%@=%@", key, [params objectForKey:key]]; + else + query = [query stringByAppendingFormat:@"&%@=%@", key, [params objectForKey:key]]; + + i++; + } + } + + return (query); +} + +- (id)initWithBaseUrl:(NSString *)baseUrl +{ + self = [super init]; + + if (!self) + return nil; + + _baseUrl = baseUrl; + + return (self); +} + +- (void)requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error +{ + _success = [success copy]; + _error = [error copy]; + + NSString *query = [self buildQueryWithDictionnary:params]; + NSString *url = [[[NSString alloc] initWithFormat:@"%@/%@%@", _baseUrl, [params objectForKey:@"p"], query] autorelease]; + + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + + [_connection start]; + [_connection release]; +} + + +#pragma mark NSURLConnexion delegate methods + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response +{ + _responseData = [[NSMutableData alloc] init]; + _request = [(NSURLRequest *)response copy]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data +{ + [_responseData appendData:data]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection +{ + _success(_responseData, _request); +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse +{ + return (nil); +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error +{ + _error(error); +} + + +@end diff --git a/Demo/oauthio/ViewController.h b/Demo/oauthio/ViewController.h new file mode 100644 index 0000000..e51bb92 --- /dev/null +++ b/Demo/oauthio/ViewController.h @@ -0,0 +1,27 @@ +// +// ViewController.h +// oauthio +// +// Copyright (c) 2013 Webshell. All rights reserved. +// + +#import +#import "OAuthIOModal.h" + +#define kTWITTER_BUTTON 1 +#define kFACEBOOK_BUTTON 2 +#define kGOOGLE_PLUS_BUTTON 3 +#define kLINKED_IN_BUTTON 4 + +@interface ViewController : UIViewController + +@property (nonatomic, retain) OAuthIOModal *oauthioModal; +@property (retain, nonatomic) IBOutlet UIButton *buttonTwitter; +@property (retain, nonatomic) IBOutlet UIButton *buttonFacebook; +@property (retain, nonatomic) IBOutlet UIButton *buttonGooglePlus; +@property (retain, nonatomic) IBOutlet UIButton *buttonLinkedIn; +@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; + +- (IBAction)connect:(id)sender; + +@end diff --git a/Demo/oauthio/ViewController.m b/Demo/oauthio/ViewController.m new file mode 100644 index 0000000..a05fe2d --- /dev/null +++ b/Demo/oauthio/ViewController.m @@ -0,0 +1,98 @@ +// +// ViewController.m +// oauthio +// +// Copyright (c) 2013 Webshell. All rights reserved. +// + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [_activityIndicator setHidden:YES]; + [_buttonTwitter setTag:kTWITTER_BUTTON]; + [_buttonFacebook setTag:kFACEBOOK_BUTTON]; + [_buttonGooglePlus setTag:kGOOGLE_PLUS_BUTTON]; + [_buttonLinkedIn setTag:kLINKED_IN_BUTTON]; + + _oauthioModal = [[OAuthIOModal alloc] initWithKey:@"WmKGOEutadU6jZ8agshVaz1VMiM" delegate:self]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)dealloc { + + [_oauthioModal release]; + [_activityIndicator release]; + [_buttonTwitter release]; + [_buttonFacebook release]; + [_buttonGooglePlus release]; + [_buttonLinkedIn release]; + + [super dealloc]; +} + +- (IBAction)connect:(id)sender +{ + [_buttonTwitter setHidden:YES]; + [_buttonFacebook setHidden:YES]; + [_buttonGooglePlus setHidden:YES]; + [_buttonLinkedIn setHidden:YES]; + [_activityIndicator setHidden:NO]; + [_activityIndicator startAnimating]; + + NSUInteger button_id = ((UIButton *)sender).tag; + NSString *provider = nil; + + if (button_id == kTWITTER_BUTTON) + provider = @"twitter"; + else if (button_id == kFACEBOOK_BUTTON) + provider = @"facebook"; + else if (button_id == kGOOGLE_PLUS_BUTTON) + provider = @"google_plus"; + else if (button_id == kLINKED_IN_BUTTON) + provider = @"linkedin"; + + [_oauthioModal showWithProvider:provider]; +} + +- (void) hideActivityIndicator +{ + [_activityIndicator startAnimating]; + [_activityIndicator setHidden:YES]; + [_buttonTwitter setHidden:NO]; + [_buttonFacebook setHidden:NO]; + [_buttonGooglePlus setHidden:NO]; + [_buttonLinkedIn setHidden:NO]; +} + +#pragma mark OAuthIO delegate methods + +- (void)didReceiveOAuthIOResponse:(NSDictionary *)result +{ + [self hideActivityIndicator]; + + NSLog(@"\nRESULT:\n-------\n%@\n", result); +} + +- (void)didFailWithOAuthIOError:(NSError *)error +{ + [self hideActivityIndicator]; + + NSLog(@"\nERROR:\n--------\n%@\n", error.description); +} + +@end diff --git a/Demo/oauthio/en.lproj/InfoPlist.strings b/Demo/oauthio/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Demo/oauthio/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Demo/oauthio/en.lproj/ViewController_iPad.xib b/Demo/oauthio/en.lproj/ViewController_iPad.xib new file mode 100644 index 0000000..41d878c --- /dev/null +++ b/Demo/oauthio/en.lproj/ViewController_iPad.xib @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo/oauthio/en.lproj/ViewController_iPhone.xib b/Demo/oauthio/en.lproj/ViewController_iPhone.xib new file mode 100644 index 0000000..841df22 --- /dev/null +++ b/Demo/oauthio/en.lproj/ViewController_iPhone.xib @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo/oauthio/logo.png b/Demo/oauthio/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f2506c19ca7311eacca1bdb5c7d7bf5c4d67ea5a GIT binary patch literal 9427 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 + +#import "AppDelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Demo/oauthio/oauthio-Info.plist b/Demo/oauthio/oauthio-Info.plist new file mode 100644 index 0000000..1c2efe6 --- /dev/null +++ b/Demo/oauthio/oauthio-Info.plist @@ -0,0 +1,56 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + bundleIdentifier.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLName + localhost + CFBundleURLSchemes + + myappname + + + + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Demo/oauthio/oauthio-Prefix.pch b/Demo/oauthio/oauthio-Prefix.pch new file mode 100644 index 0000000..43e15e2 --- /dev/null +++ b/Demo/oauthio/oauthio-Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'oauthio' target in the 'oauthio' project +// + +#import + +#ifndef __IPHONE_4_0 +#warning "This project uses features only available in iOS SDK 4.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Demo/oauthio/webshell-logo-rc1-2.png b/Demo/oauthio/webshell-logo-rc1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2778d6adff8b9e36c7b0229d5e6c647c12685dc7 GIT binary patch literal 13462 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 literal 0 HcmV?d00001 diff --git a/Demo/oauthioTests/en.lproj/InfoPlist.strings b/Demo/oauthioTests/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/Demo/oauthioTests/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/Demo/oauthioTests/oauthioTests-Info.plist b/Demo/oauthioTests/oauthioTests-Info.plist new file mode 100644 index 0000000..dad347e --- /dev/null +++ b/Demo/oauthioTests/oauthioTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + bundleIdentifier.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Demo/oauthioTests/oauthioTests.h b/Demo/oauthioTests/oauthioTests.h new file mode 100644 index 0000000..bdc4ea9 --- /dev/null +++ b/Demo/oauthioTests/oauthioTests.h @@ -0,0 +1,13 @@ +// +// oauthioTests.h +// oauthioTests +// +// Created by Termellil Walid on 29/07/13. +// Copyright (c) 2013 Webshell. All rights reserved. +// + +#import + +@interface oauthioTests : SenTestCase + +@end diff --git a/Demo/oauthioTests/oauthioTests.m b/Demo/oauthioTests/oauthioTests.m new file mode 100644 index 0000000..5fb9d2f --- /dev/null +++ b/Demo/oauthioTests/oauthioTests.m @@ -0,0 +1,32 @@ +// +// oauthioTests.m +// oauthioTests +// +// Created by Termellil Walid on 29/07/13. +// Copyright (c) 2013 Webshell. All rights reserved. +// + +#import "oauthioTests.h" + +@implementation oauthioTests + +- (void)setUp +{ + [super setUp]; + + // Set-up code here. +} + +- (void)tearDown +{ + // Tear-down code here. + + [super tearDown]; +} + +- (void)testExample +{ + STFail(@"Unit tests are not implemented yet in oauthioTests"); +} + +@end diff --git a/README.md b/README.md index a5c267a..e9b7587 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,71 @@ -oauth-ios -========= +# OAuth.io iOS SDK -OAuth.io library for iOS +This is the official iOS SDK for [OAuth.io](https://oauth.io) ! + + * Supported on iOS 5 or later + * ARC not supported currently + +### License + +See LICENSE file + +### OAuth.io Requirements and Set-Up + +To use this plugin you will need to make sure you've registered your OAuth.io app and have a public key (https://oauth.io/docs) + +### Installation + +Copy the source files within oauth-ios/Src to your project. + +### Usage + +To get the response from OAuthIO service, you must define a custom scheme and identifier in your plist file. (e.g myappname://localhost) + +![custom_scheme](https://oauth.io/img/custom_scheme.png) + +Implement the method bellow in your AppDelegate File + + - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation + { + [OAuthIOModal handleOAuthIOResponse:url]; + return (YES); + } + +Put #import "OAuthIOModal.h" in your source file and don't forget to adopt the OAuthIO protocol then in your ViewController instanciate the OAuthIOModal object + + // ViewController.h + // ---------------- + + #import + #import "OAuthIOModal.h" + + @interface ViewController : UIViewController + + + // ViewController.m + // ---------------- + + ... + + OAuthIOModal oauthioModal = [[OAuthIOModal alloc] initWithKey:@"Public key" delegate:self]; + [oauthioModal showForProvider:@"facebook"]; + + ... +Implement these delegate methods in your ViewController + + #pragma mark OAuthIO delegate methods + + - (void)didReceiveOAuthIOResponse:(NSDictionary *)result + { + NSLog(@"Result : %@\n", result); + } + + - (void)didFailWithOAuthIOError:(NSError *)error + { + NSLog(@"Error : %@\n", error.description); + } + +### Note +ARC is not yet supported, disable ARC for OAuthIO files + +![custom_scheme](https://oauth.io/img/no-objc-arc.png) diff --git a/Src/NSURLRequest+NSURLRequestAllowSSL.h b/Src/NSURLRequest+NSURLRequestAllowSSL.h new file mode 100644 index 0000000..78f2684 --- /dev/null +++ b/Src/NSURLRequest+NSURLRequestAllowSSL.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface NSURLRequest (NSURLRequestAllowSSL) + ++ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host; + +@end \ No newline at end of file diff --git a/Src/NSURLRequest+NSURLRequestAllowSSL.m b/Src/NSURLRequest+NSURLRequestAllowSSL.m new file mode 100644 index 0000000..0d7097c --- /dev/null +++ b/Src/NSURLRequest+NSURLRequestAllowSSL.m @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "NSURLRequest+NSURLRequestAllowSSL.h" + +@implementation NSURLRequest (NSURLRequestAllowSSL) + ++ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host +{ + return YES; +} + +@end \ No newline at end of file diff --git a/Src/OAuthIO.h b/Src/OAuthIO.h new file mode 100644 index 0000000..1cb0582 --- /dev/null +++ b/Src/OAuthIO.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#import +#import "OAuthIORequest.h" + + +typedef void (^SuccessBlock) (NSData *data, NSURLRequest *request); +typedef void (^ErrorBlock) (NSError *error); + +@interface OAuthIO : NSObject +{ + NSString *_key; + NSMutableData *_responseData; +} + +@property (nonatomic, copy) SuccessBlock success; +@property (nonatomic, copy) ErrorBlock error; + +- (id)initWithKey:(NSString *)key; +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error; + +@end + diff --git a/Src/OAuthIO.m b/Src/OAuthIO.m new file mode 100644 index 0000000..3238b6a --- /dev/null +++ b/Src/OAuthIO.m @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIO.h" + +#define kOAUTHIO_URL @"https://oauth.io/auth" + +@implementation OAuthIO + +- (id)initWithKey:(NSString *)key +{ + self = [super init]; + + if (!self) + return nil; + + _key = key; + + return (self); +} + +- (void)dealloc +{ + [super dealloc]; +} + +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error +{ + _success = [success copy]; + _error = [error copy]; + + OAuthIORequest *request = [[OAuthIORequest alloc] initWithBaseUrl:kOAUTHIO_URL]; + + NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease]; + [params setValue:provider forKey:@"p"]; + [params setValue:_key forKey:@"k"]; + [params setValue:url forKey:@"redirect_uri"]; + + [request requestWithParams:params success:^(NSData *data, NSURLRequest *request) { + + _success(data, request); + + } error:^(NSError *error) { + + _error(error); + + }]; + + [request release]; +} + +@end diff --git a/Src/OAuthIOModal.h b/Src/OAuthIOModal.h new file mode 100644 index 0000000..a7f07fd --- /dev/null +++ b/Src/OAuthIOModal.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#import "OAuthIORequest.h" +#import "OAuthIO.h" + +#define NAVIGATION_BAR_HEIGHT_IOS7_OR_LATER 64 +#define NAVIGATION_BAR_HEIGHT_IOS6_OR_EARLIER 44 + +@protocol OAuthIODelegate + +- (void)didReceiveOAuthIOResponse:(NSDictionary *)result; +- (void)didFailWithOAuthIOError:(NSError *)error; + +@end + +@interface OAuthIOModal : UIViewController +{ + NSString *_key; + NSString *_scheme; + NSString *_callback_url; + OAuthIO *_oauth; + UIViewController *_rootViewController; + NSUInteger _navigationBarHeight; +} + +@property (nonatomic, retain) id delegate; +@property (nonatomic, retain) NSString *provider; +@property (nonatomic, retain) UINavigationBar *navigationBar; +@property (nonatomic, retain) IBOutlet UIWebView *browser; + ++ (void) handleOAuthIOResponse:(NSURL *)url; + +- (id)initWithKey:(NSString *)key delegate:(id)delegate; +- (void)showWithProvider:(NSString *)provider; + +@end diff --git a/Src/OAuthIOModal.m b/Src/OAuthIOModal.m new file mode 100644 index 0000000..548d18b --- /dev/null +++ b/Src/OAuthIOModal.m @@ -0,0 +1,242 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIOModal.h" + +@implementation OAuthIOModal + +NSString *_host; + ++ (void) handleOAuthIOResponse:(NSURL *)url +{ + if ([url.host isEqualToString:_host]) + [[NSNotificationCenter defaultCenter] postNotificationName:@"OAuthIOGetTokens" object:self userInfo:[NSDictionary dictionaryWithObject:url forKey:@"URL"]]; +} + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return (self); +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [_browser setFrame:CGRectMake(0, _navigationBarHeight, _browser.frame.size.width, _browser.frame.size.height - _navigationBarHeight - 1)]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTokens:) name:@"OAuthIOGetTokens" object:nil]; +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [_browser release]; + [_rootViewController release]; + [_navigationBar release]; + [super dealloc]; +} + +- (id)initWithKey:(NSString *)key delegate:(id)delegate +{ + self = [super init]; + + if (!self || ![self initCustomCallbackURL]) + return (nil); + + [self setDelegate:delegate]; + + _key = key; + _oauth = [[OAuthIO alloc] initWithKey:_key]; + _rootViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; + + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) + _navigationBarHeight = NAVIGATION_BAR_HEIGHT_IOS7_OR_LATER; + else + _navigationBarHeight = NAVIGATION_BAR_HEIGHT_IOS6_OR_EARLIER; + + [self initNavigationBar]; + + return (self); +} + +- (void)getTokens:(NSNotification *)notification +{ + + NSString *url = [OAuthIORequest decodeURL:[NSString stringWithFormat:@"%@", [notification.userInfo objectForKey:@"URL"]]]; + + NSUInteger start_pos = [url rangeOfString:@"="].location + 1; + NSString *json = [url substringWithRange:NSMakeRange(start_pos, [url length] - start_pos)]; + + NSError *error = nil; + NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; + NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease]; + + + if (jsonData) + { + NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; + + if (error) + { + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; + + return; + } + + NSArray *keys = [jsonObject objectForKey:@"data"]; + + for (NSString *key in keys) + { + if ([key isEqualToString:@"request"]) continue; // clean response + + [dict setValue:[keys valueForKey:key] forKey:key]; + } + + if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)]) + [self.delegate didReceiveOAuthIOResponse:dict]; + } +} + + +# pragma mark - Toolbar methods + +- (void)initNavigationBar +{ + _navigationBar = [[UINavigationBar alloc] init]; + [_navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth]; + + UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:@""] autorelease]; + UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)] autorelease]; + UIBarButtonItem *refreshButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:nil action:@selector(refreshOperation)] autorelease]; + + [navItem setRightBarButtonItem:cancelButton]; + [navItem setLeftBarButtonItem:refreshButton]; + + [_navigationBar pushNavigationItem:navItem animated:NO]; + + [self drawNavigationBar]; +} + +- (void)drawNavigationBar +{ + CGFloat width = CGRectGetWidth(self.view.bounds); + [_navigationBar setFrame:CGRectMake(0, 0, width, _navigationBarHeight)]; + [self.view addSubview:_navigationBar]; +} + +- (void)refreshOperation +{ + [_browser reload]; +} + +- (void)cancelOperation +{ + NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; + [errorDetail setValue:@"Operation canceled" forKey:NSLocalizedDescriptionKey]; + NSError *error = [[[NSError alloc] initWithDomain:@"OAuthIO" code:100 userInfo:errorDetail] autorelease]; + + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; + + [_browser loadHTMLString:nil baseURL:nil]; + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (BOOL) initCustomCallbackURL +{ + NSDictionary *customURLDict = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"] objectAtIndex:0]; + + if (customURLDict) + { + _scheme = [[customURLDict objectForKey:@"CFBundleURLSchemes"] objectAtIndex:0]; + _host = [customURLDict objectForKey:@"CFBundleURLName"]; + } + + if (_scheme && _host) + _callback_url = [[NSString alloc] initWithFormat:@"%@://%@", _scheme, _host]; + else + { + UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"OAuthIO" message:@"You must define a custom scheme and an url identifier in your plist configuration file" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease]; + [alert show]; + + return (NO); + } + + return (YES); + +} + +- (void)showWithProvider:(NSString *)provider +{ + _provider = provider; + + [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSURLRequest *request){ + + [_rootViewController presentViewController:self animated:YES completion:^{ + + [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:request.URL]; + + }]; + + } error:^(NSError *error) { + + if ([self.delegate respondsToSelector:@selector(oauth:didFailWithError:)]) + [self.delegate didFailWithOAuthIOError:error]; + }]; +} + +#pragma mark - UIWebView delegate method + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + NSURL *url = request.URL; + + if (![url.scheme isEqual:@"http"] && ![url.scheme isEqual:@"https"] && ![url.scheme isEqual:@"file"]) + { + if ([[UIApplication sharedApplication]canOpenURL:url]) + { + [[UIApplication sharedApplication]openURL:url]; + + if ([request.URL.host isEqualToString:_host]) + [self dismissViewControllerAnimated:YES completion:nil]; + + return (NO); + } + } + + return (YES); +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error +{ + if ([error.domain isEqualToString:@"NSURLErrorDomain"] && error.code == -999) + return; + + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; +} + +@end diff --git a/Src/OAuthIOModal.xib b/Src/OAuthIOModal.xib new file mode 100644 index 0000000..d9a0567 --- /dev/null +++ b/Src/OAuthIOModal.xib @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Src/OAuthIORequest.h b/Src/OAuthIORequest.h new file mode 100644 index 0000000..7de8e87 --- /dev/null +++ b/Src/OAuthIORequest.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +typedef void (^RequestSuccessBlock) (NSData *data, NSURLRequest *request); +typedef void (^RequestErrorBlock) (NSError *error); + +@interface OAuthIORequest : NSObject +{ + NSURLConnection *_connection; + NSMutableURLRequest *_req; + NSMutableData *_responseData; + NSString *_baseUrl; +} + +@property (nonatomic, copy) RequestSuccessBlock success; +@property (nonatomic, copy) RequestErrorBlock error; +@property (nonatomic, copy) NSURLRequest *request; + +- (id) initWithBaseUrl:(NSString *)baseUrl; +- (void) requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error; ++ (NSString *)encodeURL:(NSString *)str; ++ (NSString*)decodeURL:(NSString *)str; + +@end diff --git a/Src/OAuthIORequest.m b/Src/OAuthIORequest.m new file mode 100644 index 0000000..51a5396 --- /dev/null +++ b/Src/OAuthIORequest.m @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIORequest.h" + +@implementation OAuthIORequest + ++ (NSString *)encodeURL:(NSString *)str +{ + return ([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, nil, CFSTR("&?=+/:"), kCFStringEncodingUTF8) autorelease]); +} + ++ (NSString *)decodeURL:(NSString *)str +{ + return ([(NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8) autorelease]); +} + +- (NSString *)buildQueryWithDictionnary:(NSDictionary *)params +{ + NSString *query = [[[NSString alloc] init] autorelease]; + NSUInteger i = 1; + + for (NSString *key in [params allKeys]) + { + if ([key length] != 0 && ![key isEqualToString:@"p"]) + { + if (i == 1) + query = [query stringByAppendingFormat:@"?%@=%@", key, [params objectForKey:key]]; + else + query = [query stringByAppendingFormat:@"&%@=%@", key, [params objectForKey:key]]; + + i++; + } + } + + return (query); +} + +- (id)initWithBaseUrl:(NSString *)baseUrl +{ + self = [super init]; + + if (!self) + return nil; + + _baseUrl = baseUrl; + + return (self); +} + +- (void)requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error +{ + _success = [success copy]; + _error = [error copy]; + + NSString *query = [self buildQueryWithDictionnary:params]; + NSString *url = [[[NSString alloc] initWithFormat:@"%@/%@%@", _baseUrl, [params objectForKey:@"p"], query] autorelease]; + + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + + [_connection start]; + [_connection release]; +} + + +#pragma mark NSURLConnexion delegate methods + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response +{ + _responseData = [[NSMutableData alloc] init]; + _request = [(NSURLRequest *)response copy]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data +{ + [_responseData appendData:data]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection +{ + _success(_responseData, _request); +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse +{ + return (nil); +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error +{ + _error(error); +} + + +@end From 9c578c7ad5693922f9fc3135ed6f0309c18d9f25 Mon Sep 17 00:00:00 2001 From: Walid TERMELLIL Date: Thu, 24 Oct 2013 00:33:46 +0200 Subject: [PATCH 03/10] remove header info --- Demo/oauthioTests/oauthioTests.h | 1 - Demo/oauthioTests/oauthioTests.m | 1 - 2 files changed, 2 deletions(-) diff --git a/Demo/oauthioTests/oauthioTests.h b/Demo/oauthioTests/oauthioTests.h index bdc4ea9..31a666c 100644 --- a/Demo/oauthioTests/oauthioTests.h +++ b/Demo/oauthioTests/oauthioTests.h @@ -2,7 +2,6 @@ // oauthioTests.h // oauthioTests // -// Created by Termellil Walid on 29/07/13. // Copyright (c) 2013 Webshell. All rights reserved. // diff --git a/Demo/oauthioTests/oauthioTests.m b/Demo/oauthioTests/oauthioTests.m index 5fb9d2f..6f0cf94 100644 --- a/Demo/oauthioTests/oauthioTests.m +++ b/Demo/oauthioTests/oauthioTests.m @@ -2,7 +2,6 @@ // oauthioTests.m // oauthioTests // -// Created by Termellil Walid on 29/07/13. // Copyright (c) 2013 Webshell. All rights reserved. // From 20e308f71356f00a3be4ded82a930201406f1206 Mon Sep 17 00:00:00 2001 From: Walid TERMELLIL Date: Sat, 7 Dec 2013 11:33:24 +0100 Subject: [PATCH 04/10] Requests, ARC support --- Demo/OAuthIOExample.xcodeproj/project.pbxproj | 531 ++++++++++++++++++ .../contents.xcworkspacedata | 2 +- .../{oauthio => OAuthIOExample}/AppDelegate.h | 10 +- .../{oauthio => OAuthIOExample}/AppDelegate.m | 29 +- .../OAuthIOExample/Base.lproj/Main.storyboard | 161 ++++++ Demo/OAuthIOExample/FirstViewController.h | 34 ++ Demo/OAuthIOExample/FirstViewController.m | 87 +++ Demo/OAuthIOExample/GitHubViewController.h | 25 + Demo/OAuthIOExample/GitHubViewController.m | 125 +++++ .../AppIcon.appiconset/Contents.json | 23 + .../LaunchImage.launchimage/Contents.json | 23 + .../NSURLRequest+NSURLRequestAllowSSL.h | 0 .../NSURLRequest+NSURLRequestAllowSSL.m | 0 Demo/{oauthio => OAuthIOExample}/OAuthIO.h | 19 +- .../OAuthIO.m} | 55 +- Demo/OAuthIOExample/OAuthIOData.h | 35 ++ Demo/OAuthIOExample/OAuthIOData.m | 67 +++ .../OAuthIOExample-Info.plist} | 23 +- Demo/OAuthIOExample/OAuthIOExample-Prefix.pch | 16 + .../OAuthIOModal.h | 17 +- .../OAuthIOModal.m | 55 +- .../OAuthIOModal.xib | 0 Demo/OAuthIOExample/OAuthIORequest.h | 62 ++ Demo/OAuthIOExample/OAuthIORequest.m | 321 +++++++++++ Demo/OAuthIOExample/TwitterViewController.h | 24 + Demo/OAuthIOExample/TwitterViewController.m | 94 ++++ .../en.lproj/InfoPlist.strings | 0 Demo/{oauthio => OAuthIOExample}/main.m | 10 +- .../OAuthIOExampleTests-Info.plist} | 2 +- .../OAuthIOExampleTests/OAuthIOExampleTests.m | 31 + .../en.lproj/InfoPlist.strings | 0 Demo/oauthio.xcodeproj/project.pbxproj | 515 ----------------- Demo/oauthio/OAuthIO.m | 66 --- Demo/oauthio/OAuthIORequest.h | 40 -- Demo/oauthio/ViewController.h | 27 - Demo/oauthio/ViewController.m | 98 ---- Demo/oauthio/en.lproj/ViewController_iPad.xib | 51 -- .../en.lproj/ViewController_iPhone.xib | 84 --- Demo/oauthio/logo.png | Bin 9427 -> 0 bytes Demo/oauthio/oauthio-Prefix.pch | 14 - Demo/oauthio/webshell-logo-rc1-2.png | Bin 13462 -> 0 bytes Demo/oauthioTests/oauthioTests.h | 12 - Demo/oauthioTests/oauthioTests.m | 31 - README.md | 32 +- Src/OAuthIO.h | 19 +- Src/OAuthIO.m | 66 ++- Src/OAuthIOData.h | 35 ++ Src/OAuthIOData.m | 67 +++ Src/OAuthIOModal.h | 17 +- Src/OAuthIOModal.m | 55 +- Src/OAuthIORequest.h | 38 +- Src/OAuthIORequest.m | 276 +++++++-- 52 files changed, 2226 insertions(+), 1198 deletions(-) create mode 100644 Demo/OAuthIOExample.xcodeproj/project.pbxproj rename Demo/{oauthio.xcodeproj => OAuthIOExample.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (68%) rename Demo/{oauthio => OAuthIOExample}/AppDelegate.h (51%) rename Demo/{oauthio => OAuthIOExample}/AppDelegate.m (71%) create mode 100644 Demo/OAuthIOExample/Base.lproj/Main.storyboard create mode 100644 Demo/OAuthIOExample/FirstViewController.h create mode 100644 Demo/OAuthIOExample/FirstViewController.m create mode 100644 Demo/OAuthIOExample/GitHubViewController.h create mode 100644 Demo/OAuthIOExample/GitHubViewController.m create mode 100644 Demo/OAuthIOExample/Images.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Demo/OAuthIOExample/Images.xcassets/LaunchImage.launchimage/Contents.json rename Demo/{oauthio => OAuthIOExample}/NSURLRequest+NSURLRequestAllowSSL.h (100%) rename Demo/{oauthio => OAuthIOExample}/NSURLRequest+NSURLRequestAllowSSL.m (100%) rename Demo/{oauthio => OAuthIOExample}/OAuthIO.h (62%) rename Demo/{oauthio/OAuthIORequest.m => OAuthIOExample/OAuthIO.m} (51%) create mode 100644 Demo/OAuthIOExample/OAuthIOData.h create mode 100644 Demo/OAuthIOExample/OAuthIOData.m rename Demo/{oauthio/oauthio-Info.plist => OAuthIOExample/OAuthIOExample-Info.plist} (76%) create mode 100644 Demo/OAuthIOExample/OAuthIOExample-Prefix.pch rename Demo/{oauthio => OAuthIOExample}/OAuthIOModal.h (80%) rename Demo/{oauthio => OAuthIOExample}/OAuthIOModal.m (77%) rename Demo/{oauthio => OAuthIOExample}/OAuthIOModal.xib (100%) create mode 100644 Demo/OAuthIOExample/OAuthIORequest.h create mode 100644 Demo/OAuthIOExample/OAuthIORequest.m create mode 100644 Demo/OAuthIOExample/TwitterViewController.h create mode 100644 Demo/OAuthIOExample/TwitterViewController.m rename Demo/{oauthio => OAuthIOExample}/en.lproj/InfoPlist.strings (100%) rename Demo/{oauthio => OAuthIOExample}/main.m (53%) rename Demo/{oauthioTests/oauthioTests-Info.plist => OAuthIOExampleTests/OAuthIOExampleTests-Info.plist} (90%) create mode 100644 Demo/OAuthIOExampleTests/OAuthIOExampleTests.m rename Demo/{oauthioTests => OAuthIOExampleTests}/en.lproj/InfoPlist.strings (100%) delete mode 100644 Demo/oauthio.xcodeproj/project.pbxproj delete mode 100644 Demo/oauthio/OAuthIO.m delete mode 100644 Demo/oauthio/OAuthIORequest.h delete mode 100644 Demo/oauthio/ViewController.h delete mode 100644 Demo/oauthio/ViewController.m delete mode 100644 Demo/oauthio/en.lproj/ViewController_iPad.xib delete mode 100644 Demo/oauthio/en.lproj/ViewController_iPhone.xib delete mode 100644 Demo/oauthio/logo.png delete mode 100644 Demo/oauthio/oauthio-Prefix.pch delete mode 100644 Demo/oauthio/webshell-logo-rc1-2.png delete mode 100644 Demo/oauthioTests/oauthioTests.h delete mode 100644 Demo/oauthioTests/oauthioTests.m create mode 100644 Src/OAuthIOData.h create mode 100644 Src/OAuthIOData.m diff --git a/Demo/OAuthIOExample.xcodeproj/project.pbxproj b/Demo/OAuthIOExample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..19e9836 --- /dev/null +++ b/Demo/OAuthIOExample.xcodeproj/project.pbxproj @@ -0,0 +1,531 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + CF21067E1853267D00290710 /* TwitterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CF21067D1853267D00290710 /* TwitterViewController.m */; }; + CFB3F62B184619B000E2D967 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFB3F62A184619B000E2D967 /* Foundation.framework */; }; + CFB3F62D184619B000E2D967 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFB3F62C184619B000E2D967 /* CoreGraphics.framework */; }; + CFB3F62F184619B000E2D967 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFB3F62E184619B000E2D967 /* UIKit.framework */; }; + CFB3F635184619B000E2D967 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CFB3F633184619B000E2D967 /* InfoPlist.strings */; }; + CFB3F637184619B000E2D967 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F636184619B000E2D967 /* main.m */; }; + CFB3F63B184619B000E2D967 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F63A184619B000E2D967 /* AppDelegate.m */; }; + CFB3F63E184619B000E2D967 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CFB3F63C184619B000E2D967 /* Main.storyboard */; }; + CFB3F641184619B000E2D967 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F640184619B000E2D967 /* FirstViewController.m */; }; + CFB3F646184619B000E2D967 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CFB3F645184619B000E2D967 /* Images.xcassets */; }; + CFB3F64D184619B000E2D967 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFB3F64C184619B000E2D967 /* XCTest.framework */; }; + CFB3F64E184619B000E2D967 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFB3F62A184619B000E2D967 /* Foundation.framework */; }; + CFB3F64F184619B000E2D967 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFB3F62E184619B000E2D967 /* UIKit.framework */; }; + CFB3F657184619B000E2D967 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CFB3F655184619B000E2D967 /* InfoPlist.strings */; }; + CFB3F659184619B000E2D967 /* OAuthIOExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F658184619B000E2D967 /* OAuthIOExampleTests.m */; }; + CFB3F66E184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F664184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.m */; }; + CFB3F66F184619CA00E2D967 /* OAuthIO.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F666184619CA00E2D967 /* OAuthIO.m */; }; + CFB3F670184619CA00E2D967 /* OAuthIOData.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F668184619CA00E2D967 /* OAuthIOData.m */; }; + CFB3F671184619CA00E2D967 /* OAuthIOModal.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F66A184619CA00E2D967 /* OAuthIOModal.m */; }; + CFB3F672184619CA00E2D967 /* OAuthIOModal.xib in Resources */ = {isa = PBXBuildFile; fileRef = CFB3F66B184619CA00E2D967 /* OAuthIOModal.xib */; }; + CFB3F673184619CA00E2D967 /* OAuthIORequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB3F66D184619CA00E2D967 /* OAuthIORequest.m */; }; + CFE8FCCA1846AAA9007C4BF6 /* GitHubViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFE8FCC91846AAA9007C4BF6 /* GitHubViewController.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + CFB3F650184619B000E2D967 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CFB3F61F184619B000E2D967 /* Project object */; + proxyType = 1; + remoteGlobalIDString = CFB3F626184619B000E2D967; + remoteInfo = OAuthIOExample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + CF21067C1853267D00290710 /* TwitterViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TwitterViewController.h; sourceTree = ""; }; + CF21067D1853267D00290710 /* TwitterViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TwitterViewController.m; sourceTree = ""; }; + CFB3F627184619B000E2D967 /* OAuthIOExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OAuthIOExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CFB3F62A184619B000E2D967 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + CFB3F62C184619B000E2D967 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + CFB3F62E184619B000E2D967 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + CFB3F632184619B000E2D967 /* OAuthIOExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OAuthIOExample-Info.plist"; sourceTree = ""; }; + CFB3F634184619B000E2D967 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + CFB3F636184619B000E2D967 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + CFB3F638184619B000E2D967 /* OAuthIOExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OAuthIOExample-Prefix.pch"; sourceTree = ""; }; + CFB3F639184619B000E2D967 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + CFB3F63A184619B000E2D967 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + CFB3F63D184619B000E2D967 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + CFB3F63F184619B000E2D967 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; + CFB3F640184619B000E2D967 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; + CFB3F645184619B000E2D967 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + CFB3F64B184619B000E2D967 /* OAuthIOExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OAuthIOExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CFB3F64C184619B000E2D967 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + CFB3F654184619B000E2D967 /* OAuthIOExampleTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OAuthIOExampleTests-Info.plist"; sourceTree = ""; }; + CFB3F656184619B000E2D967 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + CFB3F658184619B000E2D967 /* OAuthIOExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OAuthIOExampleTests.m; sourceTree = ""; }; + CFB3F663184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLRequest+NSURLRequestAllowSSL.h"; sourceTree = ""; }; + CFB3F664184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLRequest+NSURLRequestAllowSSL.m"; sourceTree = ""; }; + CFB3F665184619CA00E2D967 /* OAuthIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIO.h; sourceTree = ""; }; + CFB3F666184619CA00E2D967 /* OAuthIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIO.m; sourceTree = ""; }; + CFB3F667184619CA00E2D967 /* OAuthIOData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIOData.h; sourceTree = ""; }; + CFB3F668184619CA00E2D967 /* OAuthIOData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOData.m; sourceTree = ""; }; + CFB3F669184619CA00E2D967 /* OAuthIOModal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIOModal.h; sourceTree = ""; }; + CFB3F66A184619CA00E2D967 /* OAuthIOModal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOModal.m; sourceTree = ""; }; + CFB3F66B184619CA00E2D967 /* OAuthIOModal.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OAuthIOModal.xib; sourceTree = ""; }; + CFB3F66C184619CA00E2D967 /* OAuthIORequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIORequest.h; sourceTree = ""; }; + CFB3F66D184619CA00E2D967 /* OAuthIORequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIORequest.m; sourceTree = ""; }; + CFE8FCC81846AAA9007C4BF6 /* GitHubViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GitHubViewController.h; sourceTree = ""; }; + CFE8FCC91846AAA9007C4BF6 /* GitHubViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GitHubViewController.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + CFB3F624184619B000E2D967 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CFB3F62D184619B000E2D967 /* CoreGraphics.framework in Frameworks */, + CFB3F62F184619B000E2D967 /* UIKit.framework in Frameworks */, + CFB3F62B184619B000E2D967 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFB3F648184619B000E2D967 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CFB3F64D184619B000E2D967 /* XCTest.framework in Frameworks */, + CFB3F64F184619B000E2D967 /* UIKit.framework in Frameworks */, + CFB3F64E184619B000E2D967 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + CFB3F61E184619B000E2D967 = { + isa = PBXGroup; + children = ( + CFB3F630184619B000E2D967 /* OAuthIOExample */, + CFB3F652184619B000E2D967 /* OAuthIOExampleTests */, + CFB3F629184619B000E2D967 /* Frameworks */, + CFB3F628184619B000E2D967 /* Products */, + ); + sourceTree = ""; + }; + CFB3F628184619B000E2D967 /* Products */ = { + isa = PBXGroup; + children = ( + CFB3F627184619B000E2D967 /* OAuthIOExample.app */, + CFB3F64B184619B000E2D967 /* OAuthIOExampleTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + CFB3F629184619B000E2D967 /* Frameworks */ = { + isa = PBXGroup; + children = ( + CFB3F62A184619B000E2D967 /* Foundation.framework */, + CFB3F62C184619B000E2D967 /* CoreGraphics.framework */, + CFB3F62E184619B000E2D967 /* UIKit.framework */, + CFB3F64C184619B000E2D967 /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CFB3F630184619B000E2D967 /* OAuthIOExample */ = { + isa = PBXGroup; + children = ( + CFB3F662184619B600E2D967 /* OAuthIOSDK */, + CFB3F639184619B000E2D967 /* AppDelegate.h */, + CFB3F63A184619B000E2D967 /* AppDelegate.m */, + CFB3F63C184619B000E2D967 /* Main.storyboard */, + CFB3F63F184619B000E2D967 /* FirstViewController.h */, + CFB3F640184619B000E2D967 /* FirstViewController.m */, + CFE8FCC81846AAA9007C4BF6 /* GitHubViewController.h */, + CFE8FCC91846AAA9007C4BF6 /* GitHubViewController.m */, + CF21067C1853267D00290710 /* TwitterViewController.h */, + CF21067D1853267D00290710 /* TwitterViewController.m */, + CFB3F645184619B000E2D967 /* Images.xcassets */, + CFB3F631184619B000E2D967 /* Supporting Files */, + ); + path = OAuthIOExample; + sourceTree = ""; + }; + CFB3F631184619B000E2D967 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + CFB3F632184619B000E2D967 /* OAuthIOExample-Info.plist */, + CFB3F633184619B000E2D967 /* InfoPlist.strings */, + CFB3F636184619B000E2D967 /* main.m */, + CFB3F638184619B000E2D967 /* OAuthIOExample-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + CFB3F652184619B000E2D967 /* OAuthIOExampleTests */ = { + isa = PBXGroup; + children = ( + CFB3F658184619B000E2D967 /* OAuthIOExampleTests.m */, + CFB3F653184619B000E2D967 /* Supporting Files */, + ); + path = OAuthIOExampleTests; + sourceTree = ""; + }; + CFB3F653184619B000E2D967 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + CFB3F654184619B000E2D967 /* OAuthIOExampleTests-Info.plist */, + CFB3F655184619B000E2D967 /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + CFB3F662184619B600E2D967 /* OAuthIOSDK */ = { + isa = PBXGroup; + children = ( + CFB3F663184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.h */, + CFB3F664184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.m */, + CFB3F665184619CA00E2D967 /* OAuthIO.h */, + CFB3F666184619CA00E2D967 /* OAuthIO.m */, + CFB3F667184619CA00E2D967 /* OAuthIOData.h */, + CFB3F668184619CA00E2D967 /* OAuthIOData.m */, + CFB3F669184619CA00E2D967 /* OAuthIOModal.h */, + CFB3F66A184619CA00E2D967 /* OAuthIOModal.m */, + CFB3F66B184619CA00E2D967 /* OAuthIOModal.xib */, + CFB3F66C184619CA00E2D967 /* OAuthIORequest.h */, + CFB3F66D184619CA00E2D967 /* OAuthIORequest.m */, + ); + name = OAuthIOSDK; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + CFB3F626184619B000E2D967 /* OAuthIOExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = CFB3F65C184619B000E2D967 /* Build configuration list for PBXNativeTarget "OAuthIOExample" */; + buildPhases = ( + CFB3F623184619B000E2D967 /* Sources */, + CFB3F624184619B000E2D967 /* Frameworks */, + CFB3F625184619B000E2D967 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OAuthIOExample; + productName = OAuthIOExample; + productReference = CFB3F627184619B000E2D967 /* OAuthIOExample.app */; + productType = "com.apple.product-type.application"; + }; + CFB3F64A184619B000E2D967 /* OAuthIOExampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = CFB3F65F184619B000E2D967 /* Build configuration list for PBXNativeTarget "OAuthIOExampleTests" */; + buildPhases = ( + CFB3F647184619B000E2D967 /* Sources */, + CFB3F648184619B000E2D967 /* Frameworks */, + CFB3F649184619B000E2D967 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + CFB3F651184619B000E2D967 /* PBXTargetDependency */, + ); + name = OAuthIOExampleTests; + productName = OAuthIOExampleTests; + productReference = CFB3F64B184619B000E2D967 /* OAuthIOExampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + CFB3F61F184619B000E2D967 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = Webshell; + TargetAttributes = { + CFB3F64A184619B000E2D967 = { + TestTargetID = CFB3F626184619B000E2D967; + }; + }; + }; + buildConfigurationList = CFB3F622184619B000E2D967 /* Build configuration list for PBXProject "OAuthIOExample" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CFB3F61E184619B000E2D967; + productRefGroup = CFB3F628184619B000E2D967 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + CFB3F626184619B000E2D967 /* OAuthIOExample */, + CFB3F64A184619B000E2D967 /* OAuthIOExampleTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + CFB3F625184619B000E2D967 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFB3F646184619B000E2D967 /* Images.xcassets in Resources */, + CFB3F635184619B000E2D967 /* InfoPlist.strings in Resources */, + CFB3F63E184619B000E2D967 /* Main.storyboard in Resources */, + CFB3F672184619CA00E2D967 /* OAuthIOModal.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFB3F649184619B000E2D967 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFB3F657184619B000E2D967 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CFB3F623184619B000E2D967 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFB3F673184619CA00E2D967 /* OAuthIORequest.m in Sources */, + CFB3F63B184619B000E2D967 /* AppDelegate.m in Sources */, + CFB3F641184619B000E2D967 /* FirstViewController.m in Sources */, + CFB3F66F184619CA00E2D967 /* OAuthIO.m in Sources */, + CFB3F637184619B000E2D967 /* main.m in Sources */, + CFE8FCCA1846AAA9007C4BF6 /* GitHubViewController.m in Sources */, + CF21067E1853267D00290710 /* TwitterViewController.m in Sources */, + CFB3F66E184619CA00E2D967 /* NSURLRequest+NSURLRequestAllowSSL.m in Sources */, + CFB3F670184619CA00E2D967 /* OAuthIOData.m in Sources */, + CFB3F671184619CA00E2D967 /* OAuthIOModal.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFB3F647184619B000E2D967 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CFB3F659184619B000E2D967 /* OAuthIOExampleTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + CFB3F651184619B000E2D967 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CFB3F626184619B000E2D967 /* OAuthIOExample */; + targetProxy = CFB3F650184619B000E2D967 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + CFB3F633184619B000E2D967 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + CFB3F634184619B000E2D967 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + CFB3F63C184619B000E2D967 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CFB3F63D184619B000E2D967 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + CFB3F655184619B000E2D967 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + CFB3F656184619B000E2D967 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + CFB3F65A184619B000E2D967 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + CFB3F65B184619B000E2D967 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + CFB3F65D184619B000E2D967 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "OAuthIOExample/OAuthIOExample-Prefix.pch"; + INFOPLIST_FILE = "OAuthIOExample/OAuthIOExample-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + CFB3F65E184619B000E2D967 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "OAuthIOExample/OAuthIOExample-Prefix.pch"; + INFOPLIST_FILE = "OAuthIOExample/OAuthIOExample-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + CFB3F660184619B000E2D967 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/OAuthIOExample.app/OAuthIOExample"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "OAuthIOExample/OAuthIOExample-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "OAuthIOExampleTests/OAuthIOExampleTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + CFB3F661184619B000E2D967 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/OAuthIOExample.app/OAuthIOExample"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "OAuthIOExample/OAuthIOExample-Prefix.pch"; + INFOPLIST_FILE = "OAuthIOExampleTests/OAuthIOExampleTests-Info.plist"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUNDLE_LOADER)"; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + CFB3F622184619B000E2D967 /* Build configuration list for PBXProject "OAuthIOExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CFB3F65A184619B000E2D967 /* Debug */, + CFB3F65B184619B000E2D967 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CFB3F65C184619B000E2D967 /* Build configuration list for PBXNativeTarget "OAuthIOExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CFB3F65D184619B000E2D967 /* Debug */, + CFB3F65E184619B000E2D967 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CFB3F65F184619B000E2D967 /* Build configuration list for PBXNativeTarget "OAuthIOExampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CFB3F660184619B000E2D967 /* Debug */, + CFB3F661184619B000E2D967 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = CFB3F61F184619B000E2D967 /* Project object */; +} diff --git a/Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/OAuthIOExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 68% rename from Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Demo/OAuthIOExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata index b735f94..25a7321 100644 --- a/Demo/oauthio.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Demo/OAuthIOExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:OAuthIOExample.xcodeproj"> diff --git a/Demo/oauthio/AppDelegate.h b/Demo/OAuthIOExample/AppDelegate.h similarity index 51% rename from Demo/oauthio/AppDelegate.h rename to Demo/OAuthIOExample/AppDelegate.h index 51fc915..eec27db 100644 --- a/Demo/oauthio/AppDelegate.h +++ b/Demo/OAuthIOExample/AppDelegate.h @@ -1,18 +1,14 @@ // // AppDelegate.h -// oauthio -// -// Copyright (c) 2013 Webshell. All rights reserved. +// OAuthIOExample // #import - -@class ViewController; +#import "OAuthIOModal.h" +#import "FirstViewController.h" @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) ViewController *viewController; - @end diff --git a/Demo/oauthio/AppDelegate.m b/Demo/OAuthIOExample/AppDelegate.m similarity index 71% rename from Demo/oauthio/AppDelegate.m rename to Demo/OAuthIOExample/AppDelegate.m index c45b617..51a601d 100644 --- a/Demo/oauthio/AppDelegate.m +++ b/Demo/OAuthIOExample/AppDelegate.m @@ -1,33 +1,19 @@ // // AppDelegate.m -// oauthio -// -// Copyright (c) 2013 Webshell. All rights reserved. +// OAuthIOExample // #import "AppDelegate.h" -#import "ViewController.h" +#import "FirstViewController.h" @implementation AppDelegate -- (void)dealloc -{ - [_window release]; - [_viewController release]; - [super dealloc]; -} - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; - // Override point for customization after application launch. - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease]; - } else { - self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease]; - } - self.window.rootViewController = self.viewController; - [self.window makeKeyAndVisible]; + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; + FirstViewController *firstViewController = [storyboard instantiateViewControllerWithIdentifier:@"FirstViewController"]; + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:firstViewController]; + self.window.rootViewController = navController; return YES; } @@ -35,10 +21,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { [OAuthIOModal handleOAuthIOResponse:url]; - + return (YES); } - - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. diff --git a/Demo/OAuthIOExample/Base.lproj/Main.storyboard b/Demo/OAuthIOExample/Base.lproj/Main.storyboard new file mode 100644 index 0000000..b59ff05 --- /dev/null +++ b/Demo/OAuthIOExample/Base.lproj/Main.storyboard @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Demo/OAuthIOExample/FirstViewController.h b/Demo/OAuthIOExample/FirstViewController.h new file mode 100644 index 0000000..1035df5 --- /dev/null +++ b/Demo/OAuthIOExample/FirstViewController.h @@ -0,0 +1,34 @@ +// +// FirstViewController.h +// OAuthIOExample +// + +#import +#import "OAuthIOModal.h" +#import "TwitterViewController.h" +#import "GitHubViewController.h" + +#define kTWITTER_BTN 1 +#define kGITHUB_BTN 2 + +@interface FirstViewController : UIViewController +{ +@private + NSInteger _buttonTag; +} + +@property (nonatomic, retain) OAuthIOModal *oauthio; + +@property (nonatomic, retain) TwitterViewController *twitterViewController; +@property (nonatomic, retain) OAuthIORequest *req_twitter; + +@property (nonatomic, retain) GitHubViewController *githubViewController; +@property (nonatomic, retain) OAuthIORequest *req_github; + + +@property (strong, nonatomic) IBOutlet UIButton *connectGithubBtn; +@property (strong, nonatomic) IBOutlet UIButton *connectTwitterBtn; + +- (IBAction)connectEvent:(id)sender; + +@end diff --git a/Demo/OAuthIOExample/FirstViewController.m b/Demo/OAuthIOExample/FirstViewController.m new file mode 100644 index 0000000..6d5ff20 --- /dev/null +++ b/Demo/OAuthIOExample/FirstViewController.m @@ -0,0 +1,87 @@ +// +// FirstViewController.m +// OAuthIOExample +// + + +#import "FirstViewController.h" + +@interface FirstViewController () + +@end + +@implementation FirstViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + _oauthio = [[OAuthIOModal alloc] initWithKey:@"WmKGOEutadU6jZ8agshVaz1VMiM" delegate:self]; + +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (IBAction)connectEvent:(id)sender +{ + _buttonTag = [sender tag]; + + if (_buttonTag == kTWITTER_BTN) + { + if (_req_twitter == nil) + { + [_oauthio showWithProvider:@"twitter"]; + } + else + { + _twitterViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"TwitterViewController"]; + _twitterViewController.request = _req_twitter; + [self.navigationController pushViewController:_twitterViewController animated:YES]; + } + } + else + { + if (_req_github == nil) + { + [_oauthio showWithProvider:@"github"]; + } + else + { + _githubViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"GithubViewController"]; + _githubViewController.request = _req_github; + [self.navigationController pushViewController:_githubViewController animated:YES]; + } + } +} + +#pragma mark - OAuthIO delegate methods + +- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request +{ + if (_buttonTag == kTWITTER_BTN) + { + _req_twitter = [request copy]; + _twitterViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"TwitterViewController"]; + _twitterViewController.request = _req_twitter; + [self.navigationController pushViewController:_twitterViewController animated:YES]; + } + else + { + _req_github = [request copy]; + _githubViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"GithubViewController"]; + _githubViewController.request = _req_github; + [self.navigationController pushViewController:_githubViewController animated:YES]; + } +} + +- (void)didFailWithOAuthIOError:(NSError *)error +{ + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.description delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; + [alert show]; +} + +@end diff --git a/Demo/OAuthIOExample/GitHubViewController.h b/Demo/OAuthIOExample/GitHubViewController.h new file mode 100644 index 0000000..c80ce45 --- /dev/null +++ b/Demo/OAuthIOExample/GitHubViewController.h @@ -0,0 +1,25 @@ +// +// FirstViewController.m +// OAuthIOExample +// + +#import +#import "OAuthIORequest.h" + +@interface GitHubViewController : UIViewController +{ +@private + NSString *_login; + NSArray *_outputArr; +} +@property (nonatomic, strong) OAuthIORequest *request; +@property (strong, nonatomic) IBOutlet UITableView *githubTableView; +@property (strong, nonatomic) IBOutlet UIToolbar *githubToolbar; +@property (strong, nonatomic) IBOutlet UIBarButtonItem *githubRefreshBtn; +@property (strong, nonatomic) IBOutlet UIBarButtonItem *githubAddBtn; + + +- (IBAction)resfreshRepo:(id)sender; +- (IBAction)addRepo:(id)sender; + +@end diff --git a/Demo/OAuthIOExample/GitHubViewController.m b/Demo/OAuthIOExample/GitHubViewController.m new file mode 100644 index 0000000..b85cca3 --- /dev/null +++ b/Demo/OAuthIOExample/GitHubViewController.m @@ -0,0 +1,125 @@ +// +// FirstViewController.m +// OAuthIOExample +// + + +#import "GitHubViewController.h" + +@interface GitHubViewController () + +@end + +@implementation GitHubViewController + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + [_githubToolbar setItems:[NSArray arrayWithObjects:_githubRefreshBtn, flexibleSpaceLeft, _githubAddBtn, nil]]; + + [_request get:@"/user" withParams:nil success:^(NSString *output, NSHTTPURLResponse *httpResponse) { + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[output dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil]; + _login = [dict objectForKey:@"login"]; + + if (_login) + [self getRepos]; + + }]; + +} + +- (void)didReceiveMemoryWarning +{ + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)getRepos +{ + NSString *url = [NSString stringWithFormat:@"/users/%@/repos", _login]; + [_request get:url withParams:nil success:^(NSString *output, NSHTTPURLResponse *httpResponse) + { + if (httpResponse.statusCode == 200) + { + _outputArr = [NSJSONSerialization JSONObjectWithData:[output dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil]; + [_githubTableView reloadData]; + } + + }]; + +} + +#pragma mark - Events +- (IBAction)resfreshRepo:(id)sender +{ + [self getRepos]; +} + +- (IBAction)addRepo:(id)sender +{ + UIAlertView *addRepoView = [[UIAlertView alloc] initWithTitle:@"Add a new Repo !" message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; + [addRepoView setAlertViewStyle:UIAlertViewStylePlainTextInput]; + [addRepoView show]; +} + +#pragma mark - UIAlerView delegate method +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == 1) + { + if (_login) + { + NSDictionary *params = @{@"name": [[alertView textFieldAtIndex:0] text]}; + + [_request setContentType:@"json"]; // Github specification - This line convert params to JSON + [_request post:@"/user/repos" withParams:params success:^(NSString *output, NSHTTPURLResponse *httpResponse) { + [self getRepos]; + }]; + } + } +} + +#pragma mark - UITableView delegate methods + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return ([_outputArr count]); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *cellId = @"tweetCell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; + + if (cell == nil) + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId]; + + if (_outputArr) + { + NSDictionary *dict = [_outputArr objectAtIndex:indexPath.row]; + + if (dict) + { + cell.textLabel.font = [UIFont fontWithName:cell.textLabel.font.fontName size:9.0]; + cell.detailTextLabel.font = [UIFont fontWithName:cell.textLabel.font.fontName size:8.0]; + cell.textLabel.text = [dict objectForKey:@"name"]; + cell.detailTextLabel.text = [dict objectForKey:@"created_at"]; + } + } + + return (cell); +} + + +@end diff --git a/Demo/OAuthIOExample/Images.xcassets/AppIcon.appiconset/Contents.json b/Demo/OAuthIOExample/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a396706 --- /dev/null +++ b/Demo/OAuthIOExample/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/OAuthIOExample/Images.xcassets/LaunchImage.launchimage/Contents.json b/Demo/OAuthIOExample/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..c79ebd3 --- /dev/null +++ b/Demo/OAuthIOExample/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "iphone", + "subtype" : "retina4", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.h b/Demo/OAuthIOExample/NSURLRequest+NSURLRequestAllowSSL.h similarity index 100% rename from Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.h rename to Demo/OAuthIOExample/NSURLRequest+NSURLRequestAllowSSL.h diff --git a/Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.m b/Demo/OAuthIOExample/NSURLRequest+NSURLRequestAllowSSL.m similarity index 100% rename from Demo/oauthio/NSURLRequest+NSURLRequestAllowSSL.m rename to Demo/OAuthIOExample/NSURLRequest+NSURLRequestAllowSSL.m diff --git a/Demo/oauthio/OAuthIO.h b/Demo/OAuthIOExample/OAuthIO.h similarity index 62% rename from Demo/oauthio/OAuthIO.h rename to Demo/OAuthIOExample/OAuthIO.h index 1cb0582..9422784 100644 --- a/Demo/oauthio/OAuthIO.h +++ b/Demo/OAuthIOExample/OAuthIO.h @@ -20,20 +20,25 @@ #import "OAuthIORequest.h" -typedef void (^SuccessBlock) (NSData *data, NSURLRequest *request); -typedef void (^ErrorBlock) (NSError *error); +typedef void (^OAuthIOSuccessBlock) (NSData *data, NSHTTPURLResponse *httpResponse); +typedef void (^OAuthIOErrorBlock) (NSError *error); @interface OAuthIO : NSObject { - NSString *_key; - NSMutableData *_responseData; +@private + NSURLConnection *_connection; + NSHTTPURLResponse *_response; + NSMutableURLRequest *_req; + NSMutableData *_responseData; } -@property (nonatomic, copy) SuccessBlock success; -@property (nonatomic, copy) ErrorBlock error; +@property (nonatomic, copy) OAuthIOSuccessBlock success; +@property (nonatomic, copy) OAuthIOErrorBlock error; + ++ (NSString *)getPublicKey; - (id)initWithKey:(NSString *)key; -- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error; +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(OAuthIOSuccessBlock)success error:(OAuthIOErrorBlock)error; @end diff --git a/Demo/oauthio/OAuthIORequest.m b/Demo/OAuthIOExample/OAuthIO.m similarity index 51% rename from Demo/oauthio/OAuthIORequest.m rename to Demo/OAuthIOExample/OAuthIO.m index 51a5396..b029d9a 100644 --- a/Demo/oauthio/OAuthIORequest.m +++ b/Demo/OAuthIOExample/OAuthIO.m @@ -15,76 +15,48 @@ * */ -#import "OAuthIORequest.h" +#import "OAuthIO.h" -@implementation OAuthIORequest +@implementation OAuthIO -+ (NSString *)encodeURL:(NSString *)str -{ - return ([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, nil, CFSTR("&?=+/:"), kCFStringEncodingUTF8) autorelease]); -} - -+ (NSString *)decodeURL:(NSString *)str -{ - return ([(NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8) autorelease]); -} +NSString *_key; -- (NSString *)buildQueryWithDictionnary:(NSDictionary *)params ++ (NSString *)getPublicKey { - NSString *query = [[[NSString alloc] init] autorelease]; - NSUInteger i = 1; - - for (NSString *key in [params allKeys]) - { - if ([key length] != 0 && ![key isEqualToString:@"p"]) - { - if (i == 1) - query = [query stringByAppendingFormat:@"?%@=%@", key, [params objectForKey:key]]; - else - query = [query stringByAppendingFormat:@"&%@=%@", key, [params objectForKey:key]]; - - i++; - } - } - - return (query); + return (_key); } -- (id)initWithBaseUrl:(NSString *)baseUrl +- (id)initWithKey:(NSString *)key { - self = [super init]; + self = [super init]; if (!self) return nil; - _baseUrl = baseUrl; + _key = key; return (self); } -- (void)requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(OAuthIOSuccessBlock)success error:(OAuthIOErrorBlock)error { _success = [success copy]; _error = [error copy]; - NSString *query = [self buildQueryWithDictionnary:params]; - NSString *url = [[[NSString alloc] initWithFormat:@"%@/%@%@", _baseUrl, [params objectForKey:@"p"], query] autorelease]; + NSString *queryString = [[NSString alloc] initWithFormat:@"%@/%@?k=%@&redirect_uri=%@", [NSString stringWithFormat:@"%@/auth", kOAUTHIO_URL], provider, _key, url]; - _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:queryString]]; [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; - [_connection start]; - [_connection release]; } - #pragma mark NSURLConnexion delegate methods - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { _responseData = [[NSMutableData alloc] init]; - _request = [(NSURLRequest *)response copy]; + _response = [response copy]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data @@ -94,7 +66,7 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - _success(_responseData, _request); + _success(_responseData, _response); } - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse @@ -107,5 +79,4 @@ - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)err _error(error); } - @end diff --git a/Demo/OAuthIOExample/OAuthIOData.h b/Demo/OAuthIOExample/OAuthIOData.h new file mode 100644 index 0000000..5aaa0d5 --- /dev/null +++ b/Demo/OAuthIOExample/OAuthIOData.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface OAuthIOData : NSObject + +- (id)initWithDictionary:(NSDictionary *)dict; + +@property (nonatomic, strong) NSMutableDictionary *request; +@property (nonatomic, strong) NSDictionary *request_parameters; +@property (nonatomic, strong) NSDictionary *request_query; +@property (nonatomic, strong) NSDictionary *request_headers; +@property (nonatomic, strong) NSDictionary *request_conf; + +@property (nonatomic, strong) NSString *oauth_token; +@property (nonatomic, strong) NSString *oauth_token_secret; +@property (nonatomic, strong) NSString *request_url; +@property (nonatomic, strong) NSString *provider; + +@end \ No newline at end of file diff --git a/Demo/OAuthIOExample/OAuthIOData.m b/Demo/OAuthIOExample/OAuthIOData.m new file mode 100644 index 0000000..d6b7526 --- /dev/null +++ b/Demo/OAuthIOExample/OAuthIOData.m @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIOData.h" + +@implementation OAuthIOData + +- (id)initWithDictionary:(NSDictionary *)dict +{ + self = [super init]; + + if (!self || !dict) + return (nil); + + _request = [[NSMutableDictionary alloc] init]; + + if ([[dict objectForKey:@"data"] objectForKey:@"access_token"] != nil) + { + _oauth_token = [[dict objectForKey:@"data"] objectForKey:@"access_token"]; + [_request setValue:_oauth_token forKey:@"token"]; + } + else if ([[dict objectForKey:@"data"] objectForKey:@"oauth_token"] != nil && [[dict objectForKey:@"data"] objectForKey:@"oauth_token_secret"] != nil) + { + _oauth_token = [[dict objectForKey:@"data"] objectForKey:@"oauth_token"]; + _oauth_token_secret = [[dict objectForKey:@"data"] objectForKey:@"oauth_token_secret"]; + + [_request setValue:_oauth_token forKey:@"oauth_token"]; + [_request setValue:_oauth_token_secret forKey:@"oauth_token_secret"]; + } + + _request_conf = [[dict objectForKey:@"data"] objectForKey:@"request"]; + _request_url = [_request_conf objectForKey:@"url"]; + _request_headers = [_request_conf objectForKey:@"headers"]; + _request_parameters = [_request_conf objectForKey:@"parameters"]; + _request_query = [_request_conf objectForKey:@"query"]; + _provider = [dict objectForKey:@"provider"]; + + for (NSString *key in [[dict objectForKey:@"data"] allKeys]) + { + if (![key isKindOfClass:[NSDictionary class]] || ![key isKindOfClass:[NSArray class]]) + [_request setValue:[[dict objectForKey:@"data"] valueForKey:key] forKey:key]; + } + + for (NSString *key in [[_request_conf objectForKey:@"parameters"] allKeys]) + { + if (![key isKindOfClass:[NSDictionary class]] || ![key isKindOfClass:[NSArray class]]) + [_request setValue:[[_request_conf objectForKey:@"parameters"] valueForKey:key] forKey:key]; + } + + return (self); +} + +@end diff --git a/Demo/oauthio/oauthio-Info.plist b/Demo/OAuthIOExample/OAuthIOExample-Info.plist similarity index 76% rename from Demo/oauthio/oauthio-Info.plist rename to Demo/OAuthIOExample/OAuthIOExample-Info.plist index 1c2efe6..afa56f9 100644 --- a/Demo/oauthio/oauthio-Info.plist +++ b/Demo/OAuthIOExample/OAuthIOExample-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - bundleIdentifier.${PRODUCT_NAME:rfc1034identifier} + Webshell.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -27,7 +27,7 @@ localhost CFBundleURLSchemes - myappname + myapp @@ -35,22 +35,27 @@ 1.0 LSRequiresIPhoneOS + UIMainStoryboardFile + Main UIRequiredDeviceCapabilities armv7 + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - diff --git a/Demo/OAuthIOExample/OAuthIOExample-Prefix.pch b/Demo/OAuthIOExample/OAuthIOExample-Prefix.pch new file mode 100644 index 0000000..82a2bb4 --- /dev/null +++ b/Demo/OAuthIOExample/OAuthIOExample-Prefix.pch @@ -0,0 +1,16 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#import + +#ifndef __IPHONE_5_0 +#warning "This project uses features only available in iOS SDK 5.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/Demo/oauthio/OAuthIOModal.h b/Demo/OAuthIOExample/OAuthIOModal.h similarity index 80% rename from Demo/oauthio/OAuthIOModal.h rename to Demo/OAuthIOExample/OAuthIOModal.h index a7f07fd..e3401c2 100644 --- a/Demo/oauthio/OAuthIOModal.h +++ b/Demo/OAuthIOExample/OAuthIOModal.h @@ -24,25 +24,30 @@ @protocol OAuthIODelegate -- (void)didReceiveOAuthIOResponse:(NSDictionary *)result; +- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request; - (void)didFailWithOAuthIOError:(NSError *)error; @end @interface OAuthIOModal : UIViewController { + +@private + OAuthIO *_oauth; + OAuthIOData *_oauthio_data; + OAuthIORequest *_request; + NSString *_key; NSString *_scheme; NSString *_callback_url; - OAuthIO *_oauth; UIViewController *_rootViewController; + UIWebView *_browser; + UINavigationBar *_navigationBar; NSUInteger _navigationBarHeight; + } -@property (nonatomic, retain) id delegate; -@property (nonatomic, retain) NSString *provider; -@property (nonatomic, retain) UINavigationBar *navigationBar; -@property (nonatomic, retain) IBOutlet UIWebView *browser; +@property (weak) id delegate; + (void) handleOAuthIOResponse:(NSURL *)url; diff --git a/Demo/oauthio/OAuthIOModal.m b/Demo/OAuthIOExample/OAuthIOModal.m similarity index 77% rename from Demo/oauthio/OAuthIOModal.m rename to Demo/OAuthIOExample/OAuthIOModal.m index 548d18b..164e0a3 100644 --- a/Demo/oauthio/OAuthIOModal.m +++ b/Demo/OAuthIOExample/OAuthIOModal.m @@ -41,7 +41,6 @@ - (void)viewDidLoad [super viewDidLoad]; [_browser setFrame:CGRectMake(0, _navigationBarHeight, _browser.frame.size.width, _browser.frame.size.height - _navigationBarHeight - 1)]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTokens:) name:@"OAuthIOGetTokens" object:nil]; } @@ -50,12 +49,9 @@ - (void)didReceiveMemoryWarning [super didReceiveMemoryWarning]; } -- (void)dealloc { +- (void)dealloc +{ [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_browser release]; - [_rootViewController release]; - [_navigationBar release]; - [super dealloc]; } - (id)initWithKey:(NSString *)key delegate:(id)delegate @@ -83,40 +79,29 @@ - (id)initWithKey:(NSString *)key delegate:(id)delegate - (void)getTokens:(NSNotification *)notification { - NSString *url = [OAuthIORequest decodeURL:[NSString stringWithFormat:@"%@", [notification.userInfo objectForKey:@"URL"]]]; - NSUInteger start_pos = [url rangeOfString:@"="].location + 1; NSString *json = [url substringWithRange:NSMakeRange(start_pos, [url length] - start_pos)]; - - NSError *error = nil; NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; - NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease]; - - + if (jsonData) { - NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; + NSError *error = nil; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; if (error) { if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; - + return; } - NSArray *keys = [jsonObject objectForKey:@"data"]; - - for (NSString *key in keys) - { - if ([key isEqualToString:@"request"]) continue; // clean response - - [dict setValue:[keys valueForKey:key] forKey:key]; - } - + _oauthio_data = [[OAuthIOData alloc] initWithDictionary:jsonDict]; + _request = [[OAuthIORequest alloc] initWithOAuthIOData:_oauthio_data]; + if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)]) - [self.delegate didReceiveOAuthIOResponse:dict]; + [self.delegate didReceiveOAuthIOResponse:_request]; } } @@ -128,9 +113,9 @@ - (void)initNavigationBar _navigationBar = [[UINavigationBar alloc] init]; [_navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth]; - UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:@""] autorelease]; - UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)] autorelease]; - UIBarButtonItem *refreshButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:nil action:@selector(refreshOperation)] autorelease]; + UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:@""]; + UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)]; + UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:nil action:@selector(refreshOperation)]; [navItem setRightBarButtonItem:cancelButton]; [navItem setLeftBarButtonItem:refreshButton]; @@ -156,7 +141,7 @@ - (void)cancelOperation { NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; [errorDetail setValue:@"Operation canceled" forKey:NSLocalizedDescriptionKey]; - NSError *error = [[[NSError alloc] initWithDomain:@"OAuthIO" code:100 userInfo:errorDetail] autorelease]; + NSError *error = [[NSError alloc] initWithDomain:@"OAuthIO" code:100 userInfo:errorDetail]; if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; @@ -165,7 +150,7 @@ - (void)cancelOperation [self dismissViewControllerAnimated:YES completion:nil]; } -- (BOOL) initCustomCallbackURL +- (BOOL)initCustomCallbackURL { NSDictionary *customURLDict = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"] objectAtIndex:0]; @@ -179,7 +164,7 @@ - (BOOL) initCustomCallbackURL _callback_url = [[NSString alloc] initWithFormat:@"%@://%@", _scheme, _host]; else { - UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"OAuthIO" message:@"You must define a custom scheme and an url identifier in your plist configuration file" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"OAuthIO" message:@"You must define a custom scheme and an url identifier in your plist configuration file" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; return (NO); @@ -191,19 +176,17 @@ - (BOOL) initCustomCallbackURL - (void)showWithProvider:(NSString *)provider { - _provider = provider; - - [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSURLRequest *request){ + [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSHTTPURLResponse *httpResponse){ [_rootViewController presentViewController:self animated:YES completion:^{ - [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:request.URL]; + [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:httpResponse.URL]; }]; } error:^(NSError *error) { - if ([self.delegate respondsToSelector:@selector(oauth:didFailWithError:)]) + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; }]; } diff --git a/Demo/oauthio/OAuthIOModal.xib b/Demo/OAuthIOExample/OAuthIOModal.xib similarity index 100% rename from Demo/oauthio/OAuthIOModal.xib rename to Demo/OAuthIOExample/OAuthIOModal.xib diff --git a/Demo/OAuthIOExample/OAuthIORequest.h b/Demo/OAuthIOExample/OAuthIORequest.h new file mode 100644 index 0000000..864266a --- /dev/null +++ b/Demo/OAuthIOExample/OAuthIORequest.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import +#include "OAuthIOData.h" +#include "OAuthIO.h" + +#define kOAUTHIO_URL @"https://oauth.io/" + +#define kOAUTHIO_GET_METHOD @"GET" +#define kOAUTHIO_POST_METHOD @"POST" +#define kOAUTHIO_PUT_METHOD @"PUT" +#define kOAUTHIO_PATCH_METHOD @"PATCH" +#define kOAUTHIO_DELETE_METHOD @"DELETE" + +typedef void (^RequestSuccessBlock) (NSString *output, NSHTTPURLResponse *httpResponse); +typedef void (^RequestErrorBlock) (NSError *error); + +@interface OAuthIORequest : NSObject +{ +@private + NSURLConnection *_connection; + NSHTTPURLResponse *_response; + NSMutableURLRequest *_req; + NSMutableData *_responseData; +} + +@property (nonatomic, copy) RequestSuccessBlock success; +@property (nonatomic, copy) RequestErrorBlock error; +@property (nonatomic, strong) OAuthIOData *data; +@property (nonatomic, strong) NSString *contentType; + + ++ (NSString *)encodeURL:(NSString *)str; ++ (NSString*)decodeURL:(NSString *)str; + +- (id)initWithOAuthIOData:(OAuthIOData *)data; +- (id)copyWithZone:(NSZone *)zone; + +- (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value; +- (void)get:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)post:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)put:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)patch:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)delete:(NSString *)resource success:(RequestSuccessBlock)success; + + +@end diff --git a/Demo/OAuthIOExample/OAuthIORequest.m b/Demo/OAuthIOExample/OAuthIORequest.m new file mode 100644 index 0000000..80ca85f --- /dev/null +++ b/Demo/OAuthIOExample/OAuthIORequest.m @@ -0,0 +1,321 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIORequest.h" + +@implementation OAuthIORequest + ++ (NSString *)encodeURL:(NSString *)str +{ + static NSString * const charactersToEscaped = @":/?&;+!@#$()~',*"; + return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)str, nil, (__bridge CFStringRef)charactersToEscaped, kCFStringEncodingUTF8)); +} + ++ (NSString *)decodeURL:(NSString *)str +{ + return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8)); +} + +- (id)initWithOAuthIOData:(OAuthIOData *)data +{ + self = [super init]; + if (!self) + + return (nil); + + _data = data; + + return (self); +} + +- (id)copyWithZone:(NSZone *)zone +{ + OAuthIORequest *request = [[OAuthIORequest allocWithZone:zone] initWithOAuthIOData:_data]; + + return (request); +} + +- (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andParams:(id)params +{ + if (_data.oauth_token != nil && _data.oauth_token_secret != nil) + { + NSMutableString *resxUrl = [NSMutableString stringWithString:resource]; + + if ([resxUrl characterAtIndex:0] != (int)'/') + [resxUrl insertString:@"/" atIndex:0]; + + NSString *oauthio_header = [NSString stringWithFormat:@"k=%@&oauthv=1&oauth_token=%@&oauth_token_secret=%@", [OAuthIO getPublicKey], _data.oauth_token, _data.oauth_token_secret]; + + NSMutableString *url = [NSMutableString stringWithFormat:@"%@/request/%@%@", kOAUTHIO_URL, _data.provider, resxUrl]; + + if (_data.request_query) + { + if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@%@", [self buildQueryWithDictionnary:_data.request_query], [self buildQueryWithDictionnary:params]]; + else + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:_data.request_query]]; + + } + else if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; + + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + [_req setValue:oauthio_header forHTTPHeaderField:@"oauthio"]; + [_req setHTTPMethod:method]; + + if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) + { + NSData *postData = [self buildPostParams:params]; + if (postData != nil) + [_req setHTTPBody:postData]; + } + + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + [_connection start]; + } + else if (_data.oauth_token != nil) + { + if (!_data.request) + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The provider does have an API request description" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; + [alert show]; + return; + } + + NSMutableString *resxUrl = [NSMutableString stringWithString:resource]; + + if ([resxUrl characterAtIndex:0] != (int)'/') + [resxUrl insertString:@"/" atIndex:0]; + + NSMutableString *url = [[NSMutableString alloc] initWithFormat:@"%@%@", [self replaceParam:_data.request_url values:_data.request], resxUrl]; + + if (_data.request_query) + { + if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@%@", [self buildQueryWithDictionnary:_data.request_query], [self buildQueryWithDictionnary:params]]; + else + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:_data.request_query]]; + + } + else if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; + + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + + if (_data.request_headers) + [self buildHeaderWithDictionnary:_data.request_headers]; + + [_req setHTTPMethod:method]; + + if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) + { + NSData *postData = [self buildPostParams:params]; + + if (postData != nil) + [_req setHTTPBody:postData]; + } + + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + [_connection start]; + } +} + +- (void)get:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_GET_METHOD andParams:params]; +} + +- (void)post:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_POST_METHOD andParams:params]; +} + +- (void)put:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_PUT_METHOD andParams:params]; +} + +- (void)patch:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_PATCH_METHOD andParams:params]; +} + +- (void)delete:(NSString *)resource success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_DELETE_METHOD andParams:nil]; +} + + + +- (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value +{ + [_req setValue:value forHTTPHeaderField:key]; +} + +- (NSString *)replaceParam:(NSString *)key values:(NSDictionary *)dict +{ + if (![key rangeOfString:@"{"].length) + return (key); + + __block NSString *ret = nil; + __block NSRange range; + + NSRegularExpression *regex = nil; + NSError *error = nil; + + regex = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{.*?\\}\\}" options:NSRegularExpressionCaseInsensitive error:&error]; + [regex enumerateMatchesInString:key options:0 range:NSMakeRange(0, [key length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) + { + range = NSMakeRange(match.range.location + 2, match.range.length - 4); + NSString *value = [dict objectForKey:[key substringWithRange:range]]; + ret = [regex stringByReplacingMatchesInString:key options:0 range:NSMakeRange(0, [key length]) withTemplate:value]; + }]; + + if (ret) + return (ret); + + regex = [NSRegularExpression regularExpressionWithPattern:@"\\{.*?\\}" options:NSRegularExpressionCaseInsensitive error:&error]; + [regex enumerateMatchesInString:key options:0 range:NSMakeRange(0, [key length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) + { + range = NSMakeRange(match.range.location + 1, match.range.length - 2); + NSString *value = [_data.request_parameters valueForKey:[key substringWithRange:range]]; + ret = [regex stringByReplacingMatchesInString:key options:0 range:NSMakeRange(0, [key length]) withTemplate:value]; + }]; + + return (ret); +} + +- (NSString *)buildQueryWithDictionnary:(NSDictionary *)params +{ + NSString *query = [[NSString alloc] init]; + NSUInteger i = 1; + + for (NSString *key in [params allKeys]) + { + if ([key length] != 0) + { + NSString *val = [params objectForKey:key]; + + if ([val length] != 0) + { + val = [self replaceParam:val values:_data.request]; + + if (i == 1) + query = [query stringByAppendingFormat:@"%@=%@", key, val]; + else + query = [query stringByAppendingFormat:@"&%@=%@", key, val]; + + } + + i++; + } + } + + return (query); +} + +- (NSString *)buildHeaderWithDictionnary:(NSDictionary *)params +{ + NSString *query = [[NSString alloc] init]; + + for (NSString *key in [params allKeys]) + { + if ([key length] != 0) + { + NSString *val = [params objectForKey:key]; + + if ([val length] != 0) + { + val = [self replaceParam:val values:_data.request]; + [self addHeaderWithKey:key andValue:val]; + } + } + } + + return (query); +} + +- (NSData *)buildPostParams:(id)params +{ + NSData *postData = nil; + if ([params isKindOfClass:[NSDictionary class]]) + { + if (_contentType != nil) + postData = [[self formatFromContentType:params] dataUsingEncoding:NSUTF8StringEncoding]; + else + postData = [[OAuthIORequest encodeURL:[self buildQueryWithDictionnary:params]] dataUsingEncoding:NSUTF8StringEncoding]; + } + else if ([params isKindOfClass:[NSString class]]) + postData = [params dataUsingEncoding:NSUTF8StringEncoding]; + + NSString *contentLength = [NSString stringWithFormat:@"%i", [postData length]]; + [self addHeaderWithKey:@"Content-Length" andValue:contentLength]; + [self addHeaderWithKey:@"Current-Type" andValue:@"application/x-www-form-urlencoded"]; + + return (postData); +} + +- (NSString *)formatFromContentType:(NSDictionary *)params +{ + if ([[_contentType lowercaseString] isEqualToString:@"application/json"] || [[_contentType lowercaseString] isEqualToString:@"json"]) + { + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil]; + NSString *json = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding]; + + [self addHeaderWithKey:@"Content-Type" andValue:@"application/json"]; + + return (json); + } + + return (nil); +} + +#pragma mark NSURLConnexion delegate methods +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response +{ + _responseData = [[NSMutableData alloc] init]; + _response = [response copy]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data +{ + [_responseData appendData:data]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection +{ + NSString *output = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding]; + _success(output, _response); + +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse +{ + return (nil); +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error +{ + _error(error); +} + +@end diff --git a/Demo/OAuthIOExample/TwitterViewController.h b/Demo/OAuthIOExample/TwitterViewController.h new file mode 100644 index 0000000..26949a6 --- /dev/null +++ b/Demo/OAuthIOExample/TwitterViewController.h @@ -0,0 +1,24 @@ +// +// FirstViewController.m +// OAuthIOExample +// + +#import +#import "OAuthIORequest.h" + +@interface TwitterViewController : UIViewController +{ +@private + NSArray *_outputArr; +} + +@property (nonatomic, strong) OAuthIORequest *request; +@property (strong, nonatomic) IBOutlet UITableView *tweetsTableView; +@property (strong, nonatomic) IBOutlet UIToolbar *twitterToolbar; +@property (strong, nonatomic) IBOutlet UIBarButtonItem *refreshBtn; +@property (strong, nonatomic) IBOutlet UIBarButtonItem *addTweetBtn; + +- (IBAction)refreshEvent:(id)sender; +- (IBAction)addTweetEvent:(id)sender; + +@end diff --git a/Demo/OAuthIOExample/TwitterViewController.m b/Demo/OAuthIOExample/TwitterViewController.m new file mode 100644 index 0000000..bd9300a --- /dev/null +++ b/Demo/OAuthIOExample/TwitterViewController.m @@ -0,0 +1,94 @@ +// +// FirstViewController.m +// OAuthIOExample +// + + +#import "TwitterViewController.h" + +@implementation TwitterViewController + +- (void)viewDidLoad +{ + // Add tweet button to the right... + UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + [_twitterToolbar setItems:[NSArray arrayWithObjects:_refreshBtn, flexibleSpaceLeft, _addTweetBtn, nil]]; + [self getTweets]; +} + +- (void)getTweets +{ + [_request get:@"/1.1/statuses/home_timeline.json" withParams:nil success:^(NSString *output, NSHTTPURLResponse *httpResponse) + { + if (httpResponse.statusCode == 200) + { + _outputArr = [NSJSONSerialization JSONObjectWithData:[output dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil]; + [_tweetsTableView reloadData]; + } + }]; +} + +- (void)refreshEvent:(id)sender +{ + [self getTweets]; +} + +- (IBAction)addTweetEvent:(id)sender +{ + UIAlertView *addTweetView = [[UIAlertView alloc] initWithTitle:@"New Teweet !" message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; + [addTweetView setAlertViewStyle:UIAlertViewStylePlainTextInput]; + [addTweetView show]; + +} + + +#pragma mark - UIAlerView delegate method + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + if (buttonIndex == 1) + { + NSDictionary *params = @{@"status": [[alertView textFieldAtIndex:0] text]}; + + [_request post:@"/1.1/statuses/update.json" withParams:params success:^(NSString *output, NSHTTPURLResponse *httpResponse) { + NSLog(@"add Tweet repsonse code : %i\n", httpResponse.statusCode); + [self getTweets]; + }]; + } +} + + +#pragma mark - UITableView delegate methods + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return ([_outputArr count]); +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *cellId = @"tweetCell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; + + if (cell == nil) + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId]; + + if (_outputArr) + { + NSDictionary *dict = [_outputArr objectAtIndex:indexPath.row]; + + if (dict) + { + cell.textLabel.font = [UIFont fontWithName:cell.textLabel.font.fontName size:9.0]; + cell.detailTextLabel.font = [UIFont fontWithName:cell.textLabel.font.fontName size:8.0]; + cell.textLabel.text = [dict objectForKey:@"text"]; + cell.detailTextLabel.text = [dict objectForKey:@"created_at"]; + } + } + + return (cell); +} + + +@end diff --git a/Demo/oauthio/en.lproj/InfoPlist.strings b/Demo/OAuthIOExample/en.lproj/InfoPlist.strings similarity index 100% rename from Demo/oauthio/en.lproj/InfoPlist.strings rename to Demo/OAuthIOExample/en.lproj/InfoPlist.strings diff --git a/Demo/oauthio/main.m b/Demo/OAuthIOExample/main.m similarity index 53% rename from Demo/oauthio/main.m rename to Demo/OAuthIOExample/main.m index 2141aba..36bbef8 100644 --- a/Demo/oauthio/main.m +++ b/Demo/OAuthIOExample/main.m @@ -1,16 +1,14 @@ // -// main.m -// oauthio -// -// Created by Termellil Walid on 29/07/13. -// Copyright (c) 2013 Webshell. All rights reserved. +// FirstViewController.m +// OAuthIOExample // + #import #import "AppDelegate.h" -int main(int argc, char *argv[]) +int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); diff --git a/Demo/oauthioTests/oauthioTests-Info.plist b/Demo/OAuthIOExampleTests/OAuthIOExampleTests-Info.plist similarity index 90% rename from Demo/oauthioTests/oauthioTests-Info.plist rename to Demo/OAuthIOExampleTests/OAuthIOExampleTests-Info.plist index dad347e..1e686a4 100644 --- a/Demo/oauthioTests/oauthioTests-Info.plist +++ b/Demo/OAuthIOExampleTests/OAuthIOExampleTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - bundleIdentifier.${PRODUCT_NAME:rfc1034identifier} + Webshell.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/Demo/OAuthIOExampleTests/OAuthIOExampleTests.m b/Demo/OAuthIOExampleTests/OAuthIOExampleTests.m new file mode 100644 index 0000000..3dce2d1 --- /dev/null +++ b/Demo/OAuthIOExampleTests/OAuthIOExampleTests.m @@ -0,0 +1,31 @@ +// +// FirstViewController.m +// OAuthIOExample +// + +#import + +@interface OAuthIOExampleTests : XCTestCase + +@end + +@implementation OAuthIOExampleTests + +- (void)setUp +{ + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown +{ + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample +{ + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); +} + +@end diff --git a/Demo/oauthioTests/en.lproj/InfoPlist.strings b/Demo/OAuthIOExampleTests/en.lproj/InfoPlist.strings similarity index 100% rename from Demo/oauthioTests/en.lproj/InfoPlist.strings rename to Demo/OAuthIOExampleTests/en.lproj/InfoPlist.strings diff --git a/Demo/oauthio.xcodeproj/project.pbxproj b/Demo/oauthio.xcodeproj/project.pbxproj deleted file mode 100644 index 865b9e7..0000000 --- a/Demo/oauthio.xcodeproj/project.pbxproj +++ /dev/null @@ -1,515 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - CF444ACF17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m in Sources */ = {isa = PBXBuildFile; fileRef = CF444ACE17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m */; }; - CF79EF5D17A7C92E0015C0DE /* OAuthIORequest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF79EF5C17A7C92E0015C0DE /* OAuthIORequest.m */; }; - CF79EF6417A7F7390015C0DE /* OAuthIOModal.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF79EF6317A7F7390015C0DE /* OAuthIOModal.xib */; }; - CF79EF6717A7F7870015C0DE /* OAuthIOModal.m in Sources */ = {isa = PBXBuildFile; fileRef = CF79EF6617A7F7870015C0DE /* OAuthIOModal.m */; }; - CF79EF6B17A80C9D0015C0DE /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = CF79EF6917A80C9D0015C0DE /* logo.png */; }; - CF79EF6C17A80C9D0015C0DE /* webshell-logo-rc1-2.png in Resources */ = {isa = PBXBuildFile; fileRef = CF79EF6A17A80C9D0015C0DE /* webshell-logo-rc1-2.png */; }; - CFC4318117A6A30700C828F8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318017A6A30700C828F8 /* UIKit.framework */; }; - CFC4318317A6A30700C828F8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318217A6A30700C828F8 /* Foundation.framework */; }; - CFC4318517A6A30700C828F8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318417A6A30700C828F8 /* CoreGraphics.framework */; }; - CFC4318B17A6A30700C828F8 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CFC4318917A6A30700C828F8 /* InfoPlist.strings */; }; - CFC4318D17A6A30700C828F8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC4318C17A6A30700C828F8 /* main.m */; }; - CFC4319117A6A30700C828F8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC4319017A6A30700C828F8 /* AppDelegate.m */; }; - CFC4319417A6A30700C828F8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC4319317A6A30700C828F8 /* ViewController.m */; }; - CFC4319717A6A30700C828F8 /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = CFC4319517A6A30700C828F8 /* ViewController_iPhone.xib */; }; - CFC4319A17A6A30700C828F8 /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = CFC4319817A6A30700C828F8 /* ViewController_iPad.xib */; }; - CFC431A217A6A30700C828F8 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC431A117A6A30700C828F8 /* SenTestingKit.framework */; }; - CFC431A317A6A30700C828F8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318017A6A30700C828F8 /* UIKit.framework */; }; - CFC431A417A6A30700C828F8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFC4318217A6A30700C828F8 /* Foundation.framework */; }; - CFC431AC17A6A30700C828F8 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CFC431AA17A6A30700C828F8 /* InfoPlist.strings */; }; - CFC431AF17A6A30700C828F8 /* oauthioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC431AE17A6A30700C828F8 /* oauthioTests.m */; }; - CFC431BB17A6A32D00C828F8 /* OAuthIO.m in Sources */ = {isa = PBXBuildFile; fileRef = CFC431BA17A6A32D00C828F8 /* OAuthIO.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - CFC431A517A6A30700C828F8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = CFC4317317A6A30700C828F8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = CFC4317B17A6A30700C828F8; - remoteInfo = oauthio; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - CF444ACD17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLRequest+NSURLRequestAllowSSL.h"; sourceTree = ""; }; - CF444ACE17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLRequest+NSURLRequestAllowSSL.m"; sourceTree = ""; }; - CF79EF5B17A7C92E0015C0DE /* OAuthIORequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIORequest.h; sourceTree = ""; }; - CF79EF5C17A7C92E0015C0DE /* OAuthIORequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIORequest.m; sourceTree = ""; }; - CF79EF6317A7F7390015C0DE /* OAuthIOModal.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OAuthIOModal.xib; sourceTree = ""; }; - CF79EF6517A7F7870015C0DE /* OAuthIOModal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIOModal.h; sourceTree = ""; }; - CF79EF6617A7F7870015C0DE /* OAuthIOModal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOModal.m; sourceTree = ""; }; - CF79EF6917A80C9D0015C0DE /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = ""; }; - CF79EF6A17A80C9D0015C0DE /* webshell-logo-rc1-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "webshell-logo-rc1-2.png"; sourceTree = ""; }; - CFC4317C17A6A30700C828F8 /* oauthio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = oauthio.app; sourceTree = BUILT_PRODUCTS_DIR; }; - CFC4318017A6A30700C828F8 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - CFC4318217A6A30700C828F8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - CFC4318417A6A30700C828F8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - CFC4318817A6A30700C828F8 /* oauthio-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "oauthio-Info.plist"; sourceTree = ""; }; - CFC4318A17A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - CFC4318C17A6A30700C828F8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - CFC4318E17A6A30700C828F8 /* oauthio-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "oauthio-Prefix.pch"; sourceTree = ""; }; - CFC4318F17A6A30700C828F8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - CFC4319017A6A30700C828F8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - CFC4319217A6A30700C828F8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; - CFC4319317A6A30700C828F8 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - CFC4319617A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; - CFC4319917A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; - CFC431A017A6A30700C828F8 /* oauthioTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = oauthioTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; - CFC431A117A6A30700C828F8 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; - CFC431A917A6A30700C828F8 /* oauthioTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "oauthioTests-Info.plist"; sourceTree = ""; }; - CFC431AB17A6A30700C828F8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - CFC431AD17A6A30700C828F8 /* oauthioTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = oauthioTests.h; sourceTree = ""; }; - CFC431AE17A6A30700C828F8 /* oauthioTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = oauthioTests.m; sourceTree = ""; }; - CFC431B917A6A32D00C828F8 /* OAuthIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIO.h; sourceTree = ""; }; - CFC431BA17A6A32D00C828F8 /* OAuthIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIO.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - CFC4317917A6A30700C828F8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CFC4318117A6A30700C828F8 /* UIKit.framework in Frameworks */, - CFC4318317A6A30700C828F8 /* Foundation.framework in Frameworks */, - CFC4318517A6A30700C828F8 /* CoreGraphics.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - CFC4319C17A6A30700C828F8 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CFC431A217A6A30700C828F8 /* SenTestingKit.framework in Frameworks */, - CFC431A317A6A30700C828F8 /* UIKit.framework in Frameworks */, - CFC431A417A6A30700C828F8 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - CF79EF6817A80C8E0015C0DE /* Images */ = { - isa = PBXGroup; - children = ( - CF79EF6917A80C9D0015C0DE /* logo.png */, - CF79EF6A17A80C9D0015C0DE /* webshell-logo-rc1-2.png */, - ); - name = Images; - sourceTree = ""; - }; - CFC4317117A6A30700C828F8 = { - isa = PBXGroup; - children = ( - CFC4318617A6A30700C828F8 /* oauthio */, - CFC431A717A6A30700C828F8 /* oauthioTests */, - CFC4317F17A6A30700C828F8 /* Frameworks */, - CFC4317D17A6A30700C828F8 /* Products */, - ); - sourceTree = ""; - }; - CFC4317D17A6A30700C828F8 /* Products */ = { - isa = PBXGroup; - children = ( - CFC4317C17A6A30700C828F8 /* oauthio.app */, - CFC431A017A6A30700C828F8 /* oauthioTests.octest */, - ); - name = Products; - sourceTree = ""; - }; - CFC4317F17A6A30700C828F8 /* Frameworks */ = { - isa = PBXGroup; - children = ( - CFC4318017A6A30700C828F8 /* UIKit.framework */, - CFC4318217A6A30700C828F8 /* Foundation.framework */, - CFC4318417A6A30700C828F8 /* CoreGraphics.framework */, - CFC431A117A6A30700C828F8 /* SenTestingKit.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - CFC4318617A6A30700C828F8 /* oauthio */ = { - isa = PBXGroup; - children = ( - CF79EF6817A80C8E0015C0DE /* Images */, - CFC431B817A6A31600C828F8 /* OAuthIOSDK */, - CFC4318F17A6A30700C828F8 /* AppDelegate.h */, - CFC4319017A6A30700C828F8 /* AppDelegate.m */, - CFC4319217A6A30700C828F8 /* ViewController.h */, - CFC4319317A6A30700C828F8 /* ViewController.m */, - CFC4319517A6A30700C828F8 /* ViewController_iPhone.xib */, - CFC4319817A6A30700C828F8 /* ViewController_iPad.xib */, - CFC4318717A6A30700C828F8 /* Supporting Files */, - ); - path = oauthio; - sourceTree = ""; - }; - CFC4318717A6A30700C828F8 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - CFC4318817A6A30700C828F8 /* oauthio-Info.plist */, - CFC4318917A6A30700C828F8 /* InfoPlist.strings */, - CFC4318C17A6A30700C828F8 /* main.m */, - CFC4318E17A6A30700C828F8 /* oauthio-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - CFC431A717A6A30700C828F8 /* oauthioTests */ = { - isa = PBXGroup; - children = ( - CFC431AD17A6A30700C828F8 /* oauthioTests.h */, - CFC431AE17A6A30700C828F8 /* oauthioTests.m */, - CFC431A817A6A30700C828F8 /* Supporting Files */, - ); - path = oauthioTests; - sourceTree = ""; - }; - CFC431A817A6A30700C828F8 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - CFC431A917A6A30700C828F8 /* oauthioTests-Info.plist */, - CFC431AA17A6A30700C828F8 /* InfoPlist.strings */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - CFC431B817A6A31600C828F8 /* OAuthIOSDK */ = { - isa = PBXGroup; - children = ( - CF79EF6317A7F7390015C0DE /* OAuthIOModal.xib */, - CF79EF6517A7F7870015C0DE /* OAuthIOModal.h */, - CF79EF6617A7F7870015C0DE /* OAuthIOModal.m */, - CFC431B917A6A32D00C828F8 /* OAuthIO.h */, - CFC431BA17A6A32D00C828F8 /* OAuthIO.m */, - CF79EF5B17A7C92E0015C0DE /* OAuthIORequest.h */, - CF79EF5C17A7C92E0015C0DE /* OAuthIORequest.m */, - CF444ACD17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.h */, - CF444ACE17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m */, - ); - name = OAuthIOSDK; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - CFC4317B17A6A30700C828F8 /* oauthio */ = { - isa = PBXNativeTarget; - buildConfigurationList = CFC431B217A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthio" */; - buildPhases = ( - CFC4317817A6A30700C828F8 /* Sources */, - CFC4317917A6A30700C828F8 /* Frameworks */, - CFC4317A17A6A30700C828F8 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = oauthio; - productName = oauthio; - productReference = CFC4317C17A6A30700C828F8 /* oauthio.app */; - productType = "com.apple.product-type.application"; - }; - CFC4319F17A6A30700C828F8 /* oauthioTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = CFC431B517A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthioTests" */; - buildPhases = ( - CFC4319B17A6A30700C828F8 /* Sources */, - CFC4319C17A6A30700C828F8 /* Frameworks */, - CFC4319D17A6A30700C828F8 /* Resources */, - CFC4319E17A6A30700C828F8 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - CFC431A617A6A30700C828F8 /* PBXTargetDependency */, - ); - name = oauthioTests; - productName = oauthioTests; - productReference = CFC431A017A6A30700C828F8 /* oauthioTests.octest */; - productType = "com.apple.product-type.bundle"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - CFC4317317A6A30700C828F8 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0450; - ORGANIZATIONNAME = Webshell; - }; - buildConfigurationList = CFC4317617A6A30700C828F8 /* Build configuration list for PBXProject "oauthio" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = CFC4317117A6A30700C828F8; - productRefGroup = CFC4317D17A6A30700C828F8 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - CFC4317B17A6A30700C828F8 /* oauthio */, - CFC4319F17A6A30700C828F8 /* oauthioTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - CFC4317A17A6A30700C828F8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CFC4318B17A6A30700C828F8 /* InfoPlist.strings in Resources */, - CFC4319717A6A30700C828F8 /* ViewController_iPhone.xib in Resources */, - CFC4319A17A6A30700C828F8 /* ViewController_iPad.xib in Resources */, - CF79EF6417A7F7390015C0DE /* OAuthIOModal.xib in Resources */, - CF79EF6B17A80C9D0015C0DE /* logo.png in Resources */, - CF79EF6C17A80C9D0015C0DE /* webshell-logo-rc1-2.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - CFC4319D17A6A30700C828F8 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CFC431AC17A6A30700C828F8 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - CFC4319E17A6A30700C828F8 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - CFC4317817A6A30700C828F8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CFC4318D17A6A30700C828F8 /* main.m in Sources */, - CFC4319117A6A30700C828F8 /* AppDelegate.m in Sources */, - CFC4319417A6A30700C828F8 /* ViewController.m in Sources */, - CFC431BB17A6A32D00C828F8 /* OAuthIO.m in Sources */, - CF444ACF17F319BD0016AAF6 /* NSURLRequest+NSURLRequestAllowSSL.m in Sources */, - CF79EF5D17A7C92E0015C0DE /* OAuthIORequest.m in Sources */, - CF79EF6717A7F7870015C0DE /* OAuthIOModal.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - CFC4319B17A6A30700C828F8 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - CFC431AF17A6A30700C828F8 /* oauthioTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - CFC431A617A6A30700C828F8 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = CFC4317B17A6A30700C828F8 /* oauthio */; - targetProxy = CFC431A517A6A30700C828F8 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - CFC4318917A6A30700C828F8 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - CFC4318A17A6A30700C828F8 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - CFC4319517A6A30700C828F8 /* ViewController_iPhone.xib */ = { - isa = PBXVariantGroup; - children = ( - CFC4319617A6A30700C828F8 /* en */, - ); - name = ViewController_iPhone.xib; - sourceTree = ""; - }; - CFC4319817A6A30700C828F8 /* ViewController_iPad.xib */ = { - isa = PBXVariantGroup; - children = ( - CFC4319917A6A30700C828F8 /* en */, - ); - name = ViewController_iPad.xib; - sourceTree = ""; - }; - CFC431AA17A6A30700C828F8 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - CFC431AB17A6A30700C828F8 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - CFC431B017A6A30700C828F8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; - SDKROOT = iphoneos7.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - CFC431B117A6A30700C828F8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - SDKROOT = iphoneos7.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - CFC431B317A6A30700C828F8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; - INFOPLIST_FILE = "oauthio/oauthio-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - CFC431B417A6A30700C828F8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; - INFOPLIST_FILE = "oauthio/oauthio-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; - CFC431B617A6A30700C828F8 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/oauthio.app/oauthio"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; - INFOPLIST_FILE = "oauthioTests/oauthioTests-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUNDLE_LOADER)"; - WRAPPER_EXTENSION = octest; - }; - name = Debug; - }; - CFC431B717A6A30700C828F8 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/oauthio.app/oauthio"; - FRAMEWORK_SEARCH_PATHS = ( - "\"$(SDKROOT)/Developer/Library/Frameworks\"", - "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "oauthio/oauthio-Prefix.pch"; - INFOPLIST_FILE = "oauthioTests/oauthioTests-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUNDLE_LOADER)"; - WRAPPER_EXTENSION = octest; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - CFC4317617A6A30700C828F8 /* Build configuration list for PBXProject "oauthio" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CFC431B017A6A30700C828F8 /* Debug */, - CFC431B117A6A30700C828F8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - CFC431B217A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthio" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CFC431B317A6A30700C828F8 /* Debug */, - CFC431B417A6A30700C828F8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - CFC431B517A6A30700C828F8 /* Build configuration list for PBXNativeTarget "oauthioTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - CFC431B617A6A30700C828F8 /* Debug */, - CFC431B717A6A30700C828F8 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = CFC4317317A6A30700C828F8 /* Project object */; -} diff --git a/Demo/oauthio/OAuthIO.m b/Demo/oauthio/OAuthIO.m deleted file mode 100644 index 3238b6a..0000000 --- a/Demo/oauthio/OAuthIO.m +++ /dev/null @@ -1,66 +0,0 @@ -/* - * (C) Copyright 2013 Webshell SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import "OAuthIO.h" - -#define kOAUTHIO_URL @"https://oauth.io/auth" - -@implementation OAuthIO - -- (id)initWithKey:(NSString *)key -{ - self = [super init]; - - if (!self) - return nil; - - _key = key; - - return (self); -} - -- (void)dealloc -{ - [super dealloc]; -} - -- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error -{ - _success = [success copy]; - _error = [error copy]; - - OAuthIORequest *request = [[OAuthIORequest alloc] initWithBaseUrl:kOAUTHIO_URL]; - - NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease]; - [params setValue:provider forKey:@"p"]; - [params setValue:_key forKey:@"k"]; - [params setValue:url forKey:@"redirect_uri"]; - - [request requestWithParams:params success:^(NSData *data, NSURLRequest *request) { - - _success(data, request); - - } error:^(NSError *error) { - - _error(error); - - }]; - - [request release]; -} - -@end diff --git a/Demo/oauthio/OAuthIORequest.h b/Demo/oauthio/OAuthIORequest.h deleted file mode 100644 index 7de8e87..0000000 --- a/Demo/oauthio/OAuthIORequest.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * (C) Copyright 2013 Webshell SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import - -typedef void (^RequestSuccessBlock) (NSData *data, NSURLRequest *request); -typedef void (^RequestErrorBlock) (NSError *error); - -@interface OAuthIORequest : NSObject -{ - NSURLConnection *_connection; - NSMutableURLRequest *_req; - NSMutableData *_responseData; - NSString *_baseUrl; -} - -@property (nonatomic, copy) RequestSuccessBlock success; -@property (nonatomic, copy) RequestErrorBlock error; -@property (nonatomic, copy) NSURLRequest *request; - -- (id) initWithBaseUrl:(NSString *)baseUrl; -- (void) requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error; -+ (NSString *)encodeURL:(NSString *)str; -+ (NSString*)decodeURL:(NSString *)str; - -@end diff --git a/Demo/oauthio/ViewController.h b/Demo/oauthio/ViewController.h deleted file mode 100644 index e51bb92..0000000 --- a/Demo/oauthio/ViewController.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// ViewController.h -// oauthio -// -// Copyright (c) 2013 Webshell. All rights reserved. -// - -#import -#import "OAuthIOModal.h" - -#define kTWITTER_BUTTON 1 -#define kFACEBOOK_BUTTON 2 -#define kGOOGLE_PLUS_BUTTON 3 -#define kLINKED_IN_BUTTON 4 - -@interface ViewController : UIViewController - -@property (nonatomic, retain) OAuthIOModal *oauthioModal; -@property (retain, nonatomic) IBOutlet UIButton *buttonTwitter; -@property (retain, nonatomic) IBOutlet UIButton *buttonFacebook; -@property (retain, nonatomic) IBOutlet UIButton *buttonGooglePlus; -@property (retain, nonatomic) IBOutlet UIButton *buttonLinkedIn; -@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; - -- (IBAction)connect:(id)sender; - -@end diff --git a/Demo/oauthio/ViewController.m b/Demo/oauthio/ViewController.m deleted file mode 100644 index a05fe2d..0000000 --- a/Demo/oauthio/ViewController.m +++ /dev/null @@ -1,98 +0,0 @@ -// -// ViewController.m -// oauthio -// -// Copyright (c) 2013 Webshell. All rights reserved. -// - -#import "ViewController.h" - -@interface ViewController () - -@end - -@implementation ViewController - - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - [_activityIndicator setHidden:YES]; - [_buttonTwitter setTag:kTWITTER_BUTTON]; - [_buttonFacebook setTag:kFACEBOOK_BUTTON]; - [_buttonGooglePlus setTag:kGOOGLE_PLUS_BUTTON]; - [_buttonLinkedIn setTag:kLINKED_IN_BUTTON]; - - _oauthioModal = [[OAuthIOModal alloc] initWithKey:@"WmKGOEutadU6jZ8agshVaz1VMiM" delegate:self]; -} - -- (void)didReceiveMemoryWarning -{ - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -- (void)dealloc { - - [_oauthioModal release]; - [_activityIndicator release]; - [_buttonTwitter release]; - [_buttonFacebook release]; - [_buttonGooglePlus release]; - [_buttonLinkedIn release]; - - [super dealloc]; -} - -- (IBAction)connect:(id)sender -{ - [_buttonTwitter setHidden:YES]; - [_buttonFacebook setHidden:YES]; - [_buttonGooglePlus setHidden:YES]; - [_buttonLinkedIn setHidden:YES]; - [_activityIndicator setHidden:NO]; - [_activityIndicator startAnimating]; - - NSUInteger button_id = ((UIButton *)sender).tag; - NSString *provider = nil; - - if (button_id == kTWITTER_BUTTON) - provider = @"twitter"; - else if (button_id == kFACEBOOK_BUTTON) - provider = @"facebook"; - else if (button_id == kGOOGLE_PLUS_BUTTON) - provider = @"google_plus"; - else if (button_id == kLINKED_IN_BUTTON) - provider = @"linkedin"; - - [_oauthioModal showWithProvider:provider]; -} - -- (void) hideActivityIndicator -{ - [_activityIndicator startAnimating]; - [_activityIndicator setHidden:YES]; - [_buttonTwitter setHidden:NO]; - [_buttonFacebook setHidden:NO]; - [_buttonGooglePlus setHidden:NO]; - [_buttonLinkedIn setHidden:NO]; -} - -#pragma mark OAuthIO delegate methods - -- (void)didReceiveOAuthIOResponse:(NSDictionary *)result -{ - [self hideActivityIndicator]; - - NSLog(@"\nRESULT:\n-------\n%@\n", result); -} - -- (void)didFailWithOAuthIOError:(NSError *)error -{ - [self hideActivityIndicator]; - - NSLog(@"\nERROR:\n--------\n%@\n", error.description); -} - -@end diff --git a/Demo/oauthio/en.lproj/ViewController_iPad.xib b/Demo/oauthio/en.lproj/ViewController_iPad.xib deleted file mode 100644 index 41d878c..0000000 --- a/Demo/oauthio/en.lproj/ViewController_iPad.xib +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demo/oauthio/en.lproj/ViewController_iPhone.xib b/Demo/oauthio/en.lproj/ViewController_iPhone.xib deleted file mode 100644 index 841df22..0000000 --- a/Demo/oauthio/en.lproj/ViewController_iPhone.xib +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Demo/oauthio/logo.png b/Demo/oauthio/logo.png deleted file mode 100644 index f2506c19ca7311eacca1bdb5c7d7bf5c4d67ea5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9427 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 - -#ifndef __IPHONE_4_0 -#warning "This project uses features only available in iOS SDK 4.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/Demo/oauthio/webshell-logo-rc1-2.png b/Demo/oauthio/webshell-logo-rc1-2.png deleted file mode 100644 index 2778d6adff8b9e36c7b0229d5e6c647c12685dc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13462 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 diff --git a/Demo/oauthioTests/oauthioTests.h b/Demo/oauthioTests/oauthioTests.h deleted file mode 100644 index 31a666c..0000000 --- a/Demo/oauthioTests/oauthioTests.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// oauthioTests.h -// oauthioTests -// -// Copyright (c) 2013 Webshell. All rights reserved. -// - -#import - -@interface oauthioTests : SenTestCase - -@end diff --git a/Demo/oauthioTests/oauthioTests.m b/Demo/oauthioTests/oauthioTests.m deleted file mode 100644 index 6f0cf94..0000000 --- a/Demo/oauthioTests/oauthioTests.m +++ /dev/null @@ -1,31 +0,0 @@ -// -// oauthioTests.m -// oauthioTests -// -// Copyright (c) 2013 Webshell. All rights reserved. -// - -#import "oauthioTests.h" - -@implementation oauthioTests - -- (void)setUp -{ - [super setUp]; - - // Set-up code here. -} - -- (void)tearDown -{ - // Tear-down code here. - - [super tearDown]; -} - -- (void)testExample -{ - STFail(@"Unit tests are not implemented yet in oauthioTests"); -} - -@end diff --git a/README.md b/README.md index e9b7587..b46c575 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ This is the official iOS SDK for [OAuth.io](https://oauth.io) ! * Supported on iOS 5 or later - * ARC not supported currently ### License @@ -31,7 +30,7 @@ Implement the method bellow in your AppDelegate File return (YES); } -Put #import "OAuthIOModal.h" in your source file and don't forget to adopt the OAuthIO protocol then in your ViewController instanciate the OAuthIOModal object +Put #import "OAuthIOModal.h" in your source file and don't forget to implement the OAuthIO protocol then in your ViewController instanciate the OAuthIOModal object // ViewController.h // ---------------- @@ -48,16 +47,24 @@ Put #import "OAuthIOModal.h" in your source file and don't forget to adopt the O ... OAuthIOModal oauthioModal = [[OAuthIOModal alloc] initWithKey:@"Public key" delegate:self]; - [oauthioModal showForProvider:@"facebook"]; + [oauthioModal showForProvider:@"github"]; ... Implement these delegate methods in your ViewController #pragma mark OAuthIO delegate methods - - (void)didReceiveOAuthIOResponse:(NSDictionary *)result + - (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request { - NSLog(@"Result : %@\n", result); + NSDictionary *params = @{@"name": @"New repo"}; + + [request setContentType:@"json"]; // Github specification - This line convert params to JSON + + [request post:@"/user/repos" withParams:params success:^(NSString *output, NSHTTPURLResponse *httpResponse) + { + NSLog(@"output:%@, status code:%i\n", output, httpResponse.statusCode); + }]; + } - (void)didFailWithOAuthIOError:(NSError *)error @@ -65,7 +72,16 @@ Implement these delegate methods in your ViewController NSLog(@"Error : %@\n", error.description); } -### Note -ARC is not yet supported, disable ARC for OAuthIO files +### Available methods + + - (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value; + + - (void)get:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; + + - (void)post:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; + + - (void)put:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; + + - (void)patch:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; -![custom_scheme](https://oauth.io/img/no-objc-arc.png) + - (void)delete:(NSString *)resource success:(RequestSuccessBlock)success; \ No newline at end of file diff --git a/Src/OAuthIO.h b/Src/OAuthIO.h index 1cb0582..9422784 100644 --- a/Src/OAuthIO.h +++ b/Src/OAuthIO.h @@ -20,20 +20,25 @@ #import "OAuthIORequest.h" -typedef void (^SuccessBlock) (NSData *data, NSURLRequest *request); -typedef void (^ErrorBlock) (NSError *error); +typedef void (^OAuthIOSuccessBlock) (NSData *data, NSHTTPURLResponse *httpResponse); +typedef void (^OAuthIOErrorBlock) (NSError *error); @interface OAuthIO : NSObject { - NSString *_key; - NSMutableData *_responseData; +@private + NSURLConnection *_connection; + NSHTTPURLResponse *_response; + NSMutableURLRequest *_req; + NSMutableData *_responseData; } -@property (nonatomic, copy) SuccessBlock success; -@property (nonatomic, copy) ErrorBlock error; +@property (nonatomic, copy) OAuthIOSuccessBlock success; +@property (nonatomic, copy) OAuthIOErrorBlock error; + ++ (NSString *)getPublicKey; - (id)initWithKey:(NSString *)key; -- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error; +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(OAuthIOSuccessBlock)success error:(OAuthIOErrorBlock)error; @end diff --git a/Src/OAuthIO.m b/Src/OAuthIO.m index 3238b6a..b029d9a 100644 --- a/Src/OAuthIO.m +++ b/Src/OAuthIO.m @@ -17,10 +17,15 @@ #import "OAuthIO.h" -#define kOAUTHIO_URL @"https://oauth.io/auth" - @implementation OAuthIO +NSString *_key; + ++ (NSString *)getPublicKey +{ + return (_key); +} + - (id)initWithKey:(NSString *)key { self = [super init]; @@ -33,34 +38,45 @@ - (id)initWithKey:(NSString *)key return (self); } -- (void)dealloc -{ - [super dealloc]; -} - -- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(SuccessBlock)success error:(ErrorBlock)error +- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(OAuthIOSuccessBlock)success error:(OAuthIOErrorBlock)error { _success = [success copy]; _error = [error copy]; - OAuthIORequest *request = [[OAuthIORequest alloc] initWithBaseUrl:kOAUTHIO_URL]; - - NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease]; - [params setValue:provider forKey:@"p"]; - [params setValue:_key forKey:@"k"]; - [params setValue:url forKey:@"redirect_uri"]; - - [request requestWithParams:params success:^(NSData *data, NSURLRequest *request) { - - _success(data, request); - - } error:^(NSError *error) { - - _error(error); - - }]; + NSString *queryString = [[NSString alloc] initWithFormat:@"%@/%@?k=%@&redirect_uri=%@", [NSString stringWithFormat:@"%@/auth", kOAUTHIO_URL], provider, _key, url]; - [request release]; + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:queryString]]; + [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + [_connection start]; +} + +#pragma mark NSURLConnexion delegate methods + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response +{ + _responseData = [[NSMutableData alloc] init]; + _response = [response copy]; +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data +{ + [_responseData appendData:data]; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection +{ + _success(_responseData, _response); +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse +{ + return (nil); +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error +{ + _error(error); } @end diff --git a/Src/OAuthIOData.h b/Src/OAuthIOData.h new file mode 100644 index 0000000..5aaa0d5 --- /dev/null +++ b/Src/OAuthIOData.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface OAuthIOData : NSObject + +- (id)initWithDictionary:(NSDictionary *)dict; + +@property (nonatomic, strong) NSMutableDictionary *request; +@property (nonatomic, strong) NSDictionary *request_parameters; +@property (nonatomic, strong) NSDictionary *request_query; +@property (nonatomic, strong) NSDictionary *request_headers; +@property (nonatomic, strong) NSDictionary *request_conf; + +@property (nonatomic, strong) NSString *oauth_token; +@property (nonatomic, strong) NSString *oauth_token_secret; +@property (nonatomic, strong) NSString *request_url; +@property (nonatomic, strong) NSString *provider; + +@end \ No newline at end of file diff --git a/Src/OAuthIOData.m b/Src/OAuthIOData.m new file mode 100644 index 0000000..d6b7526 --- /dev/null +++ b/Src/OAuthIOData.m @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2013 Webshell SAS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "OAuthIOData.h" + +@implementation OAuthIOData + +- (id)initWithDictionary:(NSDictionary *)dict +{ + self = [super init]; + + if (!self || !dict) + return (nil); + + _request = [[NSMutableDictionary alloc] init]; + + if ([[dict objectForKey:@"data"] objectForKey:@"access_token"] != nil) + { + _oauth_token = [[dict objectForKey:@"data"] objectForKey:@"access_token"]; + [_request setValue:_oauth_token forKey:@"token"]; + } + else if ([[dict objectForKey:@"data"] objectForKey:@"oauth_token"] != nil && [[dict objectForKey:@"data"] objectForKey:@"oauth_token_secret"] != nil) + { + _oauth_token = [[dict objectForKey:@"data"] objectForKey:@"oauth_token"]; + _oauth_token_secret = [[dict objectForKey:@"data"] objectForKey:@"oauth_token_secret"]; + + [_request setValue:_oauth_token forKey:@"oauth_token"]; + [_request setValue:_oauth_token_secret forKey:@"oauth_token_secret"]; + } + + _request_conf = [[dict objectForKey:@"data"] objectForKey:@"request"]; + _request_url = [_request_conf objectForKey:@"url"]; + _request_headers = [_request_conf objectForKey:@"headers"]; + _request_parameters = [_request_conf objectForKey:@"parameters"]; + _request_query = [_request_conf objectForKey:@"query"]; + _provider = [dict objectForKey:@"provider"]; + + for (NSString *key in [[dict objectForKey:@"data"] allKeys]) + { + if (![key isKindOfClass:[NSDictionary class]] || ![key isKindOfClass:[NSArray class]]) + [_request setValue:[[dict objectForKey:@"data"] valueForKey:key] forKey:key]; + } + + for (NSString *key in [[_request_conf objectForKey:@"parameters"] allKeys]) + { + if (![key isKindOfClass:[NSDictionary class]] || ![key isKindOfClass:[NSArray class]]) + [_request setValue:[[_request_conf objectForKey:@"parameters"] valueForKey:key] forKey:key]; + } + + return (self); +} + +@end diff --git a/Src/OAuthIOModal.h b/Src/OAuthIOModal.h index a7f07fd..e3401c2 100644 --- a/Src/OAuthIOModal.h +++ b/Src/OAuthIOModal.h @@ -24,25 +24,30 @@ @protocol OAuthIODelegate -- (void)didReceiveOAuthIOResponse:(NSDictionary *)result; +- (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request; - (void)didFailWithOAuthIOError:(NSError *)error; @end @interface OAuthIOModal : UIViewController { + +@private + OAuthIO *_oauth; + OAuthIOData *_oauthio_data; + OAuthIORequest *_request; + NSString *_key; NSString *_scheme; NSString *_callback_url; - OAuthIO *_oauth; UIViewController *_rootViewController; + UIWebView *_browser; + UINavigationBar *_navigationBar; NSUInteger _navigationBarHeight; + } -@property (nonatomic, retain) id delegate; -@property (nonatomic, retain) NSString *provider; -@property (nonatomic, retain) UINavigationBar *navigationBar; -@property (nonatomic, retain) IBOutlet UIWebView *browser; +@property (weak) id delegate; + (void) handleOAuthIOResponse:(NSURL *)url; diff --git a/Src/OAuthIOModal.m b/Src/OAuthIOModal.m index 548d18b..164e0a3 100644 --- a/Src/OAuthIOModal.m +++ b/Src/OAuthIOModal.m @@ -41,7 +41,6 @@ - (void)viewDidLoad [super viewDidLoad]; [_browser setFrame:CGRectMake(0, _navigationBarHeight, _browser.frame.size.width, _browser.frame.size.height - _navigationBarHeight - 1)]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTokens:) name:@"OAuthIOGetTokens" object:nil]; } @@ -50,12 +49,9 @@ - (void)didReceiveMemoryWarning [super didReceiveMemoryWarning]; } -- (void)dealloc { +- (void)dealloc +{ [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_browser release]; - [_rootViewController release]; - [_navigationBar release]; - [super dealloc]; } - (id)initWithKey:(NSString *)key delegate:(id)delegate @@ -83,40 +79,29 @@ - (id)initWithKey:(NSString *)key delegate:(id)delegate - (void)getTokens:(NSNotification *)notification { - NSString *url = [OAuthIORequest decodeURL:[NSString stringWithFormat:@"%@", [notification.userInfo objectForKey:@"URL"]]]; - NSUInteger start_pos = [url rangeOfString:@"="].location + 1; NSString *json = [url substringWithRange:NSMakeRange(start_pos, [url length] - start_pos)]; - - NSError *error = nil; NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; - NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease]; - - + if (jsonData) { - NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; + NSError *error = nil; + NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; if (error) { if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; - + return; } - NSArray *keys = [jsonObject objectForKey:@"data"]; - - for (NSString *key in keys) - { - if ([key isEqualToString:@"request"]) continue; // clean response - - [dict setValue:[keys valueForKey:key] forKey:key]; - } - + _oauthio_data = [[OAuthIOData alloc] initWithDictionary:jsonDict]; + _request = [[OAuthIORequest alloc] initWithOAuthIOData:_oauthio_data]; + if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)]) - [self.delegate didReceiveOAuthIOResponse:dict]; + [self.delegate didReceiveOAuthIOResponse:_request]; } } @@ -128,9 +113,9 @@ - (void)initNavigationBar _navigationBar = [[UINavigationBar alloc] init]; [_navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth]; - UINavigationItem *navItem = [[[UINavigationItem alloc] initWithTitle:@""] autorelease]; - UIBarButtonItem *cancelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)] autorelease]; - UIBarButtonItem *refreshButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:nil action:@selector(refreshOperation)] autorelease]; + UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:@""]; + UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)]; + UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:nil action:@selector(refreshOperation)]; [navItem setRightBarButtonItem:cancelButton]; [navItem setLeftBarButtonItem:refreshButton]; @@ -156,7 +141,7 @@ - (void)cancelOperation { NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; [errorDetail setValue:@"Operation canceled" forKey:NSLocalizedDescriptionKey]; - NSError *error = [[[NSError alloc] initWithDomain:@"OAuthIO" code:100 userInfo:errorDetail] autorelease]; + NSError *error = [[NSError alloc] initWithDomain:@"OAuthIO" code:100 userInfo:errorDetail]; if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; @@ -165,7 +150,7 @@ - (void)cancelOperation [self dismissViewControllerAnimated:YES completion:nil]; } -- (BOOL) initCustomCallbackURL +- (BOOL)initCustomCallbackURL { NSDictionary *customURLDict = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"] objectAtIndex:0]; @@ -179,7 +164,7 @@ - (BOOL) initCustomCallbackURL _callback_url = [[NSString alloc] initWithFormat:@"%@://%@", _scheme, _host]; else { - UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"OAuthIO" message:@"You must define a custom scheme and an url identifier in your plist configuration file" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease]; + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"OAuthIO" message:@"You must define a custom scheme and an url identifier in your plist configuration file" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; return (NO); @@ -191,19 +176,17 @@ - (BOOL) initCustomCallbackURL - (void)showWithProvider:(NSString *)provider { - _provider = provider; - - [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSURLRequest *request){ + [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSHTTPURLResponse *httpResponse){ [_rootViewController presentViewController:self animated:YES completion:^{ - [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:request.URL]; + [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:httpResponse.URL]; }]; } error:^(NSError *error) { - if ([self.delegate respondsToSelector:@selector(oauth:didFailWithError:)]) + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; }]; } diff --git a/Src/OAuthIORequest.h b/Src/OAuthIORequest.h index 7de8e87..020ce97 100644 --- a/Src/OAuthIORequest.h +++ b/Src/OAuthIORequest.h @@ -16,25 +16,47 @@ */ #import +#include "OAuthIOData.h" +#include "OAuthIO.h" -typedef void (^RequestSuccessBlock) (NSData *data, NSURLRequest *request); +#define kOAUTHIO_URL @"https://192.168.1.40:6284/" + +#define kOAUTHIO_GET_METHOD @"GET" +#define kOAUTHIO_POST_METHOD @"POST" +#define kOAUTHIO_PUT_METHOD @"PUT" +#define kOAUTHIO_PATCH_METHOD @"PATCH" +#define kOAUTHIO_DELETE_METHOD @"DELETE" + +typedef void (^RequestSuccessBlock) (NSString *output, NSHTTPURLResponse *httpResponse); typedef void (^RequestErrorBlock) (NSError *error); -@interface OAuthIORequest : NSObject +@interface OAuthIORequest : NSObject { +@private NSURLConnection *_connection; + NSHTTPURLResponse *_response; NSMutableURLRequest *_req; NSMutableData *_responseData; - NSString *_baseUrl; } -@property (nonatomic, copy) RequestSuccessBlock success; -@property (nonatomic, copy) RequestErrorBlock error; -@property (nonatomic, copy) NSURLRequest *request; +@property (nonatomic, copy) RequestSuccessBlock success; +@property (nonatomic, copy) RequestErrorBlock error; +@property (nonatomic, strong) OAuthIOData *data; +@property (nonatomic, strong) NSString *contentType; + -- (id) initWithBaseUrl:(NSString *)baseUrl; -- (void) requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error; + (NSString *)encodeURL:(NSString *)str; + (NSString*)decodeURL:(NSString *)str; +- (id)initWithOAuthIOData:(OAuthIOData *)data; +- (id)copyWithZone:(NSZone *)zone; + +- (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value; +- (void)get:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)post:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)put:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)patch:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; +- (void)delete:(NSString *)resource success:(RequestSuccessBlock)success; + + @end diff --git a/Src/OAuthIORequest.m b/Src/OAuthIORequest.m index 51a5396..80ca85f 100644 --- a/Src/OAuthIORequest.m +++ b/Src/OAuthIORequest.m @@ -21,70 +21,279 @@ @implementation OAuthIORequest + (NSString *)encodeURL:(NSString *)str { - return ([(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, nil, CFSTR("&?=+/:"), kCFStringEncodingUTF8) autorelease]); + static NSString * const charactersToEscaped = @":/?&;+!@#$()~',*"; + return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)str, nil, (__bridge CFStringRef)charactersToEscaped, kCFStringEncodingUTF8)); } + (NSString *)decodeURL:(NSString *)str { - return ([(NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8) autorelease]); + return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8)); } -- (NSString *)buildQueryWithDictionnary:(NSDictionary *)params +- (id)initWithOAuthIOData:(OAuthIOData *)data { - NSString *query = [[[NSString alloc] init] autorelease]; - NSUInteger i = 1; + self = [super init]; + if (!self) + + return (nil); - for (NSString *key in [params allKeys]) + _data = data; + + return (self); +} + +- (id)copyWithZone:(NSZone *)zone +{ + OAuthIORequest *request = [[OAuthIORequest allocWithZone:zone] initWithOAuthIOData:_data]; + + return (request); +} + +- (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andParams:(id)params +{ + if (_data.oauth_token != nil && _data.oauth_token_secret != nil) { - if ([key length] != 0 && ![key isEqualToString:@"p"]) + NSMutableString *resxUrl = [NSMutableString stringWithString:resource]; + + if ([resxUrl characterAtIndex:0] != (int)'/') + [resxUrl insertString:@"/" atIndex:0]; + + NSString *oauthio_header = [NSString stringWithFormat:@"k=%@&oauthv=1&oauth_token=%@&oauth_token_secret=%@", [OAuthIO getPublicKey], _data.oauth_token, _data.oauth_token_secret]; + + NSMutableString *url = [NSMutableString stringWithFormat:@"%@/request/%@%@", kOAUTHIO_URL, _data.provider, resxUrl]; + + if (_data.request_query) { - if (i == 1) - query = [query stringByAppendingFormat:@"?%@=%@", key, [params objectForKey:key]]; + if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@%@", [self buildQueryWithDictionnary:_data.request_query], [self buildQueryWithDictionnary:params]]; else - query = [query stringByAppendingFormat:@"&%@=%@", key, [params objectForKey:key]]; - - i++; + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:_data.request_query]]; + + } + else if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; + + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + [_req setValue:oauthio_header forHTTPHeaderField:@"oauthio"]; + [_req setHTTPMethod:method]; + + if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) + { + NSData *postData = [self buildPostParams:params]; + if (postData != nil) + [_req setHTTPBody:postData]; } + + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + [_connection start]; } + else if (_data.oauth_token != nil) + { + if (!_data.request) + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The provider does have an API request description" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; + [alert show]; + return; + } + + NSMutableString *resxUrl = [NSMutableString stringWithString:resource]; - return (query); + if ([resxUrl characterAtIndex:0] != (int)'/') + [resxUrl insertString:@"/" atIndex:0]; + + NSMutableString *url = [[NSMutableString alloc] initWithFormat:@"%@%@", [self replaceParam:_data.request_url values:_data.request], resxUrl]; + + if (_data.request_query) + { + if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@%@", [self buildQueryWithDictionnary:_data.request_query], [self buildQueryWithDictionnary:params]]; + else + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:_data.request_query]]; + + } + else if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) + [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; + + _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; + + if (_data.request_headers) + [self buildHeaderWithDictionnary:_data.request_headers]; + + [_req setHTTPMethod:method]; + + if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) + { + NSData *postData = [self buildPostParams:params]; + + if (postData != nil) + [_req setHTTPBody:postData]; + } + + _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + [_connection start]; + } } -- (id)initWithBaseUrl:(NSString *)baseUrl +- (void)get:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success { - self = [super init]; + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_GET_METHOD andParams:params]; +} + +- (void)post:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_POST_METHOD andParams:params]; +} + +- (void)put:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_PUT_METHOD andParams:params]; +} + +- (void)patch:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_PATCH_METHOD andParams:params]; +} + +- (void)delete:(NSString *)resource success:(RequestSuccessBlock)success +{ + _success = [success copy]; + [self prepareAndExec:resource andMethod:kOAUTHIO_DELETE_METHOD andParams:nil]; +} + + + +- (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value +{ + [_req setValue:value forHTTPHeaderField:key]; +} + +- (NSString *)replaceParam:(NSString *)key values:(NSDictionary *)dict +{ + if (![key rangeOfString:@"{"].length) + return (key); - if (!self) - return nil; + __block NSString *ret = nil; + __block NSRange range; - _baseUrl = baseUrl; + NSRegularExpression *regex = nil; + NSError *error = nil; - return (self); + regex = [NSRegularExpression regularExpressionWithPattern:@"\\{\\{.*?\\}\\}" options:NSRegularExpressionCaseInsensitive error:&error]; + [regex enumerateMatchesInString:key options:0 range:NSMakeRange(0, [key length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) + { + range = NSMakeRange(match.range.location + 2, match.range.length - 4); + NSString *value = [dict objectForKey:[key substringWithRange:range]]; + ret = [regex stringByReplacingMatchesInString:key options:0 range:NSMakeRange(0, [key length]) withTemplate:value]; + }]; + + if (ret) + return (ret); + + regex = [NSRegularExpression regularExpressionWithPattern:@"\\{.*?\\}" options:NSRegularExpressionCaseInsensitive error:&error]; + [regex enumerateMatchesInString:key options:0 range:NSMakeRange(0, [key length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) + { + range = NSMakeRange(match.range.location + 1, match.range.length - 2); + NSString *value = [_data.request_parameters valueForKey:[key substringWithRange:range]]; + ret = [regex stringByReplacingMatchesInString:key options:0 range:NSMakeRange(0, [key length]) withTemplate:value]; + }]; + + return (ret); } -- (void)requestWithParams:(NSDictionary *)params success:(RequestSuccessBlock)success error:(RequestErrorBlock)error +- (NSString *)buildQueryWithDictionnary:(NSDictionary *)params { - _success = [success copy]; - _error = [error copy]; + NSString *query = [[NSString alloc] init]; + NSUInteger i = 1; + + for (NSString *key in [params allKeys]) + { + if ([key length] != 0) + { + NSString *val = [params objectForKey:key]; + + if ([val length] != 0) + { + val = [self replaceParam:val values:_data.request]; + + if (i == 1) + query = [query stringByAppendingFormat:@"%@=%@", key, val]; + else + query = [query stringByAppendingFormat:@"&%@=%@", key, val]; + + } + + i++; + } + } - NSString *query = [self buildQueryWithDictionnary:params]; - NSString *url = [[[NSString alloc] initWithFormat:@"%@/%@%@", _baseUrl, [params objectForKey:@"p"], query] autorelease]; + return (query); +} + +- (NSString *)buildHeaderWithDictionnary:(NSDictionary *)params +{ + NSString *query = [[NSString alloc] init]; + + for (NSString *key in [params allKeys]) + { + if ([key length] != 0) + { + NSString *val = [params objectForKey:key]; + + if ([val length] != 0) + { + val = [self replaceParam:val values:_data.request]; + [self addHeaderWithKey:key andValue:val]; + } + } + } - _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; - [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; - _connection = [[NSURLConnection alloc] initWithRequest:_req delegate:self]; + return (query); +} + +- (NSData *)buildPostParams:(id)params +{ + NSData *postData = nil; + if ([params isKindOfClass:[NSDictionary class]]) + { + if (_contentType != nil) + postData = [[self formatFromContentType:params] dataUsingEncoding:NSUTF8StringEncoding]; + else + postData = [[OAuthIORequest encodeURL:[self buildQueryWithDictionnary:params]] dataUsingEncoding:NSUTF8StringEncoding]; + } + else if ([params isKindOfClass:[NSString class]]) + postData = [params dataUsingEncoding:NSUTF8StringEncoding]; - [_connection start]; - [_connection release]; + NSString *contentLength = [NSString stringWithFormat:@"%i", [postData length]]; + [self addHeaderWithKey:@"Content-Length" andValue:contentLength]; + [self addHeaderWithKey:@"Current-Type" andValue:@"application/x-www-form-urlencoded"]; + + return (postData); } +- (NSString *)formatFromContentType:(NSDictionary *)params +{ + if ([[_contentType lowercaseString] isEqualToString:@"application/json"] || [[_contentType lowercaseString] isEqualToString:@"json"]) + { + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil]; + NSString *json = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding]; + + [self addHeaderWithKey:@"Content-Type" andValue:@"application/json"]; + + return (json); + } + + return (nil); +} #pragma mark NSURLConnexion delegate methods - - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { _responseData = [[NSMutableData alloc] init]; - _request = [(NSURLRequest *)response copy]; + _response = [response copy]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data @@ -94,7 +303,9 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - _success(_responseData, _request); + NSString *output = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding]; + _success(output, _response); + } - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse @@ -107,5 +318,4 @@ - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)err _error(error); } - @end From 83bd8ce00d780a7785cdd1a4daa28e047bb1fca3 Mon Sep 17 00:00:00 2001 From: Walid TERMELLIL Date: Sat, 7 Dec 2013 17:58:05 +0100 Subject: [PATCH 05/10] README updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b46c575..1c16afd 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Implement these delegate methods in your ViewController NSLog(@"Error : %@\n", error.description); } -### Available methods +### Available methods for OAuthIORequest - (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value; From 96853f1c17ebd950d46e5c2e3f15cbcae07b2355 Mon Sep 17 00:00:00 2001 From: Walid TERMELLIL Date: Wed, 18 Dec 2013 00:06:37 +0100 Subject: [PATCH 06/10] fix bug (headers); Can set NSData param for requests --- Demo/OAuthIOExample/OAuthIORequest.h | 1 + Demo/OAuthIOExample/OAuthIORequest.m | 44 ++++++++++++++++------------ README.md | 2 +- Src/OAuthIORequest.h | 3 +- Src/OAuthIORequest.m | 44 ++++++++++++++++------------ 5 files changed, 54 insertions(+), 40 deletions(-) diff --git a/Demo/OAuthIOExample/OAuthIORequest.h b/Demo/OAuthIOExample/OAuthIORequest.h index 864266a..95afc5b 100644 --- a/Demo/OAuthIOExample/OAuthIORequest.h +++ b/Demo/OAuthIOExample/OAuthIORequest.h @@ -37,6 +37,7 @@ typedef void (^RequestErrorBlock) (NSError *error); NSHTTPURLResponse *_response; NSMutableURLRequest *_req; NSMutableData *_responseData; + NSMutableDictionary *_headers; } @property (nonatomic, copy) RequestSuccessBlock success; diff --git a/Demo/OAuthIOExample/OAuthIORequest.m b/Demo/OAuthIOExample/OAuthIORequest.m index 80ca85f..ce5b9dd 100644 --- a/Demo/OAuthIOExample/OAuthIORequest.m +++ b/Demo/OAuthIOExample/OAuthIORequest.m @@ -36,16 +36,16 @@ - (id)initWithOAuthIOData:(OAuthIOData *)data if (!self) return (nil); - + _data = data; - + return (self); } - (id)copyWithZone:(NSZone *)zone { OAuthIORequest *request = [[OAuthIORequest allocWithZone:zone] initWithOAuthIOData:_data]; - + return (request); } @@ -61,7 +61,7 @@ - (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andPara NSString *oauthio_header = [NSString stringWithFormat:@"k=%@&oauthv=1&oauth_token=%@&oauth_token_secret=%@", [OAuthIO getPublicKey], _data.oauth_token, _data.oauth_token_secret]; NSMutableString *url = [NSMutableString stringWithFormat:@"%@/request/%@%@", kOAUTHIO_URL, _data.provider, resxUrl]; - + if (_data.request_query) { if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) @@ -73,10 +73,15 @@ - (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andPara else if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; + //url = [NSMutableString stringWithString:@"http://httpbin.org/post"]; _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; [_req setValue:oauthio_header forHTTPHeaderField:@"oauthio"]; [_req setHTTPMethod:method]; - + + if ([_headers count] && _headers != nil) + for (NSString *key in [_headers allKeys]) + [_req setValue:[_headers objectForKey:key] forHTTPHeaderField:key]; + if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) { NSData *postData = [self buildPostParams:params]; @@ -115,11 +120,14 @@ - (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andPara [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; - + [_req setHTTPMethod:method]; + if (_data.request_headers) [self buildHeaderWithDictionnary:_data.request_headers]; - - [_req setHTTPMethod:method]; + + if ([_headers count] && _headers != nil) + for (NSString *key in [_headers allKeys]) + [_req setValue:[_headers objectForKey:key] forHTTPHeaderField:key]; if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) { @@ -164,11 +172,12 @@ - (void)delete:(NSString *)resource success:(RequestSuccessBlock)success [self prepareAndExec:resource andMethod:kOAUTHIO_DELETE_METHOD andParams:nil]; } - - - (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value { - [_req setValue:value forHTTPHeaderField:key]; + if (!_headers) + _headers = [[NSMutableDictionary alloc] init]; + + [_headers setValue:value forKey:key]; } - (NSString *)replaceParam:(NSString *)key values:(NSDictionary *)dict @@ -246,7 +255,7 @@ - (NSString *)buildHeaderWithDictionnary:(NSDictionary *)params if ([val length] != 0) { val = [self replaceParam:val values:_data.request]; - [self addHeaderWithKey:key andValue:val]; + [_req setValue:val forHTTPHeaderField:key]; } } } @@ -266,11 +275,12 @@ - (NSData *)buildPostParams:(id)params } else if ([params isKindOfClass:[NSString class]]) postData = [params dataUsingEncoding:NSUTF8StringEncoding]; + else if ([params isKindOfClass:[NSData class]]) + postData = params; NSString *contentLength = [NSString stringWithFormat:@"%i", [postData length]]; [self addHeaderWithKey:@"Content-Length" andValue:contentLength]; - [self addHeaderWithKey:@"Current-Type" andValue:@"application/x-www-form-urlencoded"]; - + return (postData); } @@ -303,6 +313,7 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data - (void)connectionDidFinishLoading:(NSURLConnection *)connection { + _headers = nil; NSString *output = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding]; _success(output, _response); @@ -313,9 +324,4 @@ - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheRespo return (nil); } -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error -{ - _error(error); -} - @end diff --git a/README.md b/README.md index 1c16afd..13677e6 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Implement these delegate methods in your ViewController NSLog(@"Error : %@\n", error.description); } -### Available methods for OAuthIORequest +### Available methods for OAuthIORequest object - (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value; diff --git a/Src/OAuthIORequest.h b/Src/OAuthIORequest.h index 020ce97..95afc5b 100644 --- a/Src/OAuthIORequest.h +++ b/Src/OAuthIORequest.h @@ -19,7 +19,7 @@ #include "OAuthIOData.h" #include "OAuthIO.h" -#define kOAUTHIO_URL @"https://192.168.1.40:6284/" +#define kOAUTHIO_URL @"https://oauth.io/" #define kOAUTHIO_GET_METHOD @"GET" #define kOAUTHIO_POST_METHOD @"POST" @@ -37,6 +37,7 @@ typedef void (^RequestErrorBlock) (NSError *error); NSHTTPURLResponse *_response; NSMutableURLRequest *_req; NSMutableData *_responseData; + NSMutableDictionary *_headers; } @property (nonatomic, copy) RequestSuccessBlock success; diff --git a/Src/OAuthIORequest.m b/Src/OAuthIORequest.m index 80ca85f..ce5b9dd 100644 --- a/Src/OAuthIORequest.m +++ b/Src/OAuthIORequest.m @@ -36,16 +36,16 @@ - (id)initWithOAuthIOData:(OAuthIOData *)data if (!self) return (nil); - + _data = data; - + return (self); } - (id)copyWithZone:(NSZone *)zone { OAuthIORequest *request = [[OAuthIORequest allocWithZone:zone] initWithOAuthIOData:_data]; - + return (request); } @@ -61,7 +61,7 @@ - (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andPara NSString *oauthio_header = [NSString stringWithFormat:@"k=%@&oauthv=1&oauth_token=%@&oauth_token_secret=%@", [OAuthIO getPublicKey], _data.oauth_token, _data.oauth_token_secret]; NSMutableString *url = [NSMutableString stringWithFormat:@"%@/request/%@%@", kOAUTHIO_URL, _data.provider, resxUrl]; - + if (_data.request_query) { if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) @@ -73,10 +73,15 @@ - (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andPara else if ([method isEqualToString:kOAUTHIO_GET_METHOD] && params) [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; + //url = [NSMutableString stringWithString:@"http://httpbin.org/post"]; _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; [_req setValue:oauthio_header forHTTPHeaderField:@"oauthio"]; [_req setHTTPMethod:method]; - + + if ([_headers count] && _headers != nil) + for (NSString *key in [_headers allKeys]) + [_req setValue:[_headers objectForKey:key] forHTTPHeaderField:key]; + if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) { NSData *postData = [self buildPostParams:params]; @@ -115,11 +120,14 @@ - (void)prepareAndExec:(NSString *)resource andMethod:(NSString *)method andPara [url appendFormat:@"?%@", [self buildQueryWithDictionnary:params]]; _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; - + [_req setHTTPMethod:method]; + if (_data.request_headers) [self buildHeaderWithDictionnary:_data.request_headers]; - - [_req setHTTPMethod:method]; + + if ([_headers count] && _headers != nil) + for (NSString *key in [_headers allKeys]) + [_req setValue:[_headers objectForKey:key] forHTTPHeaderField:key]; if ([method isEqualToString:kOAUTHIO_POST_METHOD] || [method isEqualToString:kOAUTHIO_PUT_METHOD] || [method isEqualToString:kOAUTHIO_PATCH_METHOD]) { @@ -164,11 +172,12 @@ - (void)delete:(NSString *)resource success:(RequestSuccessBlock)success [self prepareAndExec:resource andMethod:kOAUTHIO_DELETE_METHOD andParams:nil]; } - - - (void)addHeaderWithKey:(NSString *)key andValue:(NSString *)value { - [_req setValue:value forHTTPHeaderField:key]; + if (!_headers) + _headers = [[NSMutableDictionary alloc] init]; + + [_headers setValue:value forKey:key]; } - (NSString *)replaceParam:(NSString *)key values:(NSDictionary *)dict @@ -246,7 +255,7 @@ - (NSString *)buildHeaderWithDictionnary:(NSDictionary *)params if ([val length] != 0) { val = [self replaceParam:val values:_data.request]; - [self addHeaderWithKey:key andValue:val]; + [_req setValue:val forHTTPHeaderField:key]; } } } @@ -266,11 +275,12 @@ - (NSData *)buildPostParams:(id)params } else if ([params isKindOfClass:[NSString class]]) postData = [params dataUsingEncoding:NSUTF8StringEncoding]; + else if ([params isKindOfClass:[NSData class]]) + postData = params; NSString *contentLength = [NSString stringWithFormat:@"%i", [postData length]]; [self addHeaderWithKey:@"Content-Length" andValue:contentLength]; - [self addHeaderWithKey:@"Current-Type" andValue:@"application/x-www-form-urlencoded"]; - + return (postData); } @@ -303,6 +313,7 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data - (void)connectionDidFinishLoading:(NSURLConnection *)connection { + _headers = nil; NSString *output = [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding]; _success(output, _response); @@ -313,9 +324,4 @@ - (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheRespo return (nil); } -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error -{ - _error(error); -} - @end From da1f63d4795593040ce8c2a05c8edd8bd4c20ecb Mon Sep 17 00:00:00 2001 From: Oliver Mason Date: Tue, 18 Feb 2014 13:47:01 +0000 Subject: [PATCH 07/10] adds the facility to specify options for request --- .../OAuthIOExample/Base.lproj/Main.storyboard | 4 +-- Src/OAuthIO.h | 6 +++- Src/OAuthIO.m | 22 ++++++++++++-- Src/OAuthIOModal.h | 1 + Src/OAuthIOModal.m | 30 ++++++++++--------- Src/OAuthIORequest.m | 2 +- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/Demo/OAuthIOExample/Base.lproj/Main.storyboard b/Demo/OAuthIOExample/Base.lproj/Main.storyboard index b59ff05..a366dd3 100644 --- a/Demo/OAuthIOExample/Base.lproj/Main.storyboard +++ b/Demo/OAuthIOExample/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + diff --git a/Src/OAuthIO.h b/Src/OAuthIO.h index 9422784..67c62d5 100644 --- a/Src/OAuthIO.h +++ b/Src/OAuthIO.h @@ -38,7 +38,11 @@ typedef void (^OAuthIOErrorBlock) (NSError *error); + (NSString *)getPublicKey; - (id)initWithKey:(NSString *)key; -- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(OAuthIOSuccessBlock)success error:(OAuthIOErrorBlock)error; +- (void)redirectWithProvider:(NSString *)provider + andUrl:(NSString *)url + andOptions:(NSDictionary*)options + success:(OAuthIOSuccessBlock)success + error:(OAuthIOErrorBlock)error; @end diff --git a/Src/OAuthIO.m b/Src/OAuthIO.m index b029d9a..f7eff89 100644 --- a/Src/OAuthIO.m +++ b/Src/OAuthIO.m @@ -38,12 +38,19 @@ - (id)initWithKey:(NSString *)key return (self); } -- (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success:(OAuthIOSuccessBlock)success error:(OAuthIOErrorBlock)error +- (void)redirectWithProvider:(NSString *)provider + andUrl:(NSString *)url + andOptions:(NSDictionary*)options + success:(OAuthIOSuccessBlock)success + error:(OAuthIOErrorBlock)error { _success = [success copy]; _error = [error copy]; + NSString *optionString = options? [NSString stringWithFormat:@"&opts=%@",[OAuthIO dictionaryToJSON:options]] + : @""; - NSString *queryString = [[NSString alloc] initWithFormat:@"%@/%@?k=%@&redirect_uri=%@", [NSString stringWithFormat:@"%@/auth", kOAUTHIO_URL], provider, _key, url]; + NSString *queryString = [[NSString alloc] initWithFormat:@"%@/%@?k=%@%@&redirect_uri=%@", [NSString stringWithFormat:@"%@/auth", kOAUTHIO_URL], provider, _key, optionString, url]; + NSLog(@"QUERY STRING IS: %@",queryString); _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:queryString]]; [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; @@ -51,6 +58,17 @@ - (void)redirectWithProvider:(NSString *)provider andUrl:(NSString *)url success [_connection start]; } ++(NSString*)dictionaryToJSON:(NSDictionary*)dictionary { + NSMutableString *retval = [@"{" mutableCopy]; + for (NSString *key in [dictionary allKeys]) { + NSString *value = dictionary[key]; + [retval appendString:[NSString stringWithFormat:@"\"%@\":\"%@\",", key, value]]; + } + [retval replaceCharactersInRange:NSMakeRange([retval length]-1, 1) withString:@"}"]; + return [OAuthIORequest encodeURL:retval]; +} + + #pragma mark NSURLConnexion delegate methods - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response diff --git a/Src/OAuthIOModal.h b/Src/OAuthIOModal.h index e3401c2..2560c0d 100644 --- a/Src/OAuthIOModal.h +++ b/Src/OAuthIOModal.h @@ -53,5 +53,6 @@ - (id)initWithKey:(NSString *)key delegate:(id)delegate; - (void)showWithProvider:(NSString *)provider; +- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options; @end diff --git a/Src/OAuthIOModal.m b/Src/OAuthIOModal.m index 164e0a3..2aa33c1 100644 --- a/Src/OAuthIOModal.m +++ b/Src/OAuthIOModal.m @@ -174,21 +174,23 @@ - (BOOL)initCustomCallbackURL } -- (void)showWithProvider:(NSString *)provider +- (void)showWithProvider:(NSString *)provider { + [self showWithProvider:provider options:nil]; +} + +- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options { - [_oauth redirectWithProvider:provider andUrl:_callback_url success:^(NSData *data, NSHTTPURLResponse *httpResponse){ - - [_rootViewController presentViewController:self animated:YES completion:^{ - - [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:httpResponse.URL]; - - }]; - - } error:^(NSError *error) { - - if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) - [self.delegate didFailWithOAuthIOError:error]; - }]; + [_oauth redirectWithProvider:provider + andUrl:_callback_url + andOptions:options + success:^(NSData *data, NSHTTPURLResponse *httpResponse){ + [_rootViewController presentViewController:self animated:YES completion:^{ + [_browser loadData:data MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:httpResponse.URL]; + }]; + } error:^(NSError *error) { + if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) + [self.delegate didFailWithOAuthIOError:error]; + }]; } #pragma mark - UIWebView delegate method diff --git a/Src/OAuthIORequest.m b/Src/OAuthIORequest.m index ce5b9dd..a46d5ac 100644 --- a/Src/OAuthIORequest.m +++ b/Src/OAuthIORequest.m @@ -278,7 +278,7 @@ - (NSData *)buildPostParams:(id)params else if ([params isKindOfClass:[NSData class]]) postData = params; - NSString *contentLength = [NSString stringWithFormat:@"%i", [postData length]]; + NSString *contentLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]]; [self addHeaderWithKey:@"Content-Length" andValue:contentLength]; return (postData); From 86b3678d9d677ef9a1986f11b9518c0873922370 Mon Sep 17 00:00:00 2001 From: Oliver Mason Date: Tue, 18 Feb 2014 13:57:20 +0000 Subject: [PATCH 08/10] Update README.md corrected method name and added example for new method --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13677e6..bc1ee68 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,10 @@ Put #import "OAuthIOModal.h" in your source file and don't forget to implement t ... OAuthIOModal oauthioModal = [[OAuthIOModal alloc] initWithKey:@"Public key" delegate:self]; - [oauthioModal showForProvider:@"github"]; + [oauthioModal showWithProvider:@"github"]; + + // Or use this if a state parameter needs to be passed through: + //[oauthioModal showWithProvider:@"github" options:@{@"state": @"STATE_VALUE"}]; ... Implement these delegate methods in your ViewController @@ -84,4 +87,4 @@ Implement these delegate methods in your ViewController - (void)patch:(NSString *)resource withParams:(id)params success:(RequestSuccessBlock)success; - - (void)delete:(NSString *)resource success:(RequestSuccessBlock)success; \ No newline at end of file + - (void)delete:(NSString *)resource success:(RequestSuccessBlock)success; From d8d7460af4bb24a7481dd94c42248573127d05e1 Mon Sep 17 00:00:00 2001 From: Oliver Mason Date: Wed, 19 Feb 2014 12:48:37 +0000 Subject: [PATCH 09/10] removes log statement --- Src/OAuthIO.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Src/OAuthIO.m b/Src/OAuthIO.m index f7eff89..b91c66d 100644 --- a/Src/OAuthIO.m +++ b/Src/OAuthIO.m @@ -50,7 +50,6 @@ - (void)redirectWithProvider:(NSString *)provider : @""; NSString *queryString = [[NSString alloc] initWithFormat:@"%@/%@?k=%@%@&redirect_uri=%@", [NSString stringWithFormat:@"%@/auth", kOAUTHIO_URL], provider, _key, optionString, url]; - NSLog(@"QUERY STRING IS: %@",queryString); _req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:queryString]]; [_req setValue:@"(iPhone; iPad) AppleWebKit" forHTTPHeaderField:@"User-Agent"]; From fc0605e610e7669b279fe99c77d2af88204a8e6a Mon Sep 17 00:00:00 2001 From: Oliver Mason Date: Thu, 20 Feb 2014 15:23:22 +0000 Subject: [PATCH 10/10] removes security risk SSL of disabled host verification --- Src/NSURLRequest+NSURLRequestAllowSSL.h | 24 ---------------------- Src/NSURLRequest+NSURLRequestAllowSSL.m | 27 ------------------------- 2 files changed, 51 deletions(-) delete mode 100644 Src/NSURLRequest+NSURLRequestAllowSSL.h delete mode 100644 Src/NSURLRequest+NSURLRequestAllowSSL.m diff --git a/Src/NSURLRequest+NSURLRequestAllowSSL.h b/Src/NSURLRequest+NSURLRequestAllowSSL.h deleted file mode 100644 index 78f2684..0000000 --- a/Src/NSURLRequest+NSURLRequestAllowSSL.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * (C) Copyright 2013 Webshell SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import - -@interface NSURLRequest (NSURLRequestAllowSSL) - -+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host; - -@end \ No newline at end of file diff --git a/Src/NSURLRequest+NSURLRequestAllowSSL.m b/Src/NSURLRequest+NSURLRequestAllowSSL.m deleted file mode 100644 index 0d7097c..0000000 --- a/Src/NSURLRequest+NSURLRequestAllowSSL.m +++ /dev/null @@ -1,27 +0,0 @@ -/* - * (C) Copyright 2013 Webshell SAS. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#import "NSURLRequest+NSURLRequestAllowSSL.h" - -@implementation NSURLRequest (NSURLRequestAllowSSL) - -+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host -{ - return YES; -} - -@end \ No newline at end of file