diff --git a/Configurations/FacebookSDK-Project.xcconfig b/Configurations/FacebookSDK-Project.xcconfig index 111fadc2d..19e020d29 100644 --- a/Configurations/FacebookSDK-Project.xcconfig +++ b/Configurations/FacebookSDK-Project.xcconfig @@ -59,7 +59,7 @@ CLANG_CXX_LIBRARY = libc++ ENABLE_BITCODE = NO FB_BITCODE_FLAG = $() // Only specify bitcode for iphoneos. Specifying iphonesimulator breaks Xcode6 -FB_BITCODE_FLAG[sdk=iphoneos9.0] = -fembed-bitcode +FB_BITCODE_FLAG[sdk=iphoneos9.*] = -fembed-bitcode OTHER_CFLAGS = $(inherited) $(FB_BITCODE_FLAG) // Warnings diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index a3ee9f8a0..2d9103c22 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = "FBSDKCoreKit" - s.version = "4.7.1" + s.version = "4.8.0" s.summary = "Official Facebook SDK for iOS to access Facebook Platform's core features" s.description = <<-DESC @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = "7.0" s.source = { :git => "https://github.com/facebook/facebook-ios-sdk.git", - :tag => "sdk-version-4.7.1" + :tag => "sdk-version-4.8.0" } s.weak_frameworks = "Accounts", "CoreLocation", "Social", "Security", "QuartzCore", "CoreGraphics", "UIKit", "Foundation", "AudioToolbox" diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 2157f1789..889d31450 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -58,8 +58,8 @@ 894C0ADF1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0ADD1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h */; }; 894C0AE01A6F1D1B009137EF /* FBSDKBridgeAPIResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0ADE1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.m */; }; 894C0AED1A6F1DAB009137EF /* FBSDKBridgeAPIProtocolType.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0AEC1A6F1DAB009137EF /* FBSDKBridgeAPIProtocolType.h */; }; - 894C0AF31A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0AF21A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 894C0AF61A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0AF41A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 894C0AF31A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0AF21A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h */; }; + 894C0AF61A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0AF41A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h */; }; 894C0AF71A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0AF51A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.m */; }; 894C0B091A702194009137EF /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; 894C0B0A1A702194009137EF /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B081A702194009137EF /* FBSDKCrypto.m */; }; @@ -67,11 +67,11 @@ 894C0B121A7021F8009137EF /* FBSDKBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B101A7021F8009137EF /* FBSDKBase64.m */; }; 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B391A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m */; }; 894C0B4A1A70524F009137EF /* FBSDKBase64Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B491A70524F009137EF /* FBSDKBase64Tests.m */; }; - 894C0B611A7150AC009137EF /* FBSDKError.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B5F1A7150AC009137EF /* FBSDKError.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 894C0B611A7150AC009137EF /* FBSDKError.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B5F1A7150AC009137EF /* FBSDKError.h */; }; 894C0B621A7150AC009137EF /* FBSDKError.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B601A7150AC009137EF /* FBSDKError.m */; }; 894C0B681A7150CC009137EF /* FBSDKConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B661A7150CC009137EF /* FBSDKConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 894C0B691A7150CC009137EF /* FBSDKConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B671A7150CC009137EF /* FBSDKConstants.m */; }; - 894C0B6C1A716A6D009137EF /* FBSDKBridgeAPICrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B6A1A716A6D009137EF /* FBSDKBridgeAPICrypto.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 894C0B6C1A716A6D009137EF /* FBSDKBridgeAPICrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B6A1A716A6D009137EF /* FBSDKBridgeAPICrypto.h */; }; 894C0B6D1A716A6D009137EF /* FBSDKBridgeAPICrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B6B1A716A6D009137EF /* FBSDKBridgeAPICrypto.m */; }; 894C0B701A717D60009137EF /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B6E1A717D60009137EF /* FBSDKTypeUtility.h */; }; 894C0B711A717D60009137EF /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B6F1A717D60009137EF /* FBSDKTypeUtility.m */; }; @@ -98,7 +98,7 @@ 89D05AA91AA1134000609300 /* FBSDKAudioResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D05AA71AA1134000609300 /* FBSDKAudioResourceLoader.h */; }; 89D05AAA1AA1134000609300 /* FBSDKAudioResourceLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D05AA81AA1134000609300 /* FBSDKAudioResourceLoader.m */; }; 89D4AE861A7FFEFC00DB8C72 /* FBSDKBridgeAPIRequest+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D4AE851A7FFEFC00DB8C72 /* FBSDKBridgeAPIRequest+Private.h */; }; - 89D4AE9F1A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D4AE9D1A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 89D4AE9F1A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D4AE9D1A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.h */; }; 89D4AEA01A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D4AE9E1A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.m */; }; 89D652841A855A6000BB651C /* FBSDKCloseIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D652821A855A6000BB651C /* FBSDKCloseIcon.h */; }; 89D652851A855A6000BB651C /* FBSDKCloseIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D652831A855A6000BB651C /* FBSDKCloseIcon.m */; }; @@ -106,7 +106,7 @@ 89F2038C1AA960FA0053499E /* FBSDKBridgeAPIProtocolWebV2.m in Sources */ = {isa = PBXBuildFile; fileRef = 89F2038A1AA960FA0053499E /* FBSDKBridgeAPIProtocolWebV2.m */; }; 89FB8C411A8425C4003CAE60 /* FBSDKWebDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 89FB8C3F1A8425C4003CAE60 /* FBSDKWebDialog.h */; }; 89FB8C421A8425C4003CAE60 /* FBSDKWebDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FB8C401A8425C4003CAE60 /* FBSDKWebDialog.m */; }; - 89FB8C4A1A842A8A003CAE60 /* FBSDKWebDialogView.h in Headers */ = {isa = PBXBuildFile; fileRef = 89FB8C481A842A8A003CAE60 /* FBSDKWebDialogView.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 89FB8C4A1A842A8A003CAE60 /* FBSDKWebDialogView.h in Headers */ = {isa = PBXBuildFile; fileRef = 89FB8C481A842A8A003CAE60 /* FBSDKWebDialogView.h */; }; 89FB8C4B1A842A8A003CAE60 /* FBSDKWebDialogView.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FB8C491A842A8A003CAE60 /* FBSDKWebDialogView.m */; }; 9894BFFB1B73D8B300FBA6DB /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9894BFFA1B73D8B300FBA6DB /* SafariServices.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 9D0043321AA91B9A008DEB62 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D0043301AA91B96008DEB62 /* Bolts.framework */; }; @@ -125,8 +125,8 @@ 9D0BC1671A8E892C00BE8BA4 /* FBSDKAppEventsState.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0BC1651A8E892C00BE8BA4 /* FBSDKAppEventsState.m */; }; 9D18A8DB1A95405A00A41042 /* FBSDKAppEventsStateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D18A8DA1A95405A00A41042 /* FBSDKAppEventsStateTests.m */; }; 9D18A8E91A95495D00A41042 /* FBSDKAppEventsUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D18A8E81A95495D00A41042 /* FBSDKAppEventsUtilityTests.m */; }; - 9D195CC81B9FE2E000BD6BEC /* FBSDKContainerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D195CC61B9FE2E000BD6BEC /* FBSDKContainerViewController.h */; settings = {ASSET_TAGS = (); }; }; - 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D195CC71B9FE2E000BD6BEC /* FBSDKContainerViewController.m */; settings = {ASSET_TAGS = (); }; }; + 9D195CC81B9FE2E000BD6BEC /* FBSDKContainerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D195CC61B9FE2E000BD6BEC /* FBSDKContainerViewController.h */; }; + 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D195CC71B9FE2E000BD6BEC /* FBSDKContainerViewController.m */; }; 9D26974D1A5DF40700143BFC /* FBSDKCoreKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D26974C1A5DF40700143BFC /* FBSDKCoreKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D2697531A5DF40700143BFC /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D2697471A5DF40700143BFC /* FBSDKCoreKit.framework */; }; 9D30290A1A65C4420086B9ED /* FBSDKAccessToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D3029081A65C4420086B9ED /* FBSDKAccessToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -134,7 +134,7 @@ 9D3029251A65E6150086B9ED /* FBSDKDynamicFrameworkLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D3029231A65E6150086B9ED /* FBSDKDynamicFrameworkLoader.h */; }; 9D3029261A65E6150086B9ED /* FBSDKDynamicFrameworkLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D3029241A65E6150086B9ED /* FBSDKDynamicFrameworkLoader.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 9D30292B1A65E6680086B9ED /* FBSDKMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D30292A1A65E6680086B9ED /* FBSDKMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D32A83E1A69941A000A936D /* FBSDKAccessTokenCacheV4.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8391A69941A000A936D /* FBSDKAccessTokenCacheV4.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9D32A83E1A69941A000A936D /* FBSDKAccessTokenCacheV4.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8391A69941A000A936D /* FBSDKAccessTokenCacheV4.h */; }; 9D32A83F1A69941A000A936D /* FBSDKAccessTokenCacheV4.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A83A1A69941A000A936D /* FBSDKAccessTokenCacheV4.m */; }; 9D32A8401A69941A000A936D /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; 9D32A8411A69941A000A936D /* FBSDKKeychainStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83C1A69941A000A936D /* FBSDKKeychainStore.h */; }; @@ -169,9 +169,9 @@ 9DC6589B1A6EE5CD00B85AAF /* FBSDKGraphRequest+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DC6589A1A6EE5CD00B85AAF /* FBSDKGraphRequest+Internal.h */; }; 9DC6589E1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DC6589C1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DC6589F1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DC6589D1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.m */; }; - 9DC658A51A6EE7E200B85AAF /* FBSDKGraphRequestBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DC658A01A6EE7E200B85AAF /* FBSDKGraphRequestBody.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9DC658A51A6EE7E200B85AAF /* FBSDKGraphRequestBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DC658A01A6EE7E200B85AAF /* FBSDKGraphRequestBody.h */; }; 9DC658A61A6EE7E200B85AAF /* FBSDKGraphRequestBody.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DC658A11A6EE7E200B85AAF /* FBSDKGraphRequestBody.m */; }; - 9DC658A81A6EE7E200B85AAF /* FBSDKURLConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DC658A31A6EE7E200B85AAF /* FBSDKURLConnection.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9DC658A81A6EE7E200B85AAF /* FBSDKURLConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DC658A31A6EE7E200B85AAF /* FBSDKURLConnection.h */; }; 9DC658A91A6EE7E200B85AAF /* FBSDKURLConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DC658A41A6EE7E200B85AAF /* FBSDKURLConnection.m */; }; 9DD50A3C1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DD50A3A1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DD50A3D1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD50A3B1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.m */; }; @@ -191,7 +191,7 @@ 9DF18BB91A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DF18BB71A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.h */; }; 9DF18BBA1A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DF18BB81A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.m */; }; 9DF18BCB1A9F2517000F6748 /* FBSDKErrorConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DF18BCA1A9F2517000F6748 /* FBSDKErrorConfigurationTests.m */; }; - 9DF2A3FF1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DF2A3FD1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 9DF2A3FF1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DF2A3FD1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.h */; }; 9DF2A4001A70572B00DFB2FD /* FBSDKGraphRequestMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DF2A3FE1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.m */; }; ADEA17731B7ECA1A0070EDC0 /* FBSDKMonotonicTime.h in Headers */ = {isa = PBXBuildFile; fileRef = ADEA17711B7ECA1A0070EDC0 /* FBSDKMonotonicTime.h */; }; ADEA17741B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m in Sources */ = {isa = PBXBuildFile; fileRef = ADEA17721B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m */; }; @@ -324,6 +324,27 @@ remoteGlobalIDString = 095981C219806A7900807DBE; remoteInfo = "OHHTTPStubs Mac Framework"; }; + DB3A5F011BED707B003919E4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7E5557191A8D3D7400344F86 /* Bolts.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = F5AFCA021BA752750076E927; + remoteInfo = "Bolts-tvOS"; + }; + DB3A5F031BED707B003919E4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7E5557191A8D3D7400344F86 /* Bolts.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8178F99C1BB0F87700AD289D; + remoteInfo = "Bolts-watchOS"; + }; + DB3A5F051BED707B003919E4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7E5557191A8D3D7400344F86 /* Bolts.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = F5AFCA131BA752770076E927; + remoteInfo = "BoltsTests-tvOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -551,8 +572,11 @@ children = ( 9D9947171A9531B5003375EC /* Bolts.framework */, 9D0043261AA91B18008DEB62 /* Bolts.framework */, - 9D9947191A9531B5003375EC /* BoltsTests.xctest */, - 9D99471B1A9531B5003375EC /* MacBoltsTests.xctest */, + DB3A5F021BED707B003919E4 /* Bolts.framework */, + DB3A5F041BED707B003919E4 /* Bolts.framework */, + 9D9947191A9531B5003375EC /* BoltsTests-iOS.xctest */, + 9D99471B1A9531B5003375EC /* BoltsTests-OSX.xctest */, + DB3A5F061BED707B003919E4 /* BoltsTests-tvOS.xctest */, 9D99471D1A9531B5003375EC /* BoltsTestUI.app */, ); name = Products; @@ -581,8 +605,8 @@ 7EB63D901A9BE720003A7AED /* AppLink */ = { isa = PBXGroup; children = ( - 7EB63D9D1A9BE730003A7AED /* FBSDKBoltsMeasurementEventListener.m */, 7EB63D9E1A9BE730003A7AED /* FBSDKBoltsMeasurementEventListener.h */, + 7EB63D9D1A9BE730003A7AED /* FBSDKBoltsMeasurementEventListener.m */, ); name = AppLink; sourceTree = ""; @@ -805,18 +829,18 @@ isa = PBXGroup; children = ( 9D0BC1531A8D23DB00BE8BA4 /* FBSDKAppEvents+Internal.h */, - 9D0BC15D1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.h */, - 9D0BC15E1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.m */, + 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */, + 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */, 9D0BC1641A8E892C00BE8BA4 /* FBSDKAppEventsState.h */, 9D0BC1651A8E892C00BE8BA4 /* FBSDKAppEventsState.m */, + 9D0BC15D1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.h */, + 9D0BC15E1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.m */, 9D0BC1591A8D427800BE8BA4 /* FBSDKAppEventsUtility.h */, 9D0BC15A1A8D427800BE8BA4 /* FBSDKAppEventsUtility.m */, 9D0BC14A1A8D236200BE8BA4 /* FBSDKPaymentObserver.h */, 9D0BC14B1A8D236200BE8BA4 /* FBSDKPaymentObserver.m */, 9D0BC14C1A8D236200BE8BA4 /* FBSDKTimeSpentData.h */, 9D0BC14D1A8D236200BE8BA4 /* FBSDKTimeSpentData.m */, - 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */, - 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */, ); path = AppEvents; sourceTree = ""; @@ -976,10 +1000,10 @@ 9D3AF4861A9EF9E200EEF724 /* ErrorRecovery */ = { isa = PBXGroup; children = ( - 9D3AF4871A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.h */, - 9D3AF4881A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.m */, 9DF18BB71A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.h */, 9DF18BB81A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.m */, + 9D3AF4871A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.h */, + 9D3AF4881A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.m */, ); path = ErrorRecovery; sourceTree = ""; @@ -1213,17 +1237,17 @@ remoteRef = 9D9947161A9531B5003375EC /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 9D9947191A9531B5003375EC /* BoltsTests.xctest */ = { + 9D9947191A9531B5003375EC /* BoltsTests-iOS.xctest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = BoltsTests.xctest; + path = "BoltsTests-iOS.xctest"; remoteRef = 9D9947181A9531B5003375EC /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 9D99471B1A9531B5003375EC /* MacBoltsTests.xctest */ = { + 9D99471B1A9531B5003375EC /* BoltsTests-OSX.xctest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = MacBoltsTests.xctest; + path = "BoltsTests-OSX.xctest"; remoteRef = 9D99471A1A9531B5003375EC /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1283,6 +1307,27 @@ remoteRef = ADEA17811B7ECA1A0070EDC0 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + DB3A5F021BED707B003919E4 /* Bolts.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Bolts.framework; + remoteRef = DB3A5F011BED707B003919E4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + DB3A5F041BED707B003919E4 /* Bolts.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Bolts.framework; + remoteRef = DB3A5F031BED707B003919E4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + DB3A5F061BED707B003919E4 /* BoltsTests-tvOS.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "BoltsTests-tvOS.xctest"; + remoteRef = DB3A5F051BED707B003919E4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/xcshareddata/xcschemes/FBSDKCoreKit-Universal.xcscheme b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/xcshareddata/xcschemes/FBSDKCoreKit-Universal.xcscheme index 2dfd963d3..f515f3a1e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/xcshareddata/xcschemes/FBSDKCoreKit-Universal.xcscheme +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/xcshareddata/xcschemes/FBSDKCoreKit-Universal.xcscheme @@ -58,7 +58,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "8E9C3CE817DE9DE000427E62" BuildableName = "Bolts.framework" - BlueprintName = "Bolts" + BlueprintName = "Bolts-iOS" ReferencedContainer = "container:../Bolts-IOS/Bolts.xcodeproj"> diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 5b4f8418b..1d15674d4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -34,5 +34,5 @@ #import #import -#define FBSDK_VERSION_STRING @"4.7.1" +#define FBSDK_VERSION_STRING @"4.8.0" #define FBSDK_TARGET_PLATFORM_VERSION @"v2.5" diff --git a/FBSDKIntegrationTests/FBSDKIntegrationTests.xcodeproj/project.pbxproj b/FBSDKIntegrationTests/FBSDKIntegrationTests.xcodeproj/project.pbxproj index dc799139a..8c211f4cc 100644 --- a/FBSDKIntegrationTests/FBSDKIntegrationTests.xcodeproj/project.pbxproj +++ b/FBSDKIntegrationTests/FBSDKIntegrationTests.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 93266D961BBA121200874D8B /* videoviewdemo.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 93266D941BBA11CB00874D8B /* videoviewdemo.mp4 */; settings = {ASSET_TAGS = (); }; }; + 9332A7591BF1DD6B004C53FD /* thumbs_up.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 9332A7571BF1DCCD004C53FD /* thumbs_up.jpg */; settings = {ASSET_TAGS = (); }; }; + 9332A75A1BF1DD6F004C53FD /* hack.png in Resources */ = {isa = PBXBuildFile; fileRef = 9332A7551BF1DCBD004C53FD /* hack.png */; settings = {ASSET_TAGS = (); }; }; 9D18A8F91A9596B600A41042 /* FBSDKAppEventsIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D18A8F81A9596B600A41042 /* FBSDKAppEventsIntegrationTests.m */; }; 9D18A8FB1A95981F00A41042 /* libOHHTTPStubs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D18A8FA1A95981F00A41042 /* libOHHTTPStubs.a */; }; 9D1999C71A7AF5C900CAD112 /* FBSDKIntegrationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D1999C61A7AF5C900CAD112 /* FBSDKIntegrationTestCase.m */; }; @@ -49,6 +52,9 @@ /* Begin PBXFileReference section */ 8918E3E61AFA66CD003F7B88 /* FacebookSDK-ApplicationTests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FacebookSDK-ApplicationTests.xcconfig"; sourceTree = ""; }; + 93266D941BBA11CB00874D8B /* videoviewdemo.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = videoviewdemo.mp4; sourceTree = ""; }; + 9332A7551BF1DCBD004C53FD /* hack.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hack.png; sourceTree = ""; }; + 9332A7571BF1DCCD004C53FD /* thumbs_up.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = thumbs_up.jpg; sourceTree = ""; }; 9D18A8F81A9596B600A41042 /* FBSDKAppEventsIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsIntegrationTests.m; sourceTree = ""; }; 9D18A8FA1A95981F00A41042 /* libOHHTTPStubs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libOHHTTPStubs.a; sourceTree = BUILT_PRODUCTS_DIR; }; 9D1999B31A7AF44B00CAD112 /* FBSDKIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FBSDKIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -93,7 +99,8 @@ 9D5F8ADB1A97C15400EC4FD3 /* FBSDKAppEventsStateManagerIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsStateManagerIntegrationTests.m; sourceTree = ""; }; 9D9ACC3A1ABCAF950050BF2E /* FBSDKShareAPIIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKShareAPIIntegrationTests.m; sourceTree = ""; }; 9DA81B061AA5092800B9FE0B /* FBSDKProfileIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKProfileIntegrationTests.m; sourceTree = ""; }; - 9DAD79F81B7B244B00DFEF8F /* libOHHTTPStubs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libOHHTTPStubs.a; path = libOHHTTPStubs.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 9DAD79F81B7B244B00DFEF8F /* libOHHTTPStubs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libOHHTTPStubs.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB3A5EF91BED6E4D003919E4 /* FBSDKShareKit+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "FBSDKShareKit+Internal.h"; path = "../../FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -159,6 +166,7 @@ 9DA81B061AA5092800B9FE0B /* FBSDKProfileIntegrationTests.m */, 9D1999DD1A7AF76200CAD112 /* FBSDKServerConfigurationManagerIntegrationTests.m */, 9D9ACC3A1ABCAF950050BF2E /* FBSDKShareAPIIntegrationTests.m */, + DB3A5EF91BED6E4D003919E4 /* FBSDKShareKit+Internal.h */, 9D1999C81A7AF5EF00CAD112 /* FBSDKTestBlocker.h */, 9D1999C91A7AF5EF00CAD112 /* FBSDKTestBlocker.m */, 9D1999D71A7AF6E400CAD112 /* FBSDKTestUsersManagersIntegrationTests.m */, @@ -212,6 +220,9 @@ 9D2BA0981AB9E110004C7C0C /* FBSDKTestHost */ = { isa = PBXGroup; children = ( + 9332A7571BF1DCCD004C53FD /* thumbs_up.jpg */, + 9332A7551BF1DCBD004C53FD /* hack.png */, + 93266D941BBA11CB00874D8B /* videoviewdemo.mp4 */, 9D2BA09D1AB9E110004C7C0C /* AppDelegate.h */, 9D2BA09E1AB9E110004C7C0C /* AppDelegate.m */, 9D2BA0A01AB9E110004C7C0C /* ViewController.h */, @@ -313,6 +324,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 93266D961BBA121200874D8B /* videoviewdemo.mp4 in Resources */, + 9332A7591BF1DD6B004C53FD /* thumbs_up.jpg in Resources */, + 9332A75A1BF1DD6F004C53FD /* hack.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKIntegrationTestCase.m b/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKIntegrationTestCase.m index bedddc655..744811dfc 100644 --- a/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKIntegrationTestCase.m +++ b/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKIntegrationTestCase.m @@ -46,14 +46,14 @@ static id g_mockNSBundle; if (g_AppID.length == 0 || g_AppSecret.length == 0 || g_AppClientToken.length == 0) { [[NSException exceptionWithName:NSInternalInconsistencyException reason: - @"Integration Tests Cannot Be Run." - @"Missing App ID or App Secret, or Client Token in Build Settings." - @" You can set this in an xcconfig file containing your unit-testing Facebook" - @" Application's ID and Secret in this format:\n" + @"Integration Tests cannot be run. " + @"Missing App ID or App Secret, or Client Token in Build Settings. " + @"You can set this in an xcconfig file containing your unit-testing Facebook " + @"Application's ID and Secret in this format:\n" @"\tIOS_SDK_TEST_APP_ID = // your app ID, e.g.: 1234567890\n" @"\tIOS_SDK_TEST_APP_SECRET = // your app secret, e.g.: 1234567890abcdef\n" @"\tIOS_SDK_TEST_CLIENT_TOKEN = // your app client token, e.g.: 1234567890abcdef\n" - @"Do NOT release your app secret in your app" + @"Do NOT release your app secret in your app. " @"To create a Facebook AppID, visit https://developers.facebook.com/apps" userInfo:nil] raise]; @@ -61,14 +61,11 @@ static id g_mockNSBundle; [FBSDKSettings setAppID:g_AppID]; g_testUsersManager = [FBSDKTestUsersManager sharedInstanceForAppID:g_AppID appSecret:g_AppSecret]; }); - - if (self == [FBSDKIntegrationTestCase class]) { - // swizzle out mainBundle - XCTest returns the XCTest program bundle instead of the target, - // and our keychain code is coded against mainBundle. - g_mockNSBundle = [OCMockObject niceMockForClass:[NSBundle class]]; - NSBundle *correctMainBundle = [NSBundle bundleForClass:[self class]]; - [[[[g_mockNSBundle stub] classMethod] andReturn:correctMainBundle] mainBundle]; - } + // swizzle out mainBundle - XCTest returns the XCTest program bundle instead of the target, + // and our keychain code is coded against mainBundle. + g_mockNSBundle = [OCMockObject niceMockForClass:[NSBundle class]]; + NSBundle *correctMainBundle = [NSBundle bundleForClass:[self class]]; + [[[[g_mockNSBundle stub] classMethod] andReturn:correctMainBundle] mainBundle]; } + (void)tearDown diff --git a/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKShareAPIIntegrationTests.m b/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKShareAPIIntegrationTests.m index 5010df299..2f438f905 100644 --- a/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKShareAPIIntegrationTests.m +++ b/FBSDKIntegrationTests/FBSDKIntegrationTests/FBSDKShareAPIIntegrationTests.m @@ -27,15 +27,21 @@ #import #import "FBSDKIntegrationTestCase.h" +#import "FBSDKShareKit+Internal.h" #import "FBSDKTestBlocker.h" -@interface FBSDKShareAPIIntegrationTests : FBSDKIntegrationTestCase +@interface FBSDKShareAPIIntegrationTests : FBSDKIntegrationTestCase @property (nonatomic, copy) void (^shareCallback)(NSDictionary *results, NSError *error, BOOL isCancel); - +@property (nonatomic, copy) void (^uploadCallback)(NSDictionary *results, NSError *error); @end +static NSString *const kTaggedPlaceID = @"88603851976"; + @implementation FBSDKShareAPIIntegrationTests +{ + NSFileHandle *_fileHandle; +} #pragma mark - FBSDKSharingDelegate @@ -62,50 +68,46 @@ } } -- (void)testOpenGraph { +#pragma mark - FBSDKVideoUploaderDelegate + +- (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger)startOffset endOffset:(NSUInteger)endOffset +{ + NSUInteger chunkSize = endOffset - startOffset; + [_fileHandle seekToFileOffset:startOffset]; + NSData *videoChunkData = [_fileHandle readDataOfLength:chunkSize]; + if (videoChunkData == nil || videoChunkData.length != chunkSize) { + NSCAssert(videoChunkData == nil || videoChunkData.length != chunkSize, @"fail to get video chunk"); + return nil; + } + return videoChunkData; +} + +- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSMutableDictionary *)results +{ + if (self.uploadCallback) { + self.uploadCallback(results, nil); + self.uploadCallback = nil; + } +} + +- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error +{ + if (self.uploadCallback) { + self.uploadCallback(nil, error); + self.uploadCallback = nil; + } +} + +#pragma mark - Test OpenGraph + +- (void)testOpenGraph +{ [FBSDKSettings setFacebookDomainPart:@"prod"]; - FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; - __block FBSDKAccessToken *one = nil, *two = nil; - FBSDKTestUsersManager *userManager = [self testUsersManager]; - // get two users. - [userManager requestTestAccountTokensWithArraysOfPermissions:@[ - [NSSet setWithObjects:@"user_friends", @"publish_actions", nil], - [NSSet setWithObject:@"user_friends"]] - createIfNotFound:YES - completionHandler:^(NSArray *tokens, NSError *error) { - XCTAssertNil(error); - one = tokens[0]; - two = tokens[1]; - [blocker signal]; - }]; - XCTAssertTrue([blocker waitWithTimeout:5], @"couldn't get 2 test users"); - - // make them friends - blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; - [userManager makeFriendsWithFirst:one second:two callback:^(NSError *error) { - XCTAssertNil(error); - [blocker signal]; - }]; - XCTAssertTrue([blocker waitWithTimeout:5], @"couldn't make friends between:\n%@\n%@", one.tokenString, two.tokenString); - - // now set one as active, and get taggable friend. - [FBSDKAccessToken setCurrentAccessToken:one]; - __block NSString *tag = nil; - __block NSString *taggedName = nil; - blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me/taggable_friends?limit=1" parameters:nil] - startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - XCTAssertNil(error); - tag = result[@"data"][0][@"id"]; - // grab the name for later verification. unfortunately we can't just compare to - // two.userID since there may already be (other) friends for this test users. - taggedName = result[@"data"][0][@"name"]; - [blocker signal]; - }]; - XCTAssertTrue([blocker waitWithTimeout:5], @"couldn't fetch taggable friends"); - XCTAssertNotNil(tag); - XCTAssertNotNil(taggedName); - + NSArray *testUsers = [self createTwoFriendedTestUsers]; + FBSDKAccessToken *one = testUsers[0]; + NSDictionary *tagParameters = [self taggableFriendsOfTestUser:one]; + NSString *tag = tagParameters[@"tag"]; + NSString *taggedName = tagParameters[@"taggedName"]; // now do the share FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init]; content.action = [FBSDKShareOpenGraphAction actionWithType:@"facebooksdktests:run" @@ -113,10 +115,9 @@ key:@"test"]; content.peopleIDs = @[tag]; content.previewPropertyName = @"test"; - static NSString *const placeID = @"88603851976"; - content.placeID = placeID; + content.placeID = kTaggedPlaceID; - blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; __block NSString *postID = nil; self.shareCallback = ^(NSDictionary *results, NSError *error, BOOL isCancel) { NSCAssert(error == nil, @"share failed :%@", error); @@ -136,10 +137,194 @@ XCTAssertNil(error); XCTAssertEqualObjects(postID, result[@"id"]); XCTAssertEqualObjects(taggedName, result[@"tags"][0][@"name"]); - XCTAssertEqualObjects(placeID, result[@"place"][@"id"]); + XCTAssertEqualObjects(kTaggedPlaceID, result[@"place"][@"id"]); [blocker signal]; }]; + XCTAssertTrue([blocker waitWithTimeout:20], @"couldn't fetch verify post."); +} + +#pragma mark - Test Share Link + +- (void)testShareLink +{ + [FBSDKSettings setFacebookDomainPart:@"prod"]; + NSArray *testUsers = [self createTwoFriendedTestUsers]; + FBSDKAccessToken *one = testUsers[0]; + NSDictionary *tagParameters = [self taggableFriendsOfTestUser:one]; + NSString *tag = tagParameters[@"tag"]; + NSString *taggedName = tagParameters[@"taggedName"]; + // now do the share + FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init]; + content.contentURL = [NSURL URLWithString:@"http://liveshows.disney.com/"]; + content.peopleIDs = @[tag]; + content.placeID = kTaggedPlaceID; + + FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + __block NSString *postID = nil; + self.shareCallback = ^(NSDictionary *results, NSError *error, BOOL isCancel) { + NSCAssert(error == nil, @"share failed :%@", error); + NSCAssert(!isCancel, @"share cancelled"); + postID = results[@"postId"]; + [blocker signal]; + }; + [FBSDKShareAPI shareWithContent:content delegate:self]; + XCTAssertTrue([blocker waitWithTimeout:5], @"share didn't complete"); + XCTAssertNotNil(postID); + + //now fetch and verify the share. + blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:postID + parameters:@{ @"fields" : @"id,with_tags.limit(1){name}, place.limit(1){id}" } ] + startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + XCTAssertNil(error); + XCTAssertEqualObjects(postID, result[@"id"]); + XCTAssertEqualObjects(taggedName, result[@"with_tags"][@"data"][0][@"name"]); + XCTAssertEqualObjects(kTaggedPlaceID, result[@"place"][@"id"]); + [blocker signal]; + }]; XCTAssertTrue([blocker waitWithTimeout:200], @"couldn't fetch verify post."); } +#pragma mark - Test Share Photo + +- (void)testSharePhoto +{ + [FBSDKSettings setFacebookDomainPart:@"prod"]; + NSArray *testUsers = [self createTwoFriendedTestUsers]; + FBSDKAccessToken *one = testUsers[0]; + NSDictionary *tagParameters = [self taggableFriendsOfTestUser:one]; + NSString *tag = tagParameters[@"tag"]; + NSString *taggedName = tagParameters[@"taggedName"]; + // now do the share + [FBSDKAccessToken setCurrentAccessToken:one]; + FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init]; + content.photos = @[[FBSDKSharePhoto photoWithImage:[UIImage imageNamed:@"hack.png"] userGenerated:YES]]; + content.peopleIDs = @[tag]; + content.placeID = kTaggedPlaceID; + + FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + __block NSString *postID = nil; + self.shareCallback = ^(NSDictionary *results, NSError *error, BOOL isCancel) { + NSCAssert(error == nil, @"share failed :%@", error); + NSCAssert(!isCancel, @"share cancelled"); + postID = results[@"postId"]; + [blocker signal]; + }; + [FBSDKShareAPI shareWithContent:content delegate:self]; + XCTAssertTrue([blocker waitWithTimeout:10], @"share didn't complete"); + XCTAssertNotNil(postID); + + //now fetch and verify the share. + blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:postID + parameters:@{ @"fields" : @"id,with_tags.limit(1){name}, place.limit(1){id}" } ] + startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + XCTAssertNil(error); + XCTAssertEqualObjects(taggedName, result[@"with_tags"][@"data"][0][@"name"]); + XCTAssertEqualObjects(kTaggedPlaceID, result[@"place"][@"id"]); + [blocker signal]; + }]; + XCTAssertTrue([blocker waitWithTimeout:200], @"couldn't fetch verify post."); +} + +#pragma mark - Test Share Video + +- (void)testShareVideo +{ + [FBSDKSettings setFacebookDomainPart:@"prod"]; + NSArray *testUsers = [self createTwoFriendedTestUsers]; + FBSDKAccessToken *one = testUsers[0]; + NSDictionary *tagParameters = [self taggableFriendsOfTestUser:one]; + NSString *tag = tagParameters[@"tag"]; + // now do the share + [FBSDKAccessToken setCurrentAccessToken:one]; + FBSDKShareVideoContent *content = [[FBSDKShareVideoContent alloc] init]; + NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:@"videoviewdemo" withExtension:@"mp4"]; + content.video = [FBSDKShareVideo videoWithVideoURL:bundleURL]; + content.peopleIDs = @[tag]; + + FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + self.shareCallback = ^(NSDictionary *results, NSError *error, BOOL isCancel) { + NSCAssert(results == nil, @"VideoContent should not allow peopleIDs"); + NSCAssert(error != nil, @"VideoContent should not allow peopleIDs."); + [blocker signal]; + }; + [FBSDKShareAPI shareWithContent:content delegate:self]; + XCTAssertTrue([blocker waitWithTimeout:10], @"share didn't complete"); +} + +- (void)testVideoUploader +{ + [FBSDKSettings setFacebookDomainPart:@"prod"]; + FBSDKAccessToken *token = [self getTokenWithPermissions:[NSSet setWithObject:@"publish_actions"]]; + [FBSDKAccessToken setCurrentAccessToken:token]; + NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; + NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:@"videoviewdemo" withExtension:@"mp4"]; + //test on file URL + __block FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + _fileHandle = [NSFileHandle fileHandleForReadingFromURL:bundleURL error:nil]; + NSCAssert(_fileHandle, @"Fail to get file handler"); + FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[bundleURL lastPathComponent] videoSize:(unsigned long)[_fileHandle seekToEndOfFile] parameters:dictionary delegate:self]; + self.uploadCallback = ^(NSDictionary *results, NSError *error) { + NSCAssert(error == nil, @"upload failed :%@", error); + NSCAssert(results[@"success"], @"upload fail"); + [blocker signal]; + }; + [videoUploader start]; + XCTAssertTrue([blocker waitWithTimeout:20], @"upload didn't complete"); +} + +#pragma mark - Help Method + +- (NSArray *)createTwoFriendedTestUsers +{ + FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + __block FBSDKAccessToken *one = nil, *two = nil; + FBSDKTestUsersManager *userManager = [self testUsersManager]; + // get two users. + [userManager requestTestAccountTokensWithArraysOfPermissions:@[ + [NSSet setWithObjects:@"user_friends", @"publish_actions", @"user_posts", nil], + [NSSet setWithObject:@"user_friends"]] + createIfNotFound:YES + completionHandler:^(NSArray *tokens, NSError *error) { + XCTAssertNil(error); + one = tokens[0]; + two = tokens[1]; + [blocker signal]; + }]; + XCTAssertTrue([blocker waitWithTimeout:15], @"couldn't get 2 test users"); + + // make them friends + blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + [userManager makeFriendsWithFirst:one second:two callback:^(NSError *error) { + XCTAssertNil(error); + [blocker signal]; + }]; + XCTAssertTrue([blocker waitWithTimeout:5], @"couldn't make friends between:\n%@\n%@", one.tokenString, two.tokenString); + return @[one, two]; +} + +- (NSDictionary *)taggableFriendsOfTestUser:(FBSDKAccessToken *)testUser +{ + [FBSDKAccessToken setCurrentAccessToken:testUser]; + __block NSString *tag = nil; + __block NSString *taggedName = nil; + __block FBSDKTestBlocker *blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + blocker = [[FBSDKTestBlocker alloc] initWithExpectedSignalCount:1]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me/taggable_friends?limit=1" parameters:nil] + startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + XCTAssertNil(error); + tag = result[@"data"][0][@"id"]; + // grab the name for later verification. unfortunately we can't just compare to + // two.userID since there may already be (other) friends for this test users. + taggedName = result[@"data"][0][@"name"]; + [blocker signal]; + }]; + XCTAssertTrue([blocker waitWithTimeout:5], @"couldn't fetch taggable friends"); + XCTAssertNotNil(tag); + XCTAssertNotNil(taggedName); + return @{ @"tag" : tag, + @"taggedName" : taggedName }; +} + @end diff --git a/FBSDKIntegrationTests/FBSDKTestHost/hack.png b/FBSDKIntegrationTests/FBSDKTestHost/hack.png new file mode 100644 index 000000000..0faca0d7d Binary files /dev/null and b/FBSDKIntegrationTests/FBSDKTestHost/hack.png differ diff --git a/FBSDKIntegrationTests/FBSDKTestHost/thumbs_up.jpg b/FBSDKIntegrationTests/FBSDKTestHost/thumbs_up.jpg new file mode 100644 index 000000000..b4580cba0 Binary files /dev/null and b/FBSDKIntegrationTests/FBSDKTestHost/thumbs_up.jpg differ diff --git a/FBSDKIntegrationTests/FBSDKTestHost/videoviewdemo.mp4 b/FBSDKIntegrationTests/FBSDKTestHost/videoviewdemo.mp4 new file mode 100644 index 000000000..57728106d Binary files /dev/null and b/FBSDKIntegrationTests/FBSDKTestHost/videoviewdemo.mp4 differ diff --git a/FBSDKLoginKit.podspec b/FBSDKLoginKit.podspec index 319588c30..c27968da8 100644 --- a/FBSDKLoginKit.podspec +++ b/FBSDKLoginKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = "FBSDKLoginKit" - s.version = "4.7.1" + s.version = "4.8.0" s.summary = "Official Facebook SDK for iOS to access Facebook Platform with features like Login, Share and Message Dialog, App Links, and Graph API" s.description = <<-DESC @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = "7.0" s.source = { :git => "https://github.com/facebook/facebook-ios-sdk.git", - :tag => "sdk-version-4.7.1" + :tag => "sdk-version-4.8.0" } s.weak_frameworks = "Accounts", "CoreLocation", "Social", "Security", "QuartzCore", "CoreGraphics", "UIKit", "Foundation", "AudioToolbox" diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index c8c2024ba..e74fb1bfa 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -173,18 +173,18 @@ 9D3AF4911A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.h */, 9D3AF4921A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.m */, 9DBC4C3B1A782E2000816FE8 /* FBSDKCoreKit+Internal.h */, - 6BADA8CF1A9544BC00A5ADC1 /* FBSDKLoginKit+Internal.h */, 6B5D2DEC1A8EB1D200D3EF09 /* FBSDKLoginCompletion.h */, - 6BAFD01F1A9531EA0096E4B5 /* FBSDKLoginCompletion+Internal.h */, 6B5D2DED1A8EB1D200D3EF09 /* FBSDKLoginCompletion.m */, + 6BAFD01F1A9531EA0096E4B5 /* FBSDKLoginCompletion+Internal.h */, + 6B5D2DEB1A8D91BD00D3EF09 /* FBSDKLoginError.h */, + 6B5D2DE91A8D91B200D3EF09 /* FBSDKLoginError.m */, + 6BADA8CF1A9544BC00A5ADC1 /* FBSDKLoginKit+Internal.h */, 9D6999F81A76DE58003AE384 /* FBSDKLoginManager+Internal.h */, 6B34A7EB1ABA4E6B00AF9858 /* FBSDKLoginManagerLogger.h */, 6B34A7EC1ABA4E6B00AF9858 /* FBSDKLoginManagerLogger.m */, - 6B5D2DEB1A8D91BD00D3EF09 /* FBSDKLoginError.h */, - 6B5D2DE91A8D91B200D3EF09 /* FBSDKLoginError.m */, + 9D1148FB1B97C42200A6A2B8 /* FBSDKLoginManagerLoginResult+Internal.h */, 9D03E8281A72DCE300207493 /* FBSDKLoginUtility.h */, 9D03E8291A72DCE300207493 /* FBSDKLoginUtility.m */, - 9D1148FB1B97C42200A6A2B8 /* FBSDKLoginManagerLoginResult+Internal.h */, ); path = Internal; sourceTree = ""; @@ -221,10 +221,10 @@ 9D03E8201A72D7E700207493 /* FBSDKLoginManager.m */, 9D03E8231A72D89100207493 /* FBSDKLoginManagerLoginResult.h */, 9D03E8241A72D89100207493 /* FBSDKLoginManagerLoginResult.m */, - 9DDFBB701A829503006C9208 /* FBSDKTooltipView.h */, - 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */, 9DBA6A2C1A80253F00B4DE6A /* FBSDKLoginTooltipView.h */, 9DBA6A281A80252F00B4DE6A /* FBSDKLoginTooltipView.m */, + 9DDFBB701A829503006C9208 /* FBSDKTooltipView.h */, + 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */, 9D03E8271A72DCA700207493 /* Internal */, 9D9DB8DC1A114E500086167B /* Supporting Files */, ); diff --git a/FBSDKMessengerShareKit.podspec b/FBSDKMessengerShareKit.podspec index ac0196053..a3aaeb3d2 100644 --- a/FBSDKMessengerShareKit.podspec +++ b/FBSDKMessengerShareKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = "FBSDKMessengerShareKit" - s.version = "1.3.1" + s.version = "1.3.2" s.summary = "Official Facebook SDK for iOS to integrate with Messenger" s.description = <<-DESC @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = "7.0" s.source = { :git => "https://github.com/facebook/facebook-ios-sdk.git", - :tag => "messenger-share-kit-version-1.3.1" + :tag => "messenger-share-kit-version-1.3.2" } s.source_files = "FBSDKMessengerShareKit/FBSDKMessengerShareKit/**/*.{h,m}" diff --git a/FBSDKMessengerShareKit/Configurations/FacebookSDK-Project.xcconfig b/FBSDKMessengerShareKit/Configurations/FacebookSDK-Project.xcconfig index 64c5cd859..2ddf17315 100644 --- a/FBSDKMessengerShareKit/Configurations/FacebookSDK-Project.xcconfig +++ b/FBSDKMessengerShareKit/Configurations/FacebookSDK-Project.xcconfig @@ -57,8 +57,7 @@ CLANG_CXX_LIBRARY = libc++ // env which applies for Archive builds. ENABLE_BITCODE = NO FB_BITCODE_FLAG = $() -FB_BITCODE_FLAG[sdk=iphoneos9.0] = -fembed-bitcode -FB_BITCODE_FLAG[sdk=iphonesimulator9.0] = -fembed-bitcode +FB_BITCODE_FLAG[sdk=iphoneos9.*] = -fembed-bitcode OTHER_CFLAGS = $(inherited) $(FB_BITCODE_FLAG) diff --git a/FBSDKShareKit.podspec b/FBSDKShareKit.podspec index 38c74c445..dca3e195d 100644 --- a/FBSDKShareKit.podspec +++ b/FBSDKShareKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = "FBSDKShareKit" - s.version = "4.7.1" + s.version = "4.8.0" s.summary = "Official Facebook SDK for iOS to access Facebook Platform's Sharing Features" s.description = <<-DESC @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.ios.deployment_target = "7.0" s.source = { :git => "https://github.com/facebook/facebook-ios-sdk.git", - :tag => "sdk-version-4.7.1" + :tag => "sdk-version-4.8.0" } s.weak_frameworks = "Accounts", "CoreLocation", "Social", "Security", "QuartzCore", "CoreGraphics", "UIKit", "Foundation", "AudioToolbox" diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index 8ebd6bd71..10842bde7 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -117,6 +117,8 @@ 89FC9C6F1A3FA1E00001910E /* FBSDKSharePhotoContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 89FC9C6D1A3FA1E00001910E /* FBSDKSharePhotoContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 89FC9C701A3FA1E00001910E /* FBSDKSharePhotoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FC9C6E1A3FA1E00001910E /* FBSDKSharePhotoContent.m */; }; 89FC9C761A3FAB4B0001910E /* FBSDKSharePhotoContentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FC9C751A3FAB4B0001910E /* FBSDKSharePhotoContentTests.m */; }; + 9382B7901BB3A5AD00E4B24F /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */; }; + 93AECB911BB4B93D001AC1C4 /* FBSDKVideoUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */; }; 9D46C5F61A11E5D800A0DDB6 /* FBSDKShareKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D46C5F51A11E5D800A0DDB6 /* FBSDKShareKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D46C5FC1A11E5D800A0DDB6 /* FBSDKShareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D46C5F01A11E5D800A0DDB6 /* FBSDKShareKit.framework */; }; 9DDACD501B45CAD100075EF3 /* FBSDKShareLinkContent+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DDACD4F1B45CA0100075EF3 /* FBSDKShareLinkContent+Internal.h */; }; @@ -253,6 +255,9 @@ 89FC9C6D1A3FA1E00001910E /* FBSDKSharePhotoContent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKSharePhotoContent.h; sourceTree = ""; }; 89FC9C6E1A3FA1E00001910E /* FBSDKSharePhotoContent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSharePhotoContent.m; sourceTree = ""; }; 89FC9C751A3FAB4B0001910E /* FBSDKSharePhotoContentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSharePhotoContentTests.m; sourceTree = ""; }; + 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKVideoUploader.h; sourceTree = ""; }; + 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKVideoUploader.m; sourceTree = ""; }; + 9382B7921BB47DC100E4B24F /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 9D46C5F01A11E5D800A0DDB6 /* FBSDKShareKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKShareKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9D46C5F41A11E5D800A0DDB6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9D46C5F51A11E5D800A0DDB6 /* FBSDKShareKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKShareKit.h; sourceTree = ""; }; @@ -299,6 +304,7 @@ 892EBBE91A3A475F00721B03 /* Frameworks */ = { isa = PBXGroup; children = ( + 9382B7921BB47DC100E4B24F /* AssetsLibrary.framework */, 89FC8C491AC9A017004187B2 /* libOCMock.a */, 9DEE5C911A671B2700D750E1 /* QuartzCore.framework */, 9DEE5C8F1A671B2100D750E1 /* XCTest.framework */, @@ -389,6 +395,8 @@ 89C1DCB41A43528900F0F9B2 /* FBSDKShareOpenGraphValueContainer+Internal.h */, 891C54561A3BB23F00DF05AF /* FBSDKShareUtility.h */, 891C54571A3BB23F00DF05AF /* FBSDKShareUtility.m */, + 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */, + 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */, ); path = Internal; sourceTree = ""; @@ -474,10 +482,10 @@ 89DC6CC71A81792000814152 /* FBSDKShareAPI.m */, 893774871A3B5B9A00BE2807 /* FBSDKShareConstants.h */, 893774881A3B5B9A00BE2807 /* FBSDKShareConstants.m */, - DB38B6811AAF663600099656 /* FBSDKShareDialogMode.h */, - DB38B6821AAF668100099656 /* FBSDKShareDialogMode.m */, 8973B3771A40A8B90001EDC5 /* FBSDKShareDialog.h */, 8973B3781A40A8B90001EDC5 /* FBSDKShareDialog.m */, + DB38B6811AAF663600099656 /* FBSDKShareDialogMode.h */, + DB38B6821AAF668100099656 /* FBSDKShareDialogMode.m */, 9D46C5F51A11E5D800A0DDB6 /* FBSDKShareKit.h */, 8904147F1A64849100617215 /* FBSDKSharing.h */, 8937747A1A3A5F5B00BE2807 /* Internal */, @@ -546,6 +554,7 @@ 89688B3B1AA62BD800A98519 /* FBSDKLikeBoxView.h in Headers */, 891C54581A3BB23F00DF05AF /* FBSDKShareUtility.h in Headers */, 8904147D1A64843500617215 /* FBSDKMessageDialog.h in Headers */, + 93AECB911BB4B93D001AC1C4 /* FBSDKVideoUploader.h in Headers */, 89CE02E51A3F56470033C9CA /* FBSDKShareLinkContent.h in Headers */, 893774771A3A585600BE2807 /* FBSDKShareOpenGraphObject.h in Headers */, 89688B421AA62C4100A98519 /* FBSDKLikeBoxBorderView.h in Headers */, @@ -717,6 +726,7 @@ 8937748E1A3B5E9E00BE2807 /* FBSDKShareOpenGraphAction.m in Sources */, 896DE21B1A9E282800195731 /* FBSDKShareVideoContent.m in Sources */, 89DC6CC91A81792000814152 /* FBSDKShareAPI.m in Sources */, + 9382B7901BB3A5AD00E4B24F /* FBSDKVideoUploader.m in Sources */, DB38B6831AAF668100099656 /* FBSDKShareDialogMode.m in Sources */, 89D05A801AA0E0D300609300 /* FBSDKLikeActionController.m in Sources */, EA3D468F1AA62A9500D0C7D5 /* FBSDKAppInviteDialog.m in Sources */, diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m index 070fd9973..31d343eff 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m @@ -115,6 +115,11 @@ } return NO; } + if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { + if (![FBSDKShareUtility validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)shareContent name:@"videoURL" error:errorRef]) { + return NO; + } + } return [FBSDKShareUtility validateShareContent:self.shareContent error:errorRef]; } diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.m index 69f124f9d..d2b71bfed 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.m @@ -37,12 +37,20 @@ #import "FBSDKShareUtility.h" #import "FBSDKShareVideo.h" #import "FBSDKShareVideoContent.h" +#import "FBSDKVideoUploader.h" static NSString *const FBSDKShareAPIDefaultGraphNode = @"me"; static NSString *const FBSDKShareAPIPhotosEdge = @"photos"; static NSString *const FBSDKShareAPIVideosEdge = @"videos"; +static NSMutableArray *g_pendingFBSDKShareAPI; -@implementation FBSDKShareAPI +@interface FBSDKShareAPI () +@end + +@implementation FBSDKShareAPI { + NSFileHandle *_fileHandle; + ALAssetRepresentation *_assetRepresentation; +} #pragma mark - Class Methods @@ -62,6 +70,23 @@ static NSString *const FBSDKShareAPIVideosEdge = @"videos"; @synthesize shouldFailOnDataError = _shouldFailOnDataError; #pragma mark - Object Lifecycle + ++ (ALAssetsLibrary *)defaultAssetsLibrary { + static dispatch_once_t pred = 0; + static ALAssetsLibrary *library = nil; + dispatch_once(&pred, ^{ + library = [[fbsdkdfl_ALAssetsLibraryClass() alloc] init]; + }); + return library; +} + ++ (void)initialize +{ + if (self == [FBSDKShareAPI class]) { + g_pendingFBSDKShareAPI = [[NSMutableArray alloc] init]; + } +} + - (instancetype)init { if ((self = [super init])) { @@ -146,11 +171,21 @@ static NSString *const FBSDKShareAPIVideosEdge = @"videos"; { id shareContent = self.shareContent; if (!shareContent) { - if (errorRef != NULL) { - *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:nil]; + if (errorRef == NULL) { + *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:@"Share content cannot be null."]; } return NO; } + if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { + if (shareContent.peopleIDs.count > 0) { + *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"peopleIDs" value:shareContent.peopleIDs message:@"Cannot specify peopleIDs with FBSDKShareVideoContent."]; + return NO; + } + if (shareContent.placeID) { + *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"placeID" value:shareContent.placeID message:@"Cannot specify place ID with FBSDKShareVideoContent."]; + return NO; + } + } return [FBSDKShareUtility validateShareContent:shareContent error:errorRef]; } @@ -170,8 +205,20 @@ static NSString *const FBSDKShareAPIVideosEdge = @"videos"; - (void)_addCommonParameters:(NSMutableDictionary *)parameters content:(id)content { - NSString *tags = [content.peopleIDs componentsJoinedByString:@","]; - [FBSDKInternalUtility dictionary:parameters setObject:tags forKey:@"tags"]; + if (content.peopleIDs.count > 0) { + NSString *tags; + if ([content isKindOfClass:[FBSDKSharePhotoContent class]]) { + NSMutableArray *tagsArray = [[NSMutableArray alloc] init]; + for (NSString *peopleID in content.peopleIDs) { + [tagsArray addObject:@{ @"tag_uid" : peopleID }]; + } + NSData *tagsJSON = [NSJSONSerialization dataWithJSONObject:tagsArray options:0 error:nil]; + tags = [[NSString alloc] initWithData:tagsJSON encoding:NSUTF8StringEncoding]; + } else { + tags = [content.peopleIDs componentsJoinedByString:@","]; + } + [FBSDKInternalUtility dictionary:parameters setObject:tags forKey:@"tags"]; + } [FBSDKInternalUtility dictionary:parameters setObject:content.placeID forKey:@"place"]; [FBSDKInternalUtility dictionary:parameters setObject:content.ref forKey:@"ref"]; } @@ -316,23 +363,6 @@ static NSString *const FBSDKShareAPIVideosEdge = @"videos"; - (BOOL)_shareVideoContent:(FBSDKShareVideoContent *)videoContent { - FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - if (!_delegate) { - return; - } - if (error) { - [_delegate sharer:self didFailWithError:error]; - } else { - result = [FBSDKTypeUtility dictionaryValue:result]; - NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; - [FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST - forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; - [FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:result[@"id"]] - forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; - [_delegate sharer:self didCompleteWithResults:shareResults]; - } - }; - NSString *graphPath = [self _graphPathWithSuffix:FBSDKShareAPIVideosEdge, nil]; NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [self _addCommonParameters:parameters content:videoContent]; [FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"description"]; @@ -346,45 +376,34 @@ static NSString *const FBSDKShareAPIVideosEdge = @"videos"; } FBSDKShareVideo *video = videoContent.video; NSURL *videoURL = video.videoURL; - void(^postVideoBlock)(NSData *,NSString *) = ^(NSData *videoData, NSString *filename){ - FBSDKGraphRequestDataAttachment *dataAttachment = [[FBSDKGraphRequestDataAttachment alloc] initWithData:videoData - filename:filename - contentType:nil]; - [FBSDKInternalUtility dictionary:parameters setObject:dataAttachment forKey:filename]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:graphPath - parameters:parameters - HTTPMethod:@"POST"] startWithCompletionHandler:completionHandler]; - }; if ([videoURL isFileURL]) { NSError *fileError; - NSData *videoData = [NSData dataWithContentsOfURL:video.videoURL - options:NSDataReadingMapped - error:&fileError]; - if (!videoData) { + _fileHandle = [NSFileHandle fileHandleForReadingFromURL:videoURL error:&fileError]; + if (!_fileHandle) { [_delegate sharer:self didFailWithError:fileError]; return NO; } - NSString *filename = [[NSString alloc] initWithFormat:@"video.%@", video.videoURL.pathExtension]; - postVideoBlock(videoData, filename); + if (![self _addToPendingShareAPI]) { + return NO; + } + FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent] + videoSize:(unsigned long)[_fileHandle seekToEndOfFile] + parameters:parameters + delegate:self]; + [videoUploader start]; return YES; } else if (videoURL) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - [[[fbsdkdfl_ALAssetsLibraryClass() alloc] init] assetForURL:video.videoURL resultBlock:^(ALAsset *asset) { - ALAssetRepresentation *defaultRepresentation = [asset defaultRepresentation]; - NSUInteger size = (NSUInteger)defaultRepresentation.size; - Byte *buffer = (Byte *)malloc(size); - NSError *error; - NSUInteger bufferedLength = [defaultRepresentation getBytes:buffer fromOffset:0.0 length:size error:&error]; - if (bufferedLength == 0) { - free(buffer); - [_delegate sharer:self didFailWithError:error]; - return; - } - NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:bufferedLength freeWhenDone:YES]; - NSString *filename = [[NSString alloc] initWithFormat:@"video.%@", defaultRepresentation.filename.pathExtension]; -#pragma clang diagnostic pop - postVideoBlock(videoData, filename); + if (![self _addToPendingShareAPI]) { + return NO; + } + [[FBSDKShareAPI defaultAssetsLibrary] assetForURL:videoURL resultBlock:^(ALAsset *asset) { + _assetRepresentation = [asset defaultRepresentation]; + NSUInteger size = (NSUInteger)_assetRepresentation.size; + FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent] + videoSize:size + parameters:parameters + delegate:self]; + [videoUploader start]; } failureBlock:^(NSError *error) { [_delegate sharer:self didFailWithError:error]; }]; @@ -698,4 +717,67 @@ static NSString *const FBSDKShareAPIVideosEdge = @"videos"; return batchEntryName; } +- (BOOL)_addToPendingShareAPI +{ + @synchronized(g_pendingFBSDKShareAPI) { + if ([g_pendingFBSDKShareAPI containsObject:self]) { + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"FBSDKShareAPI did not share video content. Video upload already in progress."]; + return NO; + } + [g_pendingFBSDKShareAPI addObject:self]; + return YES; + } +} + +- (void)_removeFromPendingShareAPI +{ + @synchronized(g_pendingFBSDKShareAPI) { + [g_pendingFBSDKShareAPI removeObject:self]; + _fileHandle = nil; + _assetRepresentation = nil; + } +} + +#pragma mark - FBSDKVideoUploaderDelegate + +- (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger)startOffset endOffset:(NSUInteger)endOffset +{ + NSUInteger chunkSize = endOffset - startOffset; + if (_fileHandle) { + [_fileHandle seekToFileOffset:startOffset]; + NSData *videoChunkData = [_fileHandle readDataOfLength:chunkSize]; + if (videoChunkData == nil || videoChunkData.length != chunkSize) { + return nil; + } + return videoChunkData; + } else if (_assetRepresentation) { + NSMutableData *data = [NSMutableData dataWithLength:chunkSize]; + NSError *error; + NSUInteger bufferedLength = [_assetRepresentation getBytes:[data mutableBytes] fromOffset:startOffset length:chunkSize error:&error]; + if (bufferedLength != chunkSize || data == nil || error) { + return nil; + } + return data; + } + return nil; +} + +- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSDictionary *)results +{ + results = [FBSDKTypeUtility dictionaryValue:results]; + NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; + [FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; + [FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:results[FBSDK_SHARE_VIDEO_ID]] forKey:FBSDK_SHARE_VIDEO_ID]; + [_delegate sharer:self didCompleteWithResults:shareResults]; + [self _removeFromPendingShareAPI]; +} + +- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error +{ + [_delegate sharer:self didFailWithError:error]; + [self _removeFromPendingShareAPI]; +} + + + @end diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.h b/FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.h index 4f2af4f44..859f4fa83 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.h +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.h @@ -47,4 +47,9 @@ typedef NS_ENUM(NSInteger, FBSDKShareErrorCode) @discussion Use the canShare methods to check for this case before calling show. */ FBSDKShareDialogNotAvailableErrorCode, + + /*! + @The error code for unknown errors. + */ + FBSDKShareUnknownErrorCode, }; diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m index dca5b203b..35840502b 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m @@ -169,6 +169,11 @@ if (![FBSDKShareUtility validateShareContent:shareContent error:errorRef]) { return NO; } + if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { + if (![FBSDKShareUtility validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)shareContent name:@"videoURL" error:errorRef]) { + return NO; + } + } switch (self.mode) { case FBSDKShareDialogModeAutomatic:{ return ( diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h index 2d647fbf6..548a432c2 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h @@ -26,5 +26,16 @@ #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST @"post" #define FBSDK_SHARE_RESULT_DID_COMPLETE_KEY @"didComplete" #define FBSDK_SHARE_RESULT_POST_ID_KEY @"postId" +#define FBSDK_SHARE_VIDEO_END_OFFSET @"end_offset" +#define FBSDK_SHARE_VIDEO_FILE_CHUNK @"video_file_chunk" +#define FBSDK_SHARE_VIDEO_ID @"video_id" +#define FBSDK_SHARE_VIDEO_SIZE @"file_size" +#define FBSDK_SHARE_VIDEO_START_OFFSET @"start_offset" +#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE @"upload_phase" +#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH @"finish" +#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START @"start" +#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_TRANSFER @"transfer" +#define FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID @"upload_session_id" +#define FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS @"success" #define FBSDK_SHARE_WEB_PARAM_POST_ID_KEY @"post_id" #define FBSDK_SHARE_WEB_SCHEME @"https" diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h index 5c753776a..a17f2fd97 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h @@ -24,3 +24,4 @@ #import "FBSDKShareError.h" #import "FBSDKShareOpenGraphValueContainer+Internal.h" #import "FBSDKShareUtility.h" +#import "FBSDKVideoUploader.h" diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.h index 82ac804bf..91244fdba 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.h @@ -23,6 +23,7 @@ #import #import #import +#import #import @interface FBSDKShareUtility : NSObject @@ -44,6 +45,7 @@ containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef; + (BOOL)validateAppInviteContent:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef; ++ (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateShareContent:(id)shareContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateShareLinkContent:(FBSDKShareLinkContent *)linkContent error:(NSError *__autoreleasing *)errorRef; diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m index 8c296e0f0..5d4d10498 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m @@ -244,6 +244,23 @@ [self _validateNetworkURL:appInviteContent.appInvitePreviewImageURL name:@"appInvitePreviewImageURL" error:errorRef]); } ++ (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef +{ + FBSDKShareVideo *video = videoContent.video; + NSURL *videoURL = video.videoURL; + if (!videoURL || [[videoURL.scheme lowercaseString] isEqualToString:@"assets-library"]) { + if (errorRef != NULL) { + *errorRef = nil; + } + return YES; + } else { + if (errorRef != NULL) { + *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:videoURL message:nil]; + } + return NO; + } +} + + (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef { if (![self _validateRequiredValue:gameRequestContent name:@"content" error:errorRef] @@ -378,8 +395,7 @@ NSURL *videoURL = video.videoURL; return ([self _validateRequiredValue:videoContent name:@"videoContent" error:errorRef] && [self _validateRequiredValue:video name:@"video" error:errorRef] && - [self _validateRequiredValue:videoURL name:@"videoURL" error:errorRef] && - [self _validateAssetLibraryURL:videoURL name:@"videoURL" error:errorRef]); + [self _validateRequiredValue:videoURL name:@"videoURL" error:errorRef]); } #pragma mark - Object Lifecycle @@ -624,21 +640,6 @@ forShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent } } -+ (BOOL)_validateAssetLibraryURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef -{ - if (!URL || [[URL.scheme lowercaseString] isEqualToString:@"assets-library"]) { - if (errorRef != NULL) { - *errorRef = nil; - } - return YES; - } else { - if (errorRef != NULL) { - *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:URL message:nil]; - } - return NO; - } -} - + (BOOL)_validateFileURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { if (!URL) { diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h new file mode 100644 index 000000000..0509ef028 --- /dev/null +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h @@ -0,0 +1,102 @@ +// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. +// +// You are hereby granted a non-exclusive, worldwide, royalty-free license to use, +// copy, modify, and distribute this software in source code or binary form for use +// in connection with the web services and APIs provided by Facebook. +// +// As with any software that integrates with the Facebook platform, your use of +// this software is subject to the Facebook Developer Principles and Policies +// [http://developers.facebook.com/policy/]. This copyright notice shall be +// included in all copies or substantial portions of the software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#import + +#import + +#import +#import + +@protocol FBSDKVideoUploaderDelegate; + +/*! + @abstract A utility class for uploading through the chunk upload graph API. Using this class requires an access token in + `[FBSDKAccessToken currentAccessToken]` that has been granted the "publish_actions" permission. + @discussion see https://developers.facebook.com/docs/graph-api/video-uploads + */ +@interface FBSDKVideoUploader : NSObject + +/*! + @abstract Initialize videoUploader + @param videoName The file name of the video to be uploaded + @param videoSize The size of the video to be uploaded + @param parameters Optional parameters for video uploads. See Graph API documentation for the full list of parameters https://developers.facebook.com/docs/graph-api/reference/video + @param delegate Receiver's delegate + */ +- (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id)delegate +NS_DESIGNATED_INITIALIZER; + + +/*! + @abstract The video to be uploaded. + */ +@property (readonly, copy, nonatomic) FBSDKShareVideo *video; + +/*! + @abstract Optional parameters for video uploads. See Graph API documentation for the full list of parameters https://developers.facebook.com/docs/graph-api/reference/video + */ +@property (copy, nonatomic) NSDictionary *parameters; + +/*! + @abstract The graph node to which video should be uploaded + */ +@property (nonatomic, copy) NSString *graphNode; + +/*! + @abstract Receiver's delegate + */ +@property (weak, nonatomic) id delegate; + +/*! + @abstract Start upload process + */ +//TODO #6229672 add cancel and/or pause +- (void)start; + +@end + +/*! + @abstract A delegate for `FBSDKVideoUploader`. + @discussion The delegate passes video chunk to `FBSDKVideoUploader` object in `NSData` format and is notified with the results of the uploader. + */ +@protocol FBSDKVideoUploaderDelegate + +/*! + @abstract get chunk of the video to be uploaded in 'NSData' format + @param videoUploader The `FBSDKVideoUploader` object which is performing the upload process + @param startOffset The start offset of video chunk to be uploaded + @param endOffset The end offset of video chunk being to be uploaded + */ +- (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger) startOffset endOffset:(NSUInteger) endOffset; + +/*! + @abstract Notify the delegate that upload process success. + @param videoUploader The `FBSDKVideoUploader` object which is performing the upload process + @param results The result from successful upload + */ +- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSDictionary *)results; + +/*! + @abstract Notify the delegate that upload process fails. + @param videoUploader The `FBSDKVideoUploader` object which is performing the upload process + @param error The error object from unsuccessful upload + */ +- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error; + +@end diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m new file mode 100644 index 000000000..0864d0c1c --- /dev/null +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m @@ -0,0 +1,230 @@ +// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. +// +// You are hereby granted a non-exclusive, worldwide, royalty-free license to use, +// copy, modify, and distribute this software in source code or binary form for use +// in connection with the web services and APIs provided by Facebook. +// +// As with any software that integrates with the Facebook platform, your use of +// this software is subject to the Facebook Developer Principles and Policies +// [http://developers.facebook.com/policy/]. This copyright notice shall be +// included in all copies or substantial portions of the software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#import "FBSDKVideoUploader.h" + +#import + +#import + +#import + +#import "FBSDKShareDefines.h" +#import "FBSDKShareError.h" + +static NSString *const FBSDKVideoUploaderDefaultGraphNode = @"me"; +static NSString *const FBSDKVideoUploaderEdge = @"videos"; + +@implementation FBSDKVideoUploader +{ + NSNumber *_videoID; + NSNumber *_uploadSessionID; + NSNumberFormatter *_numberFormatter; + NSString *_graphPath; + NSString *_videoName; + NSUInteger _videoSize; +} + +- (instancetype)init NS_UNAVAILABLE +{ + assert(0); +} + +#pragma Public Method +- (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id)delegate +{ + self = [super init]; + if (self) { + _parameters = [parameters copy]; + _delegate = delegate; + _graphNode = FBSDKVideoUploaderDefaultGraphNode; + _videoName = videoName; + _videoSize = videoSize; + } + return self; +} + +- (void)start +{ + _graphPath = [self _graphPathWithSuffix:FBSDKVideoUploaderEdge, nil]; + [self _postStartRequest]; +} + +#pragma Helper Method + +- (void)_postStartRequest +{ + FBSDKGraphRequestHandler startRequestCompletionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) + { + if (error) { + [self.delegate videoUploader:self didFailWithError:error]; + return; + } else { + result = [FBSDKTypeUtility dictionaryValue:result]; + NSNumber *uploadSessionID = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID]]; + NSNumber *videoID = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_ID]]; + NSDictionary *offsetDictionary = [self _extractOffsetsFromResultDictionary:result]; + if (uploadSessionID == nil || videoID == nil) { + [self.delegate videoUploader:self didFailWithError:[ + FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode + message:@"Failed to get valid upload_session_id or video_id."]]; + return; + } else if (offsetDictionary == nil) { + return; + } + _uploadSessionID = uploadSessionID; + _videoID = videoID; + [self _startTransferRequestWithOffsetDictionary:offsetDictionary]; + } + }; + if (_videoSize == 0) { + [self.delegate videoUploader:self didFailWithError:[ + FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode + message:[NSString stringWithFormat:@"Invalid video size: %lu", (unsigned long)_videoSize]]]; + return; + } + [[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath + parameters:@{ + FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START, + FBSDK_SHARE_VIDEO_SIZE: [NSString stringWithFormat:@"%tu", _videoSize], + } + HTTPMethod:@"POST"] startWithCompletionHandler:startRequestCompletionHandler]; +} + +- (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictionary +{ + dispatch_queue_t dataQueue; + NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; + if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { + dataQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0); + } else { + dataQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); + } + NSUInteger startOffset = [offsetDictionary[FBSDK_SHARE_VIDEO_START_OFFSET] unsignedIntegerValue]; + NSUInteger endOffset = [offsetDictionary[FBSDK_SHARE_VIDEO_END_OFFSET] unsignedIntegerValue]; + if (startOffset == endOffset) { + [self _postFinishRequest]; + return; + } else { + dispatch_async(dataQueue, ^{ + size_t chunkSize = (unsigned long)(endOffset - startOffset); + NSData *data = [self.delegate videoChunkDataForVideoUploader:self startOffset:startOffset endOffset:endOffset]; + if (data == nil || data.length != chunkSize) { + [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message: + [NSString stringWithFormat:@"Fail to get video chunk with start offset: %lu, end offset : %lu.", (unsigned long)startOffset, (unsigned long)endOffset]]]; + return; + } + dispatch_async(dispatch_get_main_queue(), ^{ + FBSDKGraphRequestDataAttachment *dataAttachment = [[FBSDKGraphRequestDataAttachment alloc] initWithData:data + filename:_videoName + contentType:nil]; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath + parameters:@{ + FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_TRANSFER, + FBSDK_SHARE_VIDEO_START_OFFSET: offsetDictionary[FBSDK_SHARE_VIDEO_START_OFFSET], + FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID: _uploadSessionID, + FBSDK_SHARE_VIDEO_FILE_CHUNK: dataAttachment, + } + HTTPMethod:@"POST"]; + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *innerError) { + if (innerError) { + [self.delegate videoUploader:self didFailWithError:innerError]; + return; + } + NSDictionary *innerOffsetDictionary = [self _extractOffsetsFromResultDictionary:result]; + if (innerOffsetDictionary == nil) { + return; + } + [self _startTransferRequestWithOffsetDictionary:innerOffsetDictionary]; + }]; + }); + }); + } +} + +- (void)_postFinishRequest +{ + NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; + parameters[FBSDK_SHARE_VIDEO_UPLOAD_PHASE] = FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH; + parameters[FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID] = _uploadSessionID; + [parameters addEntriesFromDictionary:self.parameters]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath + parameters:parameters + HTTPMethod:@"POST"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + if (error) { + [self.delegate videoUploader:self didFailWithError:error]; + } else { + result = [FBSDKTypeUtility dictionaryValue:result]; + if (result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] == nil) { + [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode + message:@"Failed to finish uploading."]]; + return; + } + NSMutableDictionary *shareResult = [[NSMutableDictionary alloc] init]; + shareResult[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] = result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS]; + shareResult[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY] = FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST; + shareResult[FBSDK_SHARE_VIDEO_ID] = _videoID; + [self.delegate videoUploader:self didCompleteWithResults:shareResult]; + } + }]; +} + +- (NSDictionary *)_extractOffsetsFromResultDictionary:(id)result +{ + result = [FBSDKTypeUtility dictionaryValue:result]; + NSNumber *startNum = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_START_OFFSET]]; + NSNumber *endNum = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_END_OFFSET]]; + if (startNum == nil || endNum == nil) { + [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode + message:@"Fail to get valid start_offset or end_offset."]]; + return nil; + } + if ([startNum compare:endNum] == NSOrderedDescending) { + [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode + message:@"Invalid offset: start_offset is greater than end_offset."]]; + return nil; + } + + NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; + shareResults[FBSDK_SHARE_VIDEO_START_OFFSET] = startNum; + shareResults[FBSDK_SHARE_VIDEO_END_OFFSET] = endNum; + return shareResults; +} + +- (NSNumberFormatter *)numberFormatter +{ + if (!_numberFormatter) { + _numberFormatter = [[NSNumberFormatter alloc] init]; + _numberFormatter.numberStyle = NSNumberFormatterDecimalStyle; + } + return _numberFormatter; +} + +- (NSString *)_graphPathWithSuffix:(NSString *)suffix, ... NS_REQUIRES_NIL_TERMINATION +{ + NSMutableString *graphPath = [[NSMutableString alloc] initWithString:self.graphNode]; + va_list args; + va_start(args, suffix); + for (NSString *arg = suffix; arg != nil; arg = va_arg(args, NSString *)) { + [graphPath appendFormat:@"/%@", arg]; + } + va_end(args); + return graphPath; +} + +@end diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m index 8055131dc..432eb56ad 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m @@ -107,13 +107,11 @@ content.video = video; XCTAssertNotNil(content); NSError *error; - XCTAssertFalse([FBSDKShareUtility validateShareContent:content error:&error]); - XCTAssertNotNil(error); - XCTAssertEqual(error.code, FBSDKInvalidArgumentErrorCode); - XCTAssertEqualObjects(error.userInfo[FBSDKErrorArgumentNameKey], @"videoURL"); + XCTAssertTrue([FBSDKShareUtility validateShareContent:content error:&error]); + XCTAssertNil(error); } -- (void)testValidationWithInvalidFileVideoURL +- (void)testValidationWithValidFileVideoURL { NSURL *videoURL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:@"video.mp4"]; FBSDKShareVideo *video = [FBSDKShareVideo videoWithVideoURL:videoURL]; @@ -122,10 +120,8 @@ content.video = video; XCTAssertNotNil(content); NSError *error; - XCTAssertFalse([FBSDKShareUtility validateShareContent:content error:&error]); - XCTAssertNotNil(error); - XCTAssertEqual(error.code, FBSDKInvalidArgumentErrorCode); - XCTAssertEqualObjects(error.userInfo[FBSDKErrorArgumentNameKey], @"videoURL"); + XCTAssertTrue([FBSDKShareUtility validateShareContent:content error:&error]); + XCTAssertNil(error); } @end diff --git a/samples/Iconicus/Iconicus/Iconicus-Info.plist b/samples/Iconicus/Iconicus/Iconicus-Info.plist index f292e72c7..7a3ec4a6c 100644 --- a/samples/Iconicus/Iconicus/Iconicus-Info.plist +++ b/samples/Iconicus/Iconicus/Iconicus-Info.plist @@ -72,19 +72,19 @@ NSIncludesSubdomains - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy facebook.com - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains akamaihd.net - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains diff --git a/samples/Iconicus/Iconicus/Iconicus-Prefix.pch b/samples/Iconicus/Iconicus/Iconicus-Prefix.pch index 197df8b54..835a9264f 100644 --- a/samples/Iconicus/Iconicus/Iconicus-Prefix.pch +++ b/samples/Iconicus/Iconicus/Iconicus-Prefix.pch @@ -1,13 +1,22 @@ +// Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // -// Iconicus-Prefix.pch -// Iconicus +// You are hereby granted a non-exclusive, worldwide, royalty-free license to use, +// copy, modify, and distribute this software in source code or binary form for use +// in connection with the web services and APIs provided by Facebook. // -// Created by Todd Krabach on 3/17/15. -// Copyright (c) 2015 Facebook, Inc. All rights reserved. +// As with any software that integrates with the Facebook platform, your use of +// this software is subject to the Facebook Developer Principles and Policies +// [http://developers.facebook.com/policy/]. This copyright notice shall be +// included in all copies or substantial portions of the software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef Iconicus_Iconicus_Prefix_pch #define Iconicus_Iconicus_Prefix_pch - #endif diff --git a/samples/RPSSample/RPSSample/RPSSample-Info.plist b/samples/RPSSample/RPSSample/RPSSample-Info.plist index b08e64e75..45b8c5e5b 100644 --- a/samples/RPSSample/RPSSample/RPSSample-Info.plist +++ b/samples/RPSSample/RPSSample/RPSSample-Info.plist @@ -90,19 +90,19 @@ NSIncludesSubdomains - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy facebook.com - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains akamaihd.net - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains diff --git a/samples/Scrumptious/scrumptious/scrumptious-Info.plist b/samples/Scrumptious/scrumptious/scrumptious-Info.plist index c100ade0e..f2c226988 100644 --- a/samples/Scrumptious/scrumptious/scrumptious-Info.plist +++ b/samples/Scrumptious/scrumptious/scrumptious-Info.plist @@ -68,19 +68,19 @@ NSIncludesSubdomains - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy facebook.com - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains akamaihd.net - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains diff --git a/samples/ShareIt/ShareIt/SIMainViewController.m b/samples/ShareIt/ShareIt/SIMainViewController.m index 577b73d29..13ba5c093 100644 --- a/samples/ShareIt/ShareIt/SIMainViewController.m +++ b/samples/ShareIt/ShareIt/SIMainViewController.m @@ -32,9 +32,7 @@ @interface SIMainViewController () < MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate, - UIActionSheetDelegate, FBSDKSharingDelegate> -@property (nonatomic, strong) UIActionSheet *shareActionSheet; @end @implementation SIMainViewController @@ -63,23 +61,6 @@ ]; } -#pragma mark - Object Lifecycle - -- (void)dealloc -{ - _shareActionSheet.delegate = nil; -} - -#pragma mark - Properties - -- (void)setShareActionSheet:(UIActionSheet *)shareActionSheet -{ - if (![_shareActionSheet isEqual:shareActionSheet]) { - _shareActionSheet.delegate = nil; - _shareActionSheet = shareActionSheet; - } -} - #pragma mark - View Management - (UIStatusBarStyle)preferredStatusBarStyle @@ -98,6 +79,7 @@ self.pageLikeControl.likeControlAuxiliaryPosition = FBSDKLikeControlAuxiliaryPositionBottom; self.pageLikeControl.likeControlHorizontalAlignment = FBSDKLikeControlHorizontalAlignmentCenter; + self.pageLikeControl.foregroundColor = [UIColor whiteColor]; self.pageLikeControl.objectID = @"shareitexampleapp"; [self _configurePhotos]; @@ -107,58 +89,51 @@ - (void)share:(id)sender { - UIActionSheet *shareActionSheet = self.shareActionSheet = [[UIActionSheet alloc] initWithTitle:nil - delegate:self - cancelButtonTitle:nil - destructiveButtonTitle:nil - otherButtonTitles:nil]; + SIPhoto *photo = [self _currentPhoto]; + UIAlertController *shareAlertController = [UIAlertController alertControllerWithTitle:@"Share" + message:nil + preferredStyle:UIAlertControllerStyleAlert]; if ([MFMailComposeViewController canSendMail]) { - [shareActionSheet addButtonWithTitle:@"Mail"]; + UIAlertAction *sendMailAction = [UIAlertAction actionWithTitle:@"Mail" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [self _sendMailWithPhoto:photo]; + }]; + [shareAlertController addAction:sendMailAction]; } if ([MFMessageComposeViewController canSendAttachments]) { - [shareActionSheet addButtonWithTitle:@"Message"]; + UIAlertAction *sendMessageAction = [UIAlertAction actionWithTitle:@"Message" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [self _sendMessageWithPhoto:photo]; + }]; + [shareAlertController addAction:sendMessageAction]; } FBSDKShareDialog *facebookShareDialog = [self getShareDialogWithContentURL:[self _currentPhoto].objectURL]; if ([facebookShareDialog canShow]) { - [shareActionSheet addButtonWithTitle:@"Share on Facebook"]; + UIAlertAction *shareOnFacebookAction = [UIAlertAction actionWithTitle:@"Share on Facebook" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + [self _shareFacebookWithPhoto:photo]; + }]; + [shareAlertController addAction:shareOnFacebookAction]; } + FBSDKMessageDialog *messengerShareDialog = [self getMessageDialogWithContentURL:[self _currentPhoto].objectURL]; if ( [messengerShareDialog canShow]) { - [shareActionSheet addButtonWithTitle:@"Send with Messenger"]; + UIAlertAction *sendWithMessengerAction = [UIAlertAction actionWithTitle:@"Send with Messenger" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) { + messengerShareDialog.delegate = self; + [messengerShareDialog show]; + }]; + [shareAlertController addAction:sendWithMessengerAction]; } - [shareActionSheet addButtonWithTitle:@"Cancel"]; - shareActionSheet.cancelButtonIndex = shareActionSheet.numberOfButtons - 1; - [shareActionSheet showInView:self.view]; -} - -- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex -{ - if (_shareActionSheet != actionSheet) { - return; - } - - SIPhoto *photo = [self _currentPhoto]; - - NSString *buttonTitle = [actionSheet buttonTitleAtIndex:buttonIndex]; - if ([buttonTitle isEqualToString:@"Mail"]) { - [self _sendMailWithPhoto:photo]; - } else if ([buttonTitle isEqualToString:@"Message"]) { - [self _sendMessageWithPhoto:photo]; - } else if ([buttonTitle isEqualToString:@"Share on Facebook"]) { - FBSDKShareDialog *shareDialog = [self getShareDialogWithContentURL:photo.objectURL]; - shareDialog.delegate = self; - [shareDialog show]; - } else if ([buttonTitle isEqualToString:@"Send with Messenger"]) { - FBSDKMessageDialog *shareDialog = [self getMessageDialogWithContentURL:photo.objectURL]; - shareDialog.delegate = self; - [shareDialog show]; - } - - _shareActionSheet = nil; + [self presentViewController:shareAlertController animated:YES completion:nil]; } - (void)_sendMailWithPhoto:(SIPhoto *)photo @@ -182,6 +157,13 @@ [self presentViewController:viewController animated:YES completion:NULL]; } +- (void)_shareFacebookWithPhoto:(SIPhoto *)photo +{ + [FBSDKShareDialog showFromViewController:self.parentViewController + withContent:[self getShareLinkContentWithContentURL:photo.objectURL] + delegate:nil]; +} + - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error diff --git a/samples/ShareIt/ShareIt/ShareIt-Info.plist b/samples/ShareIt/ShareIt/ShareIt-Info.plist index 6c3a467d6..b1f1b1640 100644 --- a/samples/ShareIt/ShareIt/ShareIt-Info.plist +++ b/samples/ShareIt/ShareIt/ShareIt-Info.plist @@ -58,19 +58,19 @@ NSIncludesSubdomains - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy facebook.com - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains akamaihd.net - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains diff --git a/samples/SwitchUserSample/SwitchUserSample/SwitchUserSample-Info.plist b/samples/SwitchUserSample/SwitchUserSample/SwitchUserSample-Info.plist index feed25d22..8afdbf2af 100644 --- a/samples/SwitchUserSample/SwitchUserSample/SwitchUserSample-Info.plist +++ b/samples/SwitchUserSample/SwitchUserSample/SwitchUserSample-Info.plist @@ -91,19 +91,19 @@ NSIncludesSubdomains - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy facebook.com - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains akamaihd.net - NSExceptionRequiresForwardSecrecy + NSThirdPartyExceptionRequiresForwardSecrecy NSIncludesSubdomains diff --git a/scripts/build_distribution.sh b/scripts/build_distribution.sh index 485de255b..b83d7d40a 100755 --- a/scripts/build_distribution.sh +++ b/scripts/build_distribution.sh @@ -43,7 +43,7 @@ FB_SDK_BUILD_PACKAGE_DOCSETS_FOLDER=$FB_SDK_BUILD_PACKAGE/DocSets/ # progress_message "Building package directory structure." \rm -rf "$FB_SDK_BUILD_PACKAGE" "$FB_SDK_BUILD_PACKAGE_SCRIPTS" -mkdir "$FB_SDK_BUILD_PACKAGE" \ +mkdir -p "$FB_SDK_BUILD_PACKAGE" \ || die "Could not create directory $FB_SDK_BUILD_PACKAGE" mkdir -p "$FB_SDK_BUILD_PACKAGE_SAMPLES" mkdir -p "$FB_SDK_BUILD_PACKAGE_SCRIPTS" diff --git a/vendor/OHHTTPStubs b/vendor/OHHTTPStubs index 5a0dc9a1e..c2898353a 160000 --- a/vendor/OHHTTPStubs +++ b/vendor/OHHTTPStubs @@ -1 +1 @@ -Subproject commit 5a0dc9a1e8f3bc20f7a2571bba5bafb9906f5506 +Subproject commit c2898353ae0f57d02dca30cfb46d2f6c6d19bf04