diff --git a/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOData.h b/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOData.h index 4af82c7..f243121 100644 --- a/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOData.h +++ b/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOData.h @@ -29,6 +29,7 @@ @property (nonatomic, strong) NSDictionary *request_conf; @property (nonatomic, strong) NSString *oauth_token; +@property (nonatomic, strong) NSString *code; @property (nonatomic, strong) NSString *oauth_token_secret; @property (nonatomic, strong) NSString *access_token; @property (nonatomic, strong) NSString *request_url; diff --git a/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOModal.h b/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOModal.h index cec0bd7..dd2215e 100644 --- a/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOModal.h +++ b/Dist/OAuthiOS.framework/Versions/A/Headers/OAuthIOModal.h @@ -25,6 +25,9 @@ @protocol OAuthIODelegate - (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request; - (void)didFailWithOAuthIOError:(NSError *)error; +- (void)didReceiveOAuthIOCode:(NSString *)code; +- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response; +- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error; @end @interface OAuthIOModal : UIViewController @@ -43,15 +46,19 @@ UIWebView *_browser; UINavigationBar *_navigationBar; NSUInteger _navigationBarHeight; + } - +@property NSMutableArray *saved_cookies; @property (weak) id delegate; +@property NSURLSession *session; +@property NSString *authUrl; - (id)initWithKey:(NSString *)key delegate:(id)delegate; - (id)initWithKey:(NSString *)key delegate:(id)delegate andOptions:(NSDictionary *) options; - (void)showWithProvider:(NSString *)provider; - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options; +- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl; - (BOOL) clearCache; - (BOOL) clearCacheForProvider:(NSString *)provider; - (BOOL) cacheAvailableForProvider:(NSString *)provider; diff --git a/Dist/OAuthiOS.framework/Versions/A/OAuthiOS b/Dist/OAuthiOS.framework/Versions/A/OAuthiOS index 342431e..c836705 100644 Binary files a/Dist/OAuthiOS.framework/Versions/A/OAuthiOS and b/Dist/OAuthiOS.framework/Versions/A/OAuthiOS differ diff --git a/OAuth.io.podspec b/OAuth.io.podspec index d6555e5..136fe69 100644 --- a/OAuth.io.podspec +++ b/OAuth.io.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "OAuth.io" - s.version = "1.1.2" + s.version = "1.2.4" s.summary = "OAuth that just works!" s.description = <<-DESC @@ -71,7 +71,7 @@ Pod::Spec.new do |s| # Supports git, hg, bzr, svn and HTTP. # - s.source = { :git => "https://github.com/oauth-io/oauth-ios.git", :tag => "1.1.1" } + s.source = { :git => "https://github.com/oauth-io/oauth-ios.git", :tag => "1.2.4" } # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # diff --git a/OAuthiOS.xcodeproj/project.pbxproj b/OAuthiOS.xcodeproj/project.pbxproj index 1dc14f4..59199b6 100644 --- a/OAuthiOS.xcodeproj/project.pbxproj +++ b/OAuthiOS.xcodeproj/project.pbxproj @@ -23,9 +23,7 @@ /* Begin PBXBuildFile section */ 710D9EB819507E4D00FA70A1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 710D9EB719507E4D00FA70A1 /* Foundation.framework */; }; - 710D9EBD19507E4D00FA70A1 /* OAuthiOS.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 710D9EBC19507E4D00FA70A1 /* OAuthiOS.h */; }; 710D9ECC19507E4D00FA70A1 /* libOAuthiOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 710D9EB419507E4D00FA70A1 /* libOAuthiOS.a */; }; - 710D9ED219507E4D00FA70A1 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 710D9ED019507E4D00FA70A1 /* InfoPlist.strings */; }; 710D9EDE19507F1300FA70A1 /* OAuthiOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 710D9EBC19507E4D00FA70A1 /* OAuthiOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 710D9FA519509B2800FA70A1 /* OAuthIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 710D9F9D19509B2800FA70A1 /* OAuthIO.m */; }; 710D9FA619509B2800FA70A1 /* OAuthIOData.m in Sources */ = {isa = PBXBuildFile; fileRef = 710D9F9F19509B2800FA70A1 /* OAuthIOData.m */; }; @@ -36,14 +34,12 @@ 710D9FB119509EDE00FA70A1 /* OAuthIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 710D9F9C19509B2800FA70A1 /* OAuthIO.h */; settings = {ATTRIBUTES = (Public, ); }; }; 711D496119536185002E37BD /* OAuth.io.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 711D496019536185002E37BD /* OAuth.io.podspec */; }; 711D4963195361E9002E37BD /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 711D4962195361E9002E37BD /* LICENSE */; }; - 711D49AA1953A0AC002E37BD /* OAuthIODataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 711D49A91953A0AC002E37BD /* OAuthIODataTests.m */; }; - 711E97F81954650A00CEF381 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 711E97F71954650A00CEF381 /* libOCMock.a */; }; - 711E97FA1954707500CEF381 /* OAuthIOTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 711E97F91954707500CEF381 /* OAuthIOTests.m */; }; - 711E97FC19547D9F00CEF381 /* OAuthIOModalTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 711E97FB19547D9F00CEF381 /* OAuthIOModalTests.m */; }; 714050351950B02A00D9283C /* OAuthIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 710D9F9D19509B2800FA70A1 /* OAuthIO.m */; }; 714050361950B02A00D9283C /* OAuthIOData.m in Sources */ = {isa = PBXBuildFile; fileRef = 710D9F9F19509B2800FA70A1 /* OAuthIOData.m */; }; 714050381950B02E00D9283C /* OAuthIORequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 710D9FA419509B2800FA70A1 /* OAuthIORequest.m */; }; 71B2666B19534F94006826F1 /* OAuthIOModal.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B2666A19534F94006826F1 /* OAuthIOModal.m */; }; + DF1F19341D9B1121009D0853 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF1F19331D9B1121009D0853 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + DF1F19361D9B1145009D0853 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF1F19351D9B1145009D0853 /* XCTest.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -70,7 +66,6 @@ dstPath = "include/$(PRODUCT_NAME)"; dstSubfolderSpec = 16; files = ( - 710D9EBD19507E4D00FA70A1 /* OAuthiOS.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -82,10 +77,6 @@ 710D9EBB19507E4D00FA70A1 /* OAuthiOS-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OAuthiOS-Prefix.pch"; sourceTree = ""; }; 710D9EBC19507E4D00FA70A1 /* OAuthiOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OAuthiOS.h; sourceTree = ""; }; 710D9EC419507E4D00FA70A1 /* OAuthiOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OAuthiOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 710D9EC519507E4D00FA70A1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - 710D9EC819507E4D00FA70A1 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - 710D9ECF19507E4D00FA70A1 /* OAuthiOSTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OAuthiOSTests-Info.plist"; sourceTree = ""; }; - 710D9ED119507E4D00FA70A1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 710D9F9C19509B2800FA70A1 /* OAuthIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIO.h; sourceTree = ""; }; 710D9F9D19509B2800FA70A1 /* OAuthIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIO.m; sourceTree = ""; }; 710D9F9E19509B2800FA70A1 /* OAuthIOData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthIOData.h; sourceTree = ""; }; @@ -95,13 +86,11 @@ 710D9FA419509B2800FA70A1 /* OAuthIORequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIORequest.m; sourceTree = ""; }; 711D496019536185002E37BD /* OAuth.io.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OAuth.io.podspec; sourceTree = ""; }; 711D4962195361E9002E37BD /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - 711D49A91953A0AC002E37BD /* OAuthIODataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIODataTests.m; sourceTree = ""; }; - 711E97F71954650A00CEF381 /* libOCMock.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libOCMock.a; path = usr/lib/libOCMock.a; sourceTree = ""; }; - 711E97F91954707500CEF381 /* OAuthIOTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOTests.m; sourceTree = ""; }; - 711E97FB19547D9F00CEF381 /* OAuthIOModalTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOModalTests.m; sourceTree = ""; }; 71B2666A19534F94006826F1 /* OAuthIOModal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAuthIOModal.m; sourceTree = ""; }; 71F3011F1950AB9A004515FC /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 71F301201950ABA7004515FC /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + DF1F19331D9B1121009D0853 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + DF1F19351D9B1145009D0853 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -109,6 +98,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DF1F19361D9B1145009D0853 /* XCTest.framework in Frameworks */, + DF1F19341D9B1121009D0853 /* UIKit.framework in Frameworks */, 710D9EB819507E4D00FA70A1 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -117,7 +108,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 711E97F81954650A00CEF381 /* libOCMock.a in Frameworks */, 710D9ECC19507E4D00FA70A1 /* libOAuthiOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -133,7 +123,6 @@ 71F301201950ABA7004515FC /* README.md */, 71F3011F1950AB9A004515FC /* .gitignore */, 710D9EB919507E4D00FA70A1 /* OAuthiOS */, - 710D9ECD19507E4D00FA70A1 /* OAuthiOSTests */, 710D9EB619507E4D00FA70A1 /* Frameworks */, 710D9EB519507E4D00FA70A1 /* Products */, ); @@ -151,10 +140,9 @@ 710D9EB619507E4D00FA70A1 /* Frameworks */ = { isa = PBXGroup; children = ( - 711E97F71954650A00CEF381 /* libOCMock.a */, + DF1F19351D9B1145009D0853 /* XCTest.framework */, + DF1F19331D9B1121009D0853 /* UIKit.framework */, 710D9EB719507E4D00FA70A1 /* Foundation.framework */, - 710D9EC519507E4D00FA70A1 /* XCTest.framework */, - 710D9EC819507E4D00FA70A1 /* UIKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -177,26 +165,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 710D9ECD19507E4D00FA70A1 /* OAuthiOSTests */ = { - isa = PBXGroup; - children = ( - 710D9ECE19507E4D00FA70A1 /* Supporting Files */, - 711D49A91953A0AC002E37BD /* OAuthIODataTests.m */, - 711E97F91954707500CEF381 /* OAuthIOTests.m */, - 711E97FB19547D9F00CEF381 /* OAuthIOModalTests.m */, - ); - path = OAuthiOSTests; - sourceTree = ""; - }; - 710D9ECE19507E4D00FA70A1 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 710D9ECF19507E4D00FA70A1 /* OAuthiOSTests-Info.plist */, - 710D9ED019507E4D00FA70A1 /* InfoPlist.strings */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; 710D9F9B19509B2800FA70A1 /* Src */ = { isa = PBXGroup; children = ( @@ -274,7 +242,7 @@ 710D9EAC19507E4D00FA70A1 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = OAuth.io; }; buildConfigurationList = 710D9EAF19507E4D00FA70A1 /* Build configuration list for PBXProject "OAuthiOS" */; @@ -301,7 +269,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 710D9ED219507E4D00FA70A1 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -342,7 +309,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n\n# If we're already inside this script then die\nif [ -n \"$RW_MULTIPLATFORM_BUILD_IN_PROGRESS\" ]; then\nexit 0\nfi\nexport RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1\n\nRW_FRAMEWORK_NAME=${PROJECT_NAME}\nRW_INPUT_STATIC_LIB=\"lib${PROJECT_NAME}.a\"\nRW_FRAMEWORK_LOCATION=\"${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework\"\n\nfunction build_static_library {\n # Will rebuild the static library as specified\n # build_static_library sdk\n xcrun xcodebuild -project \"${PROJECT_FILE_PATH}\" \\\n -target \"${TARGET_NAME}\" \\\n -configuration \"${CONFIGURATION}\" \\\n -sdk \"${1}\" \\\n ONLY_ACTIVE_ARCH=NO \\\n BUILD_DIR=\"${BUILD_DIR}\" \\\n OBJROOT=\"${OBJROOT}\" \\\n BUILD_ROOT=\"${BUILD_ROOT}\" \\\n SYMROOT=\"${SYMROOT}\" $ACTION\n}\n\nfunction make_fat_library {\n # Will smash 2 static libs together\n # make_fat_library in1 in2 out\n xcrun lipo -create \"${1}\" \"${2}\" -output \"${3}\"\n}\n\n# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name\nif [[ \"$SDK_NAME\" =~ ([A-Za-z]+) ]]; then\nRW_SDK_PLATFORM=${BASH_REMATCH[1]}\nelse\necho \"Could not find platform name from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 2 - Extract the version from the SDK\nif [[ \"$SDK_NAME\" =~ ([0-9]+.*$) ]]; then\nRW_SDK_VERSION=${BASH_REMATCH[1]}\nelse\necho \"Could not find sdk version from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 3 - Determine the other platform\nif [ \"$RW_SDK_PLATFORM\" == \"iphoneos\" ]; then\nRW_OTHER_PLATFORM=iphonesimulator\nelse\nRW_OTHER_PLATFORM=iphoneos\nfi\n\n# 4 - Find the build directory\nif [[ \"$BUILT_PRODUCTS_DIR\" =~ (.*)$RW_SDK_PLATFORM$ ]]; then\nRW_OTHER_BUILT_PRODUCTS_DIR=\"${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}\"\nelse\necho \"Could not find other platform build directory.\"\nexit 1\nfi\n\n# Build the other platform.\nbuild_static_library \"${RW_OTHER_PLATFORM}${RW_SDK_VERSION}\"\n\n# If we're currently building for iphonesimulator, then need to rebuild\n# to ensure that we get both i386 and x86_64\nif [ \"$RW_SDK_PLATFORM\" == \"iphonesimulator\" ]; then\nbuild_static_library \"${SDK_NAME}\"\nfi\n\n# Join the 2 static libs into 1 and push into the .framework\nmake_fat_library \"${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\"\n\n# Ensure that the framework is present in both platform's build directories\ncp -a \"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}\"\n\n# Copy the framework to the user's desktop\nditto \"${RW_FRAMEWORK_LOCATION}\" \"./Dist/${RW_FRAMEWORK_NAME}.framework\"\n#\"${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework\""; + shellScript = "set -e\n\n# If we're already inside this script then die\nif [ -n \"$RW_MULTIPLATFORM_BUILD_IN_PROGRESS\" ]; then\nexit 0\nfi\nexport RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1\n\nRW_FRAMEWORK_NAME=${PROJECT_NAME}\nRW_INPUT_STATIC_LIB=\"lib${PROJECT_NAME}.a\"\nRW_FRAMEWORK_LOCATION=\"${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework\"\n\nfunction build_static_library {\n # Will rebuild the static library as specified\n # build_static_library sdk\n xcrun xcodebuild -project \"${PROJECT_FILE_PATH}\" \\\n -target \"${TARGET_NAME}\" \\\n -configuration \"${CONFIGURATION}\" \\\n -sdk \"${1}\" \\\n ONLY_ACTIVE_ARCH=NO \\\n BUILD_DIR=\"${BUILD_DIR}\" \\\n OBJROOT=\"${OBJROOT}\" \\\n BUILD_ROOT=\"${BUILD_ROOT}\" \\\n SYMROOT=\"${SYMROOT}\" $ACTION\n}\n\nfunction make_fat_library {\n # Will smash 2 static libs together\n # make_fat_library in1 in2 out\n xcrun lipo -create \"${1}\" \"${2}\" -output \"${3}\"\n}\n\n# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name\nif [[ \"$SDK_NAME\" =~ ([A-Za-z]+) ]]; then\nRW_SDK_PLATFORM=${BASH_REMATCH[1]}\nelse\necho \"Could not find platform name from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 2 - Extract the version from the SDK\nif [[ \"$SDK_NAME\" =~ ([0-9]+.*$) ]]; then\nRW_SDK_VERSION=${BASH_REMATCH[1]}\nelse\necho \"Could not find sdk version from SDK_NAME: $SDK_NAME\"\nexit 1\nfi\n\n# 3 - Determine the other platform\nif [ \"$RW_SDK_PLATFORM\" == \"iphoneos\" ]; then\nRW_OTHER_PLATFORM=iphonesimulator\nelse\nRW_OTHER_PLATFORM=iphoneos\nfi\n\n# 4 - Find the build directory\nif [[ \"$BUILT_PRODUCTS_DIR\" =~ (.*)$RW_SDK_PLATFORM$ ]]; then\nRW_OTHER_BUILT_PRODUCTS_DIR=\"${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}\"\nelse\necho \"Could not find other platform build directory.\"\nexit 1\nfi\n\n# Build the other platform.\nbuild_static_library \"${RW_OTHER_PLATFORM}${RW_SDK_VERSION}\"\n\n# If we're currently building for iphonesimulator, then need to rebuild\n# to ensure that we get both i386 and x86_64\nif [ \"$RW_SDK_PLATFORM\" == \"iphonesimulator\" ]; then\nbuild_static_library \"${SDK_NAME}\"\nfi\n\n# Join the 2 static libs into 1 and push into the .framework\nmake_fat_library \"${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}\" \\\n\"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\"\n\n# Ensure that the framework is present in both platform's build directories\ncp -a \"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}\" \\\n\"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}\"\n\n# Copy the framework to the user's desktop\nditto \"${RW_FRAMEWORK_LOCATION}\" \"./Dist/${RW_FRAMEWORK_NAME}.framework\"\n#\"${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -363,11 +330,8 @@ buildActionMask = 2147483647; files = ( 710D9FA919509B2800FA70A1 /* OAuthIORequest.m in Sources */, - 711D49AA1953A0AC002E37BD /* OAuthIODataTests.m in Sources */, 710D9FA619509B2800FA70A1 /* OAuthIOData.m in Sources */, 710D9FA519509B2800FA70A1 /* OAuthIO.m in Sources */, - 711E97FA1954707500CEF381 /* OAuthIOTests.m in Sources */, - 711E97FC19547D9F00CEF381 /* OAuthIOModalTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,17 +350,6 @@ }; /* End PBXTargetDependency section */ -/* Begin PBXVariantGroup section */ - 710D9ED019507E4D00FA70A1 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 710D9ED119507E4D00FA70A1 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 710D9ED519507E4D00FA70A1 /* Debug */ = { isa = XCBuildConfiguration; @@ -406,17 +359,29 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = 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_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -429,7 +394,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -443,24 +408,35 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = 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_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; 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_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -530,6 +506,7 @@ "-force_load", "$(PROJECT_DIR)/usr/lib/libOCMock.a", ); + PRODUCT_BUNDLE_IDENTIFIER = "com.oauthio.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xctest; }; @@ -563,6 +540,7 @@ "-force_load", "$(PROJECT_DIR)/usr/lib/libOCMock.a", ); + PRODUCT_BUNDLE_IDENTIFIER = "com.oauthio.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xctest; }; diff --git a/OAuthiOS.xcodeproj/xcuserdata/antoine.xcuserdatad/xcschemes/xcschememanagement.plist b/OAuthiOS.xcodeproj/xcuserdata/antoine.xcuserdatad/xcschemes/xcschememanagement.plist index 7e00c5b..5efb438 100644 --- a/OAuthiOS.xcodeproj/xcuserdata/antoine.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/OAuthiOS.xcodeproj/xcuserdata/antoine.xcuserdatad/xcschemes/xcschememanagement.plist @@ -12,7 +12,7 @@ OAuthiOS.xcscheme orderHint - 0 + 1 SuppressBuildableAutocreation diff --git a/OAuthiOS/Src/OAuthIOData.h b/OAuthiOS/Src/OAuthIOData.h index 4af82c7..f243121 100644 --- a/OAuthiOS/Src/OAuthIOData.h +++ b/OAuthiOS/Src/OAuthIOData.h @@ -29,6 +29,7 @@ @property (nonatomic, strong) NSDictionary *request_conf; @property (nonatomic, strong) NSString *oauth_token; +@property (nonatomic, strong) NSString *code; @property (nonatomic, strong) NSString *oauth_token_secret; @property (nonatomic, strong) NSString *access_token; @property (nonatomic, strong) NSString *request_url; diff --git a/OAuthiOS/Src/OAuthIOData.m b/OAuthiOS/Src/OAuthIOData.m index 88d7057..e73dcf4 100644 --- a/OAuthiOS/Src/OAuthIOData.m +++ b/OAuthiOS/Src/OAuthIOData.m @@ -40,7 +40,10 @@ - (id)initWithDictionary:(NSDictionary *)dict [_request setValue:_oauth_token forKey:@"oauth_token"]; [_request setValue:_oauth_token_secret forKey:@"oauth_token_secret"]; - } else { + } else if ([[dict objectForKey:@"data"] objectForKey:@"code"] != nil) { + _code = [[dict objectForKey:@"data"] objectForKey:@"code"]; + _request = nil; + }else { [NSException raise:@"Wrong credentials" format:@"A problem occured with the credentials data initialization"]; } diff --git a/OAuthiOS/Src/OAuthIOModal.h b/OAuthiOS/Src/OAuthIOModal.h index cec0bd7..dd2215e 100644 --- a/OAuthiOS/Src/OAuthIOModal.h +++ b/OAuthiOS/Src/OAuthIOModal.h @@ -25,6 +25,9 @@ @protocol OAuthIODelegate - (void)didReceiveOAuthIOResponse:(OAuthIORequest *)request; - (void)didFailWithOAuthIOError:(NSError *)error; +- (void)didReceiveOAuthIOCode:(NSString *)code; +- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response; +- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error; @end @interface OAuthIOModal : UIViewController @@ -43,15 +46,19 @@ UIWebView *_browser; UINavigationBar *_navigationBar; NSUInteger _navigationBarHeight; + } - +@property NSMutableArray *saved_cookies; @property (weak) id delegate; +@property NSURLSession *session; +@property NSString *authUrl; - (id)initWithKey:(NSString *)key delegate:(id)delegate; - (id)initWithKey:(NSString *)key delegate:(id)delegate andOptions:(NSDictionary *) options; - (void)showWithProvider:(NSString *)provider; - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options; +- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl; - (BOOL) clearCache; - (BOOL) clearCacheForProvider:(NSString *)provider; - (BOOL) cacheAvailableForProvider:(NSString *)provider; diff --git a/OAuthiOS/Src/OAuthIOModal.m b/OAuthiOS/Src/OAuthIOModal.m index a765d73..0e8ae33 100644 --- a/OAuthiOS/Src/OAuthIOModal.m +++ b/OAuthiOS/Src/OAuthIOModal.m @@ -18,7 +18,6 @@ #import "OAuthIOModal.h" @implementation OAuthIOModal - NSString *_host; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil @@ -39,11 +38,12 @@ - (void)viewDidLoad [_browser setFrame:CGRectMake(0, _navigationBarHeight, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height - _navigationBarHeight - 1)]; _browser.autoresizesSubviews = YES; - _browser.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth); + _browser.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth); + _browser.scalesPageToFit = true; + _browser.contentMode = UIViewContentModeScaleAspectFit; [_browser setDelegate:self]; [[self view] addSubview:_browser]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getTokens:) name:@"OAuthIOGetTokens" object:nil]; } @@ -146,10 +146,63 @@ - (void)getTokens:(NSString *)url [data_to_file writeToFile:file_url atomically:YES]; } + if (_saved_cookies != nil) { + NSHTTPCookie *cookie; + NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + for (cookie in _saved_cookies) { + [storage setCookie:cookie]; + } + [[NSUserDefaults standardUserDefaults] synchronize]; + } + + @try { OAuthIORequest *request = [self buildRequestObject:json]; - if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)]) - [self.delegate didReceiveOAuthIOResponse:request]; + if ([[request getCredentials] objectForKey:@"code"] != nil && _authUrl != nil) { + //Signing in to the selected URL, giving back the response + + NSString *code = [[request getCredentials] objectForKey:@"code"]; + NSString *post = [NSString stringWithFormat:@"code=%@", code]; + NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; + NSString *postLength = [NSString stringWithFormat:@"%tu", [postData length]]; + NSMutableURLRequest *state_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_authUrl] + cachePolicy:NSURLRequestUseProtocolCachePolicy + timeoutInterval:60.0]; + [state_request setHTTPMethod:@"POST"]; + [state_request setValue:postLength forHTTPHeaderField:@"Content-Length"]; + [state_request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; + [state_request setHTTPBody:postData]; + + [[_session dataTaskWithRequest:state_request + completionHandler:^(NSData *data, + NSURLResponse *response, + NSError *error) { + NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; + NSString *body = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; + if ([httpResponse statusCode] == 200) { + if ([self.delegate respondsToSelector:@selector(didAuthenticateServerSide:andResponse:)]) + [self.delegate didAuthenticateServerSide:body andResponse:response]; + } else { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil), + NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The authentication endpoint did not return 200 OK.", nil), + NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Are you using the right authentication endpoint?", nil) + }; + NSError *error = [NSError errorWithDomain:@"com.oauthio.error" + code:-1 + userInfo:userInfo]; + if ([self.delegate respondsToSelector:@selector(didFailAuthenticationServerSide:andResponse:andError:)]) + [self.delegate didFailAuthenticationServerSide:body andResponse:response andError:error]; + } + }] resume]; + + } else if ([[request getCredentials] objectForKey:@"code"] != nil) { + if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOCode:)]) + [self.delegate didReceiveOAuthIOCode:[[request getCredentials] objectForKey:@"code"]]; + }else { + if ([self.delegate respondsToSelector:@selector(didReceiveOAuthIOResponse:)]) + [self.delegate didReceiveOAuthIOResponse:request]; + } } @catch (NSException *e) { NSMutableDictionary *errorDetail = [NSMutableDictionary dictionary]; @@ -198,6 +251,8 @@ - (void)initNavigationBar { _navigationBar = [[UINavigationBar alloc] init]; [_navigationBar setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth]; + _navigationBar.translucent = NO; + _navigationBar.barTintColor = [UIColor lightGrayColor]; UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:@""]; UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:nil action:@selector(cancelOperation)]; @@ -214,7 +269,12 @@ - (void)initNavigationBar - (void)drawNavigationBar { CGFloat width = CGRectGetWidth(self.view.bounds); - [_navigationBar setFrame:CGRectMake(0, 0, width, _navigationBarHeight)]; + UIView *statusbar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 20)]; + [statusbar setAutoresizingMask: UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | + UIViewAutoresizingFlexibleWidth]; + statusbar.backgroundColor = [UIColor lightGrayColor]; + [self.view addSubview:statusbar]; + [_navigationBar setFrame:CGRectMake(0, 20, width, _navigationBarHeight)]; [self.view addSubview:_navigationBar]; } @@ -232,7 +292,7 @@ - (void)cancelOperation if ([self.delegate respondsToSelector:@selector(didFailWithOAuthIOError:)]) [self.delegate didFailWithOAuthIOError:error]; - [_browser loadHTMLString:nil baseURL:nil]; + [_browser loadHTMLString:@"" baseURL:[NSURL URLWithString:@""]]; [self dismissViewControllerAnimated:YES completion:nil]; } @@ -251,6 +311,38 @@ - (void)showWithProvider:(NSString *)provider { [self showWithProvider:provider options:nil]; } +- (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options stateTokenUrl:(NSString*) stateUrl authUrl:(NSString*) authUrl; +{ + _session = [NSURLSession sharedSession]; + _authUrl = authUrl; + [[_session dataTaskWithURL:[NSURL URLWithString:stateUrl] + completionHandler:^(NSData *data, + NSURLResponse *response, + NSError *error) { + NSString *body = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; + NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; + if (dictionary != nil && [dictionary objectForKey:@"token"] != nil) { + + NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; + NSMutableDictionary *options_mut = [options mutableCopy]; + [options_mut setObject:[dictionary objectForKey:@"token"] forKey:@"state"]; + [self showWithProvider:provider options:options_mut]; + } else { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Operation was unsuccessful.", nil), + NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The state token could not be retrieved.", nil), + NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Are you using the right state token retrieval endpoint?", nil) + }; + NSError *error = [NSError errorWithDomain:@"com.oauthio.error" + code:-1 + userInfo:userInfo]; + if ([self.delegate respondsToSelector:@selector(didFailAuthenticationServerSide:andResponse:andError:)]) + [self.delegate didFailAuthenticationServerSide:body andResponse:response andError:error]; + } + + }] resume]; +} + - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options { _options = options; @@ -267,8 +359,17 @@ - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options NSDictionary *json_d = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options: NSJSONReadingMutableContainers error:nil]; NSNumber *expires = [[json_d objectForKey:@"data"] objectForKey:@"expires"]; NSTimeInterval interval = [expires doubleValue]; - NSDate *expiring_date = [[NSDate alloc] initWithTimeIntervalSince1970:interval]; NSDate *now = [[NSDate alloc] init]; + NSDate *expiring_date; + + if (expires != nil) { + expiring_date = [[NSDate alloc] initWithTimeIntervalSince1970:interval]; + } else { + // If no expiry date is available, defaults to one hour + interval = 3600; + expiring_date = [[NSDate alloc] initWithTimeIntervalSinceNow:interval]; + } + if ([now compare:expiring_date] == NSOrderedAscending) { @try { @@ -293,11 +394,12 @@ - (void)showWithProvider:(NSString *)provider options:(NSDictionary*)options NSURLRequest *url = [_oauth getOAuthRequest:provider andUrl:_callback_url andOptions:options]; if ([[_options objectForKey:@"clear-popup-cache"] isEqual: @"true"]) { -// [[NSURLCache sharedURLCache] removeAllCachedResponses]; NSHTTPCookie *cookie; NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + _saved_cookies = [[NSMutableArray alloc] init]; for (cookie in [storage cookies]) { [storage deleteCookie:cookie]; + [_saved_cookies addObject:cookie]; } [[NSUserDefaults standardUserDefaults] synchronize]; } diff --git a/README.md b/README.md index c3e5310..ed01267 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Getting the SDK To install this SDK in your iOS app, you can either: - Get the framework from Cocoapods -- Install the framework by hand in XCode +- Install the framework by hand in Xcode Both options are pretty simple. @@ -36,7 +36,7 @@ This will get the framework for you and install it as a project dependency. Once **Installing the framework manually** -The framework is available in this repository as the `Dist/OAuthiOS.framework` file. To add it as a dependency in your projet in XCode, follow this procedure: +The framework is available in this repository as the `Dist/OAuthiOS.framework` file. To add it as a dependency in your projet in Xcode, follow this procedure: - click on the project name in the Documents explorer - go to **Build phases** - open the **Link Binary with Libraries** section @@ -218,6 +218,78 @@ You can filter the fields returned by this method by passing a `NSArray` contain }]; ``` +Notes on the server-side flow +============================= + +If you're planning to use OAuth.io from your back-end thanks to one of our server-side SDKs, the usage of this SDK is a bit different. + +First, a little reminder of the server-side flow, in which all API calls are performed server-side, as well as authentication (thanks to a code retrieved in the front-end). The server-side flow involves the following steps: + +- Retrieving of a state token from your back-end in your front-end +- Launching the authentication popup in the front-end, with the state token, gives back a code +- Sending the code back to the back-end +- Authenticating in the back-end thanks to the code +- Performing API calls in the back-end + +Thus, in your back-end, you need two endpoints: + +- one for the state token (GET) +- one for the authentication (POST with the code as parameter) + +In the iOS SDK, the calls to these endpoints are performed automatically. All you need to do is give their URLs to the `showWithProvider` method like this: + +```Objective-C +[_oauthioModal showWithProvider:@"facebook" options:options stateTokenUrl:@"http://example/state/url" authUrl:@"http://example/auth/url"]; +``` + +This will first call the state URL, then show the authentication popup to the user, get the code, and finally send the code to the authentication URL. + +To know when the process is done, you need to add the following methods to your OAuthIODelegate class: + +```Objective-C +- (void)didAuthenticateServerSide:(NSString *)body andResponse:(NSURLResponse *) response; +- (void)didFailAuthenticationServerSide:(NSString *)body andResponse:(NSURLResponse *)response andError:(NSError *)error; +``` + +The first one will catches a successfull authentication (which usually means the authentication URL returned "200 OK") and give you the body and response objects it got from that URL. The second one will catch errors (state token not found, unsucessfull authentication). + +Building +======== + +There is excellent instruction on building/updating your cocoapod [https://sebastiandobrincu.com/blog/how-to-update-your-cocoapods-library-version](here) + +In brief: + +1. Update the 'version' in OAuth.io.podspec file +2. Tag the master branch with: +* `git tag {{VERSION}} -m 'Version Message' +* `git push origin --tags +3. Check if your Pod passess verification: +* `pod spec lint OAuth.io.podspec` +4. Register a Trunk session +* `pod trunk register name@company 'Firstname Lastname' --description='OAuth.io'` +5. Push new Pod version using trunk: +* `pod trunk push OAuth.io.podspec` + +Errors +====== + +When building, if you get: + +``` + pod spec lint OAuth.io.podspec + + -> OAuth.io (1.2.3) + - ERROR | [iOS] unknown: Encountered an unknown error (/usr/bin/xcrun simctl list -j devices + +xcrun: error: unable to find utility "simctl", not a developer tool or in PATH +) during validation. + +Analyzed 1 podspec. +``` + * Download the latest XCode (not just the CLI) + * Open XCode and goto 'XCode' -> 'Preferences' -> 'Location' + Contributing ============