From 5391abc1041a274b547d2ac783d377de64fa91c1 Mon Sep 17 00:00:00 2001 From: joesusnick Date: Tue, 22 Sep 2020 10:00:24 -0700 Subject: [PATCH 001/227] fbshipit-source-id: fafb217e6ccb2f8da19871a8acb4397e15d6d79e --- .../FacebookSDK-DynamicFramework.xcconfig | 2 +- .../FacebookSDK-LogicTests.xcconfig | 2 +- Configurations/FacebookSDK-Project.xcconfig | 2 +- Configurations/Platform/iOS.xcconfig | 2 +- FBSDKCoreKit.podspec | 17 +- .../FBSDKCoreKit-Dynamic.xcconfig | 2 +- .../Configurations/FBSDKCoreKitTests.xcconfig | 2 +- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 849 +++++---- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 535 +++--- .../Internal/AAM/FBSDKMetadataIndexer.h | 2 +- .../Internal/AAM/FBSDKMetadataIndexer.m | 54 +- .../Internal/Codeless/FBSDKCodelessIndexer.m | 158 +- .../FBSDKCodelessParameterComponent.m | 11 +- .../Codeless/FBSDKCodelessPathComponent.m | 8 +- .../Internal/Codeless/FBSDKEventBinding.m | 65 +- .../Codeless/FBSDKEventBindingManager.m | 121 +- .../FBSDKEventDeactivationManager.h | 1 - .../FBSDKEventDeactivationManager.m | 75 +- .../Internal/FBSDKAppEvents+Internal.h | 18 +- .../Internal/FBSDKAppEventsConfiguration.h | 46 + .../Internal/FBSDKAppEventsConfiguration.m | 105 ++ .../FBSDKAppEventsConfigurationManager.h | 36 + .../FBSDKAppEventsConfigurationManager.m | 120 ++ .../Internal/FBSDKAppEventsDeviceInfo.m | 50 +- .../AppEvents/Internal/FBSDKAppEventsState.m | 31 +- .../Internal/FBSDKAppEventsStateManager.m | 2 + .../Internal/FBSDKAppEventsUtility.h | 4 +- .../Internal/FBSDKAppEventsUtility.m | 132 +- ...FBSDKHybridAppEventsScriptMessageHandler.m | 31 +- .../AppEvents/Internal/FBSDKPaymentObserver.m | 63 +- .../AppEvents/Internal/FBSDKTimeSpentData.m | 69 +- .../Integrity/FBSDKIntegrityManager.h | 2 +- .../Integrity/FBSDKIntegrityManager.m | 13 +- .../Internal/Integrity/FBSDKRestrictiveData.m | 2 +- .../FBSDKRestrictiveDataFilterManager.m | 145 +- .../AppEvents/Internal/ML/FBSDKMLMacros.h | 4 +- .../AppEvents/Internal/ML/FBSDKModelManager.h | 2 +- .../Internal/ML/FBSDKModelManager.mm | 260 +-- .../AppEvents/Internal/ML/FBSDKModelParser.h | 4 +- .../AppEvents/Internal/ML/FBSDKModelParser.mm | 53 +- .../Internal/ML/FBSDKModelRuntime.hpp | 526 +++--- .../AppEvents/Internal/ML/FBSDKModelUtility.h | 2 +- .../AppEvents/Internal/ML/FBSDKModelUtility.m | 6 +- .../AppEvents/Internal/ML/FBSDKTensor.hpp | 171 +- .../FBSDKSKAdNetworkConversionConfiguration.h | 51 + .../FBSDKSKAdNetworkConversionConfiguration.m | 116 ++ .../SKAdNetwork/FBSDKSKAdNetworkEvent.h | 39 + .../SKAdNetwork/FBSDKSKAdNetworkEvent.m | 64 + .../SKAdNetwork/FBSDKSKAdNetworkReporter.h | 41 + .../SKAdNetwork/FBSDKSKAdNetworkReporter.m | 299 +++ .../SKAdNetwork/FBSDKSKAdNetworkRule.h | 44 + .../SKAdNetwork/FBSDKSKAdNetworkRule.m | 92 + .../SuggestedEvents/FBSDKFeatureExtractor.h | 2 +- .../SuggestedEvents/FBSDKFeatureExtractor.m | 84 +- .../FBSDKSuggestedEventsIndexer.h | 2 +- .../FBSDKSuggestedEventsIndexer.m | 65 +- .../ViewHierarchy/FBSDKViewHierarchy.m | 123 +- .../ViewHierarchy/FBSDKViewHierarchyMacros.h | 6 +- .../FBSDKCoreKit/AppLink/FBSDKAppLink.m | 39 +- .../AppLink/FBSDKAppLinkNavigation.m | 400 ++-- .../AppLink/FBSDKAppLinkResolver.m | 48 +- .../FBSDKAppLinkReturnToRefererController.m | 347 ++-- .../AppLink/FBSDKAppLinkReturnToRefererView.m | 372 ++-- .../FBSDKCoreKit/AppLink/FBSDKAppLinkTarget.m | 15 +- .../AppLink/FBSDKAppLinkUtility.m | 81 +- .../AppLink/FBSDKWebViewAppLinkResolver.m | 2 +- .../Internal/FBSDKMeasurementEventListener.m | 84 +- .../Basics/FBSDKCoreKit.modulemap | 6 - FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m | 76 +- .../FBSDKCoreKit/FBSDKApplicationDelegate.m | 165 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m | 78 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m | 1 - FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 134 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceButton.m | 52 +- .../FBSDKDeviceViewControllerBase.m | 22 +- .../FBSDKCoreKit/FBSDKMeasurementEvent.m | 67 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 105 +- .../FBSDKCoreKit/FBSDKProfilePictureView.h | 12 + .../FBSDKCoreKit/FBSDKProfilePictureView.m | 51 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h | 19 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m | 260 ++- .../FBSDKCoreKit/FBSDKTestUsersManager.m | 75 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKURL.m | 233 +-- FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m | 43 +- .../FBSDKGraphErrorRecoveryProcessor.m | 36 +- .../FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m | 51 +- .../GraphAPI/FBSDKGraphRequestConnection.m | 337 ++-- .../Internal/Base64/FBSDKBase64.m | 2 +- .../BridgeAPI/FBSDKBridgeAPI+Internal.h | 31 + .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 139 +- .../BridgeAPI/FBSDKBridgeAPIRequest+Private.h | 8 +- .../BridgeAPI/FBSDKBridgeAPIRequest.m | 46 +- .../BridgeAPI/FBSDKBridgeAPIResponse.m | 23 +- .../FBSDKBridgeAPIProtocolNativeV1.m | 93 +- .../FBSDKBridgeAPIProtocolWebV1.m | 35 +- .../FBSDKBridgeAPIProtocolWebV2.m | 22 +- .../Device/FBSDKDeviceButton+Internal.h | 12 +- .../Internal/Device/FBSDKDeviceDialogView.m | 42 +- .../Internal/Device/FBSDKDeviceUtilities.m | 8 +- .../FBSDKDeviceViewControllerBase+Internal.h | 24 +- .../FBSDKModalFormPresentationController.m | 25 +- .../Device/FBSDKSmartDeviceDialogView.m | 68 +- .../FBSDKErrorRecoveryAttempter.m | 5 +- .../_FBSDKTemporaryErrorRecoveryAttempter.m | 6 +- .../Internal/FBSDKAccessToken+Internal.h | 32 + ...FBSDKAppLinkReturnToRefererView_Internal.h | 2 +- .../Internal/FBSDKAppLink_Internal.h | 4 +- .../FBSDKApplicationDelegate+Internal.h | 6 +- .../Internal/FBSDKApplicationObserving.h | 5 +- .../Internal/FBSDKAudioResourceLoader.h | 8 +- .../Internal/FBSDKAudioResourceLoader.m | 20 +- .../Internal/FBSDKContainerViewController.m | 2 +- .../Internal/FBSDKCoreKit+Internal.h | 283 ++- .../Internal/FBSDKDeviceRequestsHelper.m | 43 +- .../FBSDKCoreKit/Internal/FBSDKError.m | 3 +- .../Internal/FBSDKFeatureManager.h | 3 + .../Internal/FBSDKFeatureManager.m | 15 +- .../Internal/FBSDKImageDownloader.m | 27 +- .../Internal/FBSDKInternalUtility.m | 89 +- .../FBSDKCoreKit/Internal/FBSDKLogger.m | 33 +- .../FBSDKCoreKit/Internal/FBSDKMath.m | 10 +- .../Internal/FBSDKMeasurementEvent_Internal.h | 2 +- .../Internal/FBSDKMonotonicTime.h | 2 +- .../Internal/FBSDKMonotonicTime.m | 71 +- .../Internal/FBSDKProfile+Internal.h | 4 +- .../Internal/FBSDKSettings+Internal.h | 28 +- .../FBSDKCoreKit/Internal/FBSDKSwizzler.m | 146 +- .../FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m | 8 +- .../FBSDKCoreKit/Internal/FBSDKURL_Internal.h | 2 +- .../CrashReport/FBSDKCrashObserver.h | 4 +- .../CrashReport/FBSDKCrashObserver.m | 3 - .../Instrument/CrashReport/FBSDKCrashShield.m | 55 +- .../Instrument/ErrorReport/FBSDKErrorReport.h | 1 + .../Instrument/ErrorReport/FBSDKErrorReport.m | 29 +- .../Monitoring/FBSDKMethodUsageMonitorEntry.h | 2 +- .../Monitoring/FBSDKMethodUsageMonitorEntry.m | 9 +- .../Internal/Monitoring/FBSDKMonitor.m | 4 +- .../Internal/Monitoring/FBSDKMonitorHeaders.h | 2 +- .../Monitoring/FBSDKMonitorNetworker.m | 16 +- .../Internal/Monitoring/FBSDKMonitorStore.m | 8 +- .../Monitoring/FBSDKMonitoringConfiguration.h | 2 +- .../Monitoring/FBSDKMonitoringConfiguration.m | 13 +- .../Monitoring/FBSDKPerformanceMonitor.m | 1 + .../Monitoring/FBSDKPerformanceMonitorEntry.h | 2 +- .../Monitoring/FBSDKPerformanceMonitorEntry.m | 24 +- .../Network/FBSDKGraphRequest+Internal.h | 9 +- .../FBSDKGraphRequestConnection+Internal.h | 13 +- .../Network/FBSDKGraphRequestMetadata.m | 7 +- .../FBSDKGraphRequestPiggybackManager.m | 43 +- .../FBSDKErrorConfiguration.m | 107 +- .../FBSDKErrorRecoveryConfiguration.m | 5 +- .../FBSDKGateKeeperManager.m | 100 +- .../FBSDKServerConfiguration+Internal.h | 1 + .../FBSDKServerConfiguration.m | 141 +- .../FBSDKServerConfigurationManager.m | 307 +-- .../TokenCaching/FBSDKAccessTokenCache.m | 8 +- .../TokenCaching/FBSDKKeychainStore.m | 19 +- .../FBSDKKeychainStoreViaBundleID.m | 2 +- .../FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m | 14 +- .../FBSDKCoreKit/Internal/UI/FBSDKColor.h | 2 +- .../FBSDKCoreKit/Internal/UI/FBSDKColor.m | 6 +- .../FBSDKCoreKit/Internal/UI/FBSDKLogo.m | 82 +- .../Internal/UI/FBSDKMaleSilhouetteIcon.m | 2 +- .../FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h | 18 +- .../Internal/UI/FBSDKViewImpressionTracker.m | 2 +- .../Internal/WebDialog/FBSDKWebDialog.m | 71 +- .../Internal/WebDialog/FBSDKWebDialogView.m | 70 +- .../FBSDKDynamicFrameworkLoader.m | 42 +- FBSDKCoreKit/FBSDKCoreKit/Swift/Imports.swift | 19 + .../FBSDKAppLinkUtilityTests.m | 4 +- .../FBSDKApplicationDelegateTests.m | 349 +++- .../FBSDKCoreKitTestUtility.h | 11 + .../FBSDKGraphRequestConnectionTests.m | 442 ++--- .../FBSDKGraphRequestTests.m | 67 +- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 342 ++++ .../FBSDKCoreKitTests/FBSDKUtilityTests.m | 28 +- FBSDKCoreKit/FBSDKCoreKitTests/Info.plist | 19 +- .../AppEvents/AAM/FBSDKMetadataIndexerTests.m | 110 +- .../Codeless/FBSDKEventBindingTests.m | 27 +- .../Codeless/FBSDKSampleEventBinding.h | 2 +- .../Codeless/FBSDKSampleEventBinding.m | 231 +-- .../FBSDKEventDeactivationTests.m | 11 +- .../FBSDKAppEventsConfigurationFixtures.h | 36 + .../FBSDKAppEventsConfigurationFixtures.m | 61 + .../FBSDKAppEventsConfigurationManagerTests.m | 47 + .../FBSDKAppEventsConfigurationTests.m | 95 + .../AppEvents/FBSDKAppEventsStateTests.m | 467 ++++- .../Internal/AppEvents/FBSDKAppEventsTests.m | 459 +++-- .../AppEvents/FBSDKAppEventsUtilityTests.m | 92 +- .../AppEvents/FBSDKPaymentObserverTests.m | 7 +- .../AppEvents/FBSDKTimeSpentDataTests.m | 3 +- .../AppEvents/Integrity/FBSDKIntegrityTests.m | 14 +- .../FBSDKRestrictiveDataFilterTests.m | 77 +- .../Integrity/FBSDKRestrictiveDataTests.m | 2 +- .../AppEvents/ML/FBSDKModelParserTests.mm | 22 +- .../AppEvents/ML/FBSDKModelRuntimeTests.mm | 74 +- ...pEventsConfigurationResponseFixtures.swift | 39 + ...KSKAdNetworkConversionConfigurationTests.m | 385 ++++ .../SKAdNetwork/FBSDKSKAdNetworkEventTests.m | 103 + .../FBSDKSKAdNetworkReporterTests.m | 221 +++ .../SKAdNetwork/FBSDKSKAdNetworkRuleTests.m | 170 ++ .../FBSDKFeatureExtractorTests.m | 338 ++-- .../ViewHierarchy/FBSDKViewHierarchyTests.m | 36 +- .../AppLinks/FBSDKAppLinkResolverTests.m | 39 +- .../Internal/Base64/FBSDKBase64Tests.m | 25 +- .../Internal/Basics/FBSDKBasicUtilityTests.m | 16 +- .../Internal/Basics/FBSDKCrashHandlerTests.m | 52 +- .../Internal/Basics/FBSDKLibAnalyzerTests.m | 6 +- .../Internal/Basics/FBSDKSafeCastTests.m | 51 +- .../Internal/Basics/FBSDKTypeUtilityTests.m | 85 +- .../FBSDKBridgeAPIProtocolNativeV1Tests.m | 276 +-- .../Internal/FBSDKErrorConfigurationTests.m | 99 +- .../Internal/FBSDKInternalUtilityTests.m | 10 +- .../Internal/FBSDKJSONValueTests.m | 137 ++ .../Internal/FBSDKSettingsTests.m | 1668 ++++++++++++++++- .../Helpers/AppDelegateObserverFake.h | 32 + .../Helpers/AppDelegateObserverFake.m | 40 + .../FBSDKMonitoringConfigurationTestHelper.h | 12 +- .../FBSDKMonitoringConfigurationTestHelper.m | 4 +- .../Internal/Helpers/FBSDKTestCase.h | 186 ++ .../Internal/Helpers/FBSDKTestCase.m | 356 ++++ .../Internal/Helpers/FakeAccessTokenCache.h | 31 + .../Internal/Helpers/FakeAccessTokenCache.m | 49 + .../Internal/Helpers/FakeBundle.h | 31 + .../Internal/Helpers/FakeBundle.m | 52 + .../Helpers/KeychainStoreSpy.h} | 18 +- .../Internal/Helpers/KeychainStoreSpy.m | 41 + .../Internal/Helpers/NotificationCenterSpy.h | 27 + .../Internal/Helpers/NotificationCenterSpy.m | 28 + .../Internal/Helpers/SampleAccessToken.h | 31 + .../Internal/Helpers/SampleAccessToken.m | 36 + .../Internal/Helpers/SampleAppEvents.h | 32 + .../Internal/Helpers/SampleAppEvents.m | 38 + .../Internal/Helpers/SampleUserProfile.h | 31 + .../Internal/Helpers/SampleUserProfile.m | 34 + .../Internal/Helpers/UserDefaultsSpy.h | 30 + .../Internal/Helpers/UserDefaultsSpy.m | 59 + .../Instrument/FBSDKCrashObserverTests.m | 9 +- .../Instrument/FBSDKCrashShieldTests.m | 5 +- .../FBSDKMethodUsageMonitorEntryTests.m | 38 +- .../Monitoring/FBSDKMethodUsageMonitorTests.m | 10 +- .../FBSDKMonitorConfigurationTests.m | 134 +- .../Monitoring/FBSDKMonitorNetworkerTests.m | 94 +- .../Monitoring/FBSDKMonitorStoreTests.m | 76 +- .../Internal/Monitoring/FBSDKMonitorTests.m | 291 ++- .../FBSDKPerformanceMonitorEntryTests.m | 73 +- .../Monitoring/FBSDKPerformanceMonitorTests.m | 32 +- .../Internal/Monitoring/TestMonitorEntry.h | 2 +- .../Internal/Monitoring/TestMonitorEntry.m | 1 - .../FBSDKServerConfigurationManagerTests.m | 2 +- .../FBSDKServerConfigurationTests.m | 662 ++++--- FBSDKGamingServicesKit.podspec | 2 +- .../project.pbxproj | 287 ++- .../FBSDKGamingServicesKit-Dynamic.xcscheme | 13 +- .../FBSDKGamingServicesKitTests.xcscheme | 53 + .../FBSDKFriendFinderDialog.m | 22 +- .../FBSDKGamingGroupIntegration.m | 12 +- .../FBSDKGamingImageUploader.m | 108 +- .../FBSDKGamingImageUploaderConfiguration.m | 4 +- .../FBSDKGamingServicesKit.h | 29 +- .../FBSDKGamingVideoUploader.m | 74 +- .../FBSDKGamingVideoUploaderConfiguration.m | 4 +- .../Internal/FBSDKCoreKitInternalImport.h | 26 + .../Internal/FBSDKGamingServiceController.h | 3 +- .../Internal/FBSDKGamingServiceController.m | 55 +- .../FBSDKFriendFinderDialogTests.m | 65 +- .../FBSDKGamingImageUploaderTests.m | 157 +- .../FBSDKGamingServicesKitTestUtility.m | 10 +- .../FBSDKGamingVideoUploaderTests.m | 95 +- FBSDKLoginKit.podspec | 2 +- .../FBSDKLoginKit-Dynamic.xcconfig | 2 +- .../FBSDKLoginKitTests.xcconfig | 2 +- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 56 + .../FBSDKLoginKit/FBSDKCoreKitImport.h | 4 +- .../FBSDKLoginKit/FBSDKDeviceLoginCodeInfo.m | 9 +- .../FBSDKLoginKit/FBSDKDeviceLoginManager.m | 125 +- .../FBSDKLoginKit/FBSDKLoginButton.m | 127 +- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h | 10 +- .../FBSDKLoginKit/FBSDKLoginManager.h | 11 + .../FBSDKLoginKit/FBSDKLoginManager.m | 164 +- .../FBSDKLoginManagerLoginResult.m | 21 +- .../FBSDKLoginKit/FBSDKLoginTooltipView.m | 24 +- .../FBSDKLoginKit/FBSDKReferralCode.h | 52 + .../FBSDKLoginKit/FBSDKReferralCode.m | 64 + .../FBSDKLoginKit/FBSDKReferralManager.h | 60 + .../FBSDKLoginKit/FBSDKReferralManager.m | 241 +++ .../FBSDKReferralManagerResult.h | 59 + .../FBSDKReferralManagerResult.m | 40 + .../FBSDKLoginKit/FBSDKTooltipView.m | 243 ++- .../FBSDKDeviceLoginManagerResult+Internal.h | 2 +- .../Internal/FBSDKLoginCompletion+Internal.h | 10 +- .../Internal/FBSDKLoginCompletion.m | 129 +- .../FBSDKLoginKit/Internal/FBSDKLoginError.h | 8 +- .../FBSDKLoginKit/Internal/FBSDKLoginError.m | 86 +- .../Internal/FBSDKLoginKit+Internal.h | 1 - .../Internal/FBSDKLoginManager+Internal.h | 24 + .../Internal/FBSDKLoginManagerLogger.h | 1 + .../Internal/FBSDKLoginManagerLogger.m | 89 +- .../FBSDKLoginManagerLoginResult+Internal.h | 8 +- .../Internal/FBSDKLoginUtility.h | 6 +- .../Internal/FBSDKLoginUtility.m | 22 +- .../Internal/FBSDKReferralManager+Internal.h | 35 + .../Internal/FBSDKReferralManagerLogger.h | 34 + .../Internal/FBSDKReferralManagerLogger.m | 174 ++ .../Internal/_FBSDKLoginRecoveryAttempter.h | 10 +- .../Internal/_FBSDKLoginRecoveryAttempter.m | 10 +- .../FBSDKLoginKit/include/FBSDKReferralCode.h | 1 + .../include/FBSDKReferralManager.h | 1 + .../include/FBSDKReferralManagerResult.h | 1 + .../FBSDKLoginManagerTests.m | 197 +- .../FBSDKReferralCodeTests.m | 72 + .../FBSDKReferralManagerTests.m | 311 +++ FBSDKMarketingKit.podspec | 45 - FBSDKShareKit.podspec | 5 +- .../FBSDKShareKit-Dynamic.xcconfig | 2 +- .../FBSDKShareKitTests.xcconfig | 2 +- .../FBSDKShareKit.xcodeproj/project.pbxproj | 18 +- .../FBSDKShareKit/FBSDKAppGroupContent.m | 36 +- .../FBSDKShareKit/FBSDKAppInviteContent.m | 63 +- .../FBSDKCameraEffectArguments.m | 25 +- .../FBSDKShareKit/FBSDKCameraEffectTextures.m | 24 +- .../FBSDKShareKit/FBSDKCoreKitImport.h | 4 +- .../FBSDKShareKit/FBSDKDeviceShareButton.h | 1 + .../FBSDKShareKit/FBSDKDeviceShareButton.m | 32 +- .../FBSDKDeviceShareViewController.h | 2 + .../FBSDKDeviceShareViewController.m | 32 +- .../FBSDKShareKit/FBSDKGameRequestContent.m | 74 +- .../FBSDKShareKit/FBSDKGameRequestDialog.m | 67 +- FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m | 12 +- .../FBSDKShareKit/FBSDKMessageDialog.m | 83 +- FBSDKShareKit/FBSDKShareKit/FBSDKSendButton.m | 44 +- .../FBSDKShareKit/FBSDKShareButton.m | 32 +- .../FBSDKShareCameraEffectContent.m | 84 +- .../FBSDKShareKit/FBSDKShareDialog.m | 253 ++- .../FBSDKShareKit/FBSDKShareDialogMode.m | 18 +- FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h | 31 +- .../FBSDKShareKit/FBSDKShareLinkContent.m | 22 +- .../FBSDKShareKit/FBSDKShareMediaContent.m | 23 +- FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m | 16 +- .../FBSDKShareKit/FBSDKSharePhotoContent.m | 26 +- FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m | 14 +- .../FBSDKShareKit/FBSDKShareVideoContent.m | 50 +- .../FBSDKCameraEffectArguments+Internal.h | 2 +- .../FBSDKCameraEffectTextures+Internal.h | 2 +- .../Internal/FBSDKCheckmarkIcon.m | 2 +- .../Internal/FBSDKCoreKitInternalImport.h | 26 + ...SDKGameRequestFrictionlessRecipientCache.m | 32 +- .../Internal/FBSDKLikeActionController.m | 493 ++--- .../Internal/FBSDKLikeActionControllerCache.m | 38 +- .../Internal/FBSDKLikeBoxBorderView.m | 120 +- .../FBSDKShareKit/Internal/FBSDKLikeBoxView.m | 22 +- .../Internal/FBSDKLikeButton+Internal.h | 8 +- .../FBSDKShareKit/Internal/FBSDKLikeDialog.m | 64 +- .../Internal/FBSDKMessengerIcon.m | 2 +- .../Internal/FBSDKShareExtension.h | 2 +- .../Internal/FBSDKShareExtension.m | 2 +- .../Internal/FBSDKShareKit+Internal.h | 3 +- .../Internal/FBSDKShareUtility.m | 54 +- .../Internal/FBSDKVideoUploader.m | 76 +- .../FBSDKMessageDialogTests.m | 126 +- .../FBSDKShareDialogTests.m | 270 ++- .../FBSDKShareKitTestUtility.m | 5 +- .../FBSDKShareKitTests/FakeSharingDelegate.h | 2 +- .../FBSDKShareKitTests/FakeSharingDelegate.m | 9 +- .../Internal/FBSDKShareUtilityTests.m | 2 +- .../Models/FBSDKAppInviteContentTests.m | 2 +- .../Models/FBSDKCameraEffectArgumentsTests.m | 10 +- .../Models/FBSDKGameRequestContentTests.m | 4 +- .../Models/FBSDKShareLinkContentTests.m | 21 +- .../Models/FBSDKShareModelTestUtility.m | 28 +- .../Models/FBSDKSharePhotoContentTests.m | 8 +- .../Models/FBSDKSharePhotoTests.m | 10 +- .../Models/FBSDKShareVideoContentTests.m | 34 +- .../Models/FBSDKShareVideoTests.m | 2 +- .../Configurations/FBSDKTVOSKitTests.xcconfig | 2 +- .../FBSDKTVOSKit/FBSDKDeviceLoginButton.m | 115 +- .../FBSDKDeviceLoginViewController.m | 80 +- FBSDKTVOSKit/FBSDKTVOSKit/FBSDKJS.m | 3 +- .../FBSDKTVOSKit/FBSDKTVInterfaceFactory.m | 12 +- .../FBSDKTVOSKit/FBSDKTVLoginButtonElement.m | 6 +- .../FBSDKTVLoginViewControllerElement.m | 2 +- FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h | 4 +- .../FBSDKTVOSKitTests/FBSDKTVOSKitTests.m | 7 +- Package.swift | 12 +- .../FBSDKCoreKit_Basics}/FBSDKBasicUtility.m | 62 +- .../FBSDKCoreKit_Basics}/FBSDKCrashHandler.m | 124 +- Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.m | 232 +++ .../FBSDKCoreKit_Basics}/FBSDKLibAnalyzer.m | 19 +- .../FBSDKCoreKit_Basics}/FBSDKSafeCast.m | 0 .../FBSDKCoreKit_Basics}/FBSDKTypeUtility.m | 21 +- .../FBSDKCoreKit_Basics}/FBSDKURLSession.m | 0 .../FBSDKURLSessionTask.m | 0 .../FBSDKCoreKit_Basics}/FBSDKUserDataStore.m | 41 +- .../include}/FBSDKBasicUtility.h | 1 + .../include/FBSDKCoreKit_Basics.h | 41 + .../include}/FBSDKCrashHandler.h | 0 .../include}/FBSDKCrashObserving.h | 2 +- .../include/FBSDKJSONValue.h | 112 ++ .../include}/FBSDKLibAnalyzer.h | 4 +- .../include}/FBSDKSafeCast.h | 0 .../include}/FBSDKTypeUtility.h | 0 .../include}/FBSDKURLSession.h | 6 +- .../include}/FBSDKURLSessionTask.h | 0 .../include}/FBSDKUserDataStore.h | 36 +- samples/Configurations/Project.xcconfig | 2 +- .../project.pbxproj | 31 +- .../project.pbxproj | 31 +- samples/RPSSample/RPSSample/RPSAppDelegate.h | 6 +- samples/RPSSample/RPSSample/RPSAppDelegate.m | 112 +- .../RPSSample/RPSAppLinkedViewController.m | 75 +- .../RPSAutoAppLinkBasicViewController.m | 76 +- .../RPSSample/RPSAutoAppLinkDebugTool.m | 144 +- .../RPSAutoAppLinkStoryboardViewController.h | 1 - .../RPSAutoAppLinkStoryboardViewController.m | 32 +- samples/RPSSample/RPSSample/RPSCoffee.h | 2 +- samples/RPSSample/RPSSample/RPSCoffee.m | 14 +- .../RPSSample/RPSSample/RPSCommonObjects.h | 9 +- .../RPSSample/RPSSample/RPSCommonObjects.m | 7 +- .../RPSSample/RPSFriendsViewController.h | 6 +- .../RPSSample/RPSFriendsViewController.m | 443 ++--- .../RPSSample/RPSGameViewController.h | 26 +- .../RPSSample/RPSGameViewController.m | 1092 +++++------ .../RPSSample/RPSRootViewController.h | 2 +- .../RPSSample/RPSRootViewController.m | 40 +- samples/RPSSample/RPSSample/main.m | 6 +- 425 files changed, 19963 insertions(+), 9554 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.m create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.m create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.m create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.m create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.m delete mode 100644 FBSDKCoreKit/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI+Internal.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAccessToken+Internal.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Swift/Imports.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/RawAppEventsConfigurationResponseFixtures.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkReporterTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m rename FBSDKCoreKit/FBSDKCoreKitTests/{ExampleSwiftTests.swift => Internal/Helpers/KeychainStoreSpy.h} (84%) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m create mode 100644 FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/xcshareddata/xcschemes/FBSDKGamingServicesKitTests.xcscheme create mode 100644 FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKCoreKitInternalImport.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.m create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.m create mode 120000 FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralCode.h create mode 120000 FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManager.h create mode 120000 FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManagerResult.h create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m delete mode 100644 FBSDKMarketingKit.podspec create mode 100644 FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCoreKitInternalImport.h rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics}/FBSDKBasicUtility.m (87%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument => Sources/FBSDKCoreKit_Basics}/FBSDKCrashHandler.m (82%) create mode 100644 Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.m rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument => Sources/FBSDKCoreKit_Basics}/FBSDKLibAnalyzer.m (95%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics}/FBSDKSafeCast.m (100%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics}/FBSDKTypeUtility.m (90%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics}/FBSDKURLSession.m (100%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics}/FBSDKURLSessionTask.m (100%) rename {FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal => Sources/FBSDKCoreKit_Basics}/FBSDKUserDataStore.m (88%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics/include}/FBSDKBasicUtility.h (98%) create mode 100644 Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument => Sources/FBSDKCoreKit_Basics/include}/FBSDKCrashHandler.h (100%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument => Sources/FBSDKCoreKit_Basics/include}/FBSDKCrashObserving.h (95%) create mode 100644 Sources/FBSDKCoreKit_Basics/include/FBSDKJSONValue.h rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument => Sources/FBSDKCoreKit_Basics/include}/FBSDKLibAnalyzer.h (95%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics/include}/FBSDKSafeCast.h (100%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics/include}/FBSDKTypeUtility.h (100%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics/include}/FBSDKURLSession.h (89%) rename {FBSDKCoreKit/FBSDKCoreKit/Basics/Internal => Sources/FBSDKCoreKit_Basics/include}/FBSDKURLSessionTask.h (100%) rename {FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal => Sources/FBSDKCoreKit_Basics/include}/FBSDKUserDataStore.h (61%) diff --git a/Configurations/FacebookSDK-DynamicFramework.xcconfig b/Configurations/FacebookSDK-DynamicFramework.xcconfig index 8da434c645..245074f43a 100644 --- a/Configurations/FacebookSDK-DynamicFramework.xcconfig +++ b/Configurations/FacebookSDK-DynamicFramework.xcconfig @@ -17,7 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // Deployment -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 // Cocoa Touch Framework MACH_O_TYPE = mh_dylib diff --git a/Configurations/FacebookSDK-LogicTests.xcconfig b/Configurations/FacebookSDK-LogicTests.xcconfig index 1a381c8f49..44539f729b 100644 --- a/Configurations/FacebookSDK-LogicTests.xcconfig +++ b/Configurations/FacebookSDK-LogicTests.xcconfig @@ -28,4 +28,4 @@ WRAPPER_EXTENSION = xctest OTHER_LDFLAGS = -all_load -lc++ ENABLE_BITCODE = YES -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 diff --git a/Configurations/FacebookSDK-Project.xcconfig b/Configurations/FacebookSDK-Project.xcconfig index 7b35492bdd..52f3d102ee 100644 --- a/Configurations/FacebookSDK-Project.xcconfig +++ b/Configurations/FacebookSDK-Project.xcconfig @@ -18,7 +18,7 @@ // Architectures ARCHS = i386 armv7 x86_64 arm64 -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 SDKROOT = iphoneos // Build Options diff --git a/Configurations/Platform/iOS.xcconfig b/Configurations/Platform/iOS.xcconfig index 8b4c14958e..cc1c5b2705 100644 --- a/Configurations/Platform/iOS.xcconfig +++ b/Configurations/Platform/iOS.xcconfig @@ -17,7 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SDKROOT = iphoneos -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 // Supported device families (1 is iPhone, 2 is iPad, 3 is Apple TV) TARGETED_DEVICE_FAMILY = 1,2 diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index 107bdcf089..8765ef6095 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.author = 'Facebook' s.platform = :ios, :tvos - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '9.0' s.tvos.deployment_target = '10.0' s.source = { @@ -26,14 +26,14 @@ Pod::Spec.new do |s| tag: "v#{s.version}" } - s.ios.weak_frameworks = 'Accelerate', 'Accounts', 'Social', 'Security', 'QuartzCore', 'CoreGraphics', 'UIKit', 'Foundation', 'AudioToolbox' + s.ios.weak_frameworks = 'Accelerate', 'Accounts', 'Social', 'Security', 'StoreKit', 'QuartzCore', 'CoreGraphics', 'UIKit', 'Foundation', 'AudioToolbox' s.tvos.weak_frameworks = 'CoreLocation', 'Security', 'QuartzCore', 'CoreGraphics', 'UIKit', 'Foundation', 'AudioToolbox' # This excludes `FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/` folder, as that folder includes only `no-arc` files. s.requires_arc = ['FBSDKCoreKit/FBSDKCoreKit/*', 'FBSDKCoreKit/FBSDKCoreKit/AppEvents/**/*', 'FBSDKCoreKit/FBSDKCoreKit/AppLink/**/*', - 'FBSDKCoreKit/FBSDKCoreKit/Basics/**/*', + 'Sources/FBSDKCoreKit_Basics/**/*', 'FBSDKCoreKit/FBSDKCoreKit/GraphAPI/*', 'FBSDKCoreKit/FBSDKCoreKit/Internal/**/*'] @@ -47,20 +47,13 @@ Pod::Spec.new do |s| s.library = 'c++', 'stdc++' s.subspec 'Basics' do |ss| - ss.source_files = 'FBSDKCoreKit/FBSDKCoreKit/Basics/*.{h,m}', - 'FBSDKCoreKit/FBSDKCoreKit/Basics/**/*.{h,m}' - ss.public_header_files = 'FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/**/*.h', - 'FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/**/*.h', - 'FBSDKCoreKit/FBSDKCoreKit/Basics/*.h' - ss.private_header_files = 'FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/**/*.h', - 'FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/**/*.h' + ss.source_files = 'Sources/FBSDKCoreKit_Basics/**/*.{h,m}' ss.library = 'z' end s.subspec 'Core' do |ss| ss.dependency 'FBSDKCoreKit/Basics' - ss.exclude_files = 'FBSDKCoreKit/FBSDKCoreKit/Basics/*', - 'FBSDKCoreKit/FBSDKCoreKit/Basics/**/*.{h,m}', + ss.exclude_files = 'Sources/FBSDKCoreKit_Basics/**/*', 'FBSDKCoreKit/FBSDKCoreKit/include/**/*', 'FBSDKCoreKit/FBSDKCoreKit/Swift/Exports.swift' ss.source_files = 'FBSDKCoreKit/FBSDKCoreKit/**/*.{h,hpp,m,mm,swift}' diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit-Dynamic.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit-Dynamic.xcconfig index 339bfaf634..0e521e6cca 100644 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKit-Dynamic.xcconfig +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKit-Dynamic.xcconfig @@ -28,4 +28,4 @@ CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist MODULEMAP_FILE = $(SRCROOT)/FBSDKCoreKit/FBSDKCoreKit.modulemap -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig index 87fe289f18..d7205af39b 100644 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig @@ -24,7 +24,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKitTests INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKitTests/Info.plist -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 HEADER_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) LIBRARY_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 914b0ca430..4226b310a3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -67,6 +67,7 @@ 0384CED0208E606A0013D404 /* FBSDKAccessTokenExpirer.m in Sources */ = {isa = PBXBuildFile; fileRef = 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */; }; 0384CED1208E606B0013D404 /* FBSDKAccessTokenExpirer.m in Sources */ = {isa = PBXBuildFile; fileRef = 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */; }; 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */; }; + 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */; }; 4AF47CF31F42468E00A57A67 /* FBSDKDeviceUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */; }; 4AF47CF41F42468E00A57A67 /* FBSDKDeviceUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */; }; 4AF47CF51F42468E00A57A67 /* FBSDKDeviceUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF47CF21F42468D00A57A67 /* FBSDKDeviceUtilities.h */; }; @@ -74,13 +75,6 @@ 4AF47D131F424A8700A57A67 /* CoreImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AF47CFE1F424A8700A57A67 /* CoreImage.framework */; }; 520223F71D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */; }; 520223F81D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 520223F61D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m */; }; - 5263EDBE215D97ED00FAAB0C /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F9169B822155A02000FA1789 /* FBSDKUserDataStore.h */; }; - 5263EDD7215D98A400FAAB0C /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F9169B822155A02000FA1789 /* FBSDKUserDataStore.h */; }; - 5263EDD8215D98B000FAAB0C /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */; }; - 5263EDD9215D98BC00FAAB0C /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F9169B822155A02000FA1789 /* FBSDKUserDataStore.h */; }; - 5263EDDA215D98BD00FAAB0C /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F9169B822155A02000FA1789 /* FBSDKUserDataStore.h */; }; - 5263EDDB215D98C100FAAB0C /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */; }; - 5263EDDC215D98C200FAAB0C /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */; }; 52963A76215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */ = {isa = PBXBuildFile; fileRef = 52963A65215992F000C7B252 /* FBSDKAppLinkReturnToRefererView.m */; }; 52963A77215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */ = {isa = PBXBuildFile; fileRef = 52963A65215992F000C7B252 /* FBSDKAppLinkReturnToRefererView.m */; }; 52963A7A215992F400C7B252 /* FBSDKAppLinkTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = 52963A67215992F000C7B252 /* FBSDKAppLinkTarget.m */; }; @@ -143,10 +137,6 @@ 5D4360E123219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4360DF23219F8E00254DF7 /* FBSDKCrashObserver.m */; }; 5D4360E223219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4360DF23219F8E00254DF7 /* FBSDKCrashObserver.m */; }; 5D4360E323219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D4360DF23219F8E00254DF7 /* FBSDKCrashObserver.m */; }; - 5D4361152321C30400254DF7 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D4361162321C30400254DF7 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D4361172321C30400254DF7 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D4361182321C30400254DF7 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; 5D497702244A3E6A00BD45C6 /* FBSDKIntegrityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D497701244A3E6A00BD45C6 /* FBSDKIntegrityTests.m */; }; 5D59BFFD23A705010008CA5A /* FBSDKCrashHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D59BFFC23A705010008CA5A /* FBSDKCrashHandlerTests.m */; }; 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D59BFFE23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m */; }; @@ -171,42 +161,6 @@ 5D90CDE72343D4D200AF326A /* FBSDKCrashShield.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */; }; 5D90CDE82343D4D200AF326A /* FBSDKCrashShield.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */; }; 5D90CDE92343D4D200AF326A /* FBSDKCrashShield.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */; }; - 5D9A703A23261D4A00BF9783 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D9A703B23261D4B00BF9783 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D9A703C23261D4C00BF9783 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D9A703D23261D4D00BF9783 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */; }; - 5D9A704323261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704423261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704523261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704623261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704723261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704823261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704923261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704A23261D6900BF9783 /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */; }; - 5D9A704C23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A704D23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A704E23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A704F23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A705023261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A705123261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A705223261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A705323261D6900BF9783 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */; }; - 5D9A705523261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705623261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705723261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705823261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705923261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705A23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705B23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705C23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */; }; - 5D9A705E23261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A705F23261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A706023261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A706123261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A706223261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A706323261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A706423261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; - 5D9A706523261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */; }; 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB01F023A1831A005495FB /* FBSDKCrashObserverTests.m */; }; 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.m */; }; 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB612A723593AB600150851 /* FBSDKCrashShieldTests.m */; }; @@ -223,10 +177,6 @@ 5DBC72D22373793400A9D859 /* FBSDKModelManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBC72D02373792A00A9D859 /* FBSDKModelManager.h */; }; 5DBC72D82373795600A9D859 /* FBSDKModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */; }; 5DBC72D92373795600A9D859 /* FBSDKModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */; }; - 5DEF22CF226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - 5DEF22D0226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - 5DEF22D1226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - 5DEF22D2226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; 5F7063FB1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */; }; 5F7064091AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */; }; 7E253D811A8EAEF500CCCFE7 /* FBSDKInternalUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 893F44A51A6445C1001DB0B6 /* FBSDKInternalUtilityTests.m */; }; @@ -727,6 +677,7 @@ 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 */; }; + B3C20ACD250B100F00DEC008 /* FBSDKAccessToken+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */; }; BF1C64E624039AD50052C580 /* FBSDKViewHierarchyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1C64E524039AD50052C580 /* FBSDKViewHierarchyTests.m */; }; BF247C822374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = BF247C802374E1B100A522C0 /* FBSDKSuggestedEventsIndexer.h */; }; BF247C832374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = BF247C812374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m */; }; @@ -791,33 +742,22 @@ C5696FA8209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; C5696FA9209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; C5696FAA209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; - C5C4B3BA2276B54B00CA3706 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - C5C4B3C22276B67200CA3706 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - C5C4B3E82276B88600CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; - C5C4B3E92276B88600CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; - C5C4B3EA2276B88600CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; - C5C4B3EB2276B88600CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; - C5C4B3EC2276B88600CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; - C5C4B3ED2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B3EE2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B3EF2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B3F02276B88600CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B3F12276B88600CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B3F22276B88600CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B3F32276B88600CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B3F42276B88600CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B3F62276B88600CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B3F72276B88600CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B3F82276B88600CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B3F92276B88600CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B4D72276BA5100CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B4D82276BA5100CA3706 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - C5C4B4D92276BA7000CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B4DA2276BA7000CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; - C5C4B4DF2276BA8D00CA3706 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */; }; - C5C4B4E02276BA8D00CA3706 /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */; }; - C5C4B4E42276BA8D00CA3706 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */; }; - C5C4B4E52276BA8D00CA3706 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; + C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D724E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044D824E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044D924E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044DA24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044DB24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044DC24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044DD24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044DE24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; C5C7B74A22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */; }; C5C7B74B22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */; }; C5C7B74C22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */; }; @@ -830,7 +770,6 @@ C5D25D3721795B790037B13D /* FBSDKCodelessIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = C5D25D3421795B790037B13D /* FBSDKCodelessIndexer.h */; }; C5D25D3821795B790037B13D /* FBSDKCodelessIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = C5D25D3521795B790037B13D /* FBSDKCodelessIndexer.m */; }; C5D25D3921795B790037B13D /* FBSDKCodelessIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = C5D25D3521795B790037B13D /* FBSDKCodelessIndexer.m */; }; - C5DFB84322CBC1EB0086E16C /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */; }; C5F6EC861FA24FAF009EB258 /* FBSDKPaymentObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */; }; C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */; }; E4416C0123F61902009CCBFA /* FBSDKModelParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */; }; @@ -850,22 +789,6 @@ F40F6568241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; F40F6569241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; F40F656A241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; - F413881E24C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413881F24C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413882024C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413882124C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413882224C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413882324C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413882424C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413882524C76E0A001BC075 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */; }; - F413883524C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883624C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883724C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883824C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883924C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883A24C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883B24C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; - F413883C24C76E78001BC075 /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883424C76E78001BC075 /* FBSDKSafeCast.m */; }; F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */; }; F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */; }; F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41979272475A20E003007CC /* FBSDKTypeUtilityTests.m */; }; @@ -909,6 +832,71 @@ F462DC0023B9575100FFCECA /* FBSDKServerConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8917C4AB1B7A46C800B0B96B /* FBSDKServerConfiguration+Internal.h */; }; F462DC0123B9578E00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D69FC421AA66BBC0068EC76 /* FBSDKGraphRequestConnection+Internal.h */; }; F462DC0223B9578F00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D69FC421AA66BBC0068EC76 /* FBSDKGraphRequestConnection+Internal.h */; }; + F468B22E24C2399900979F8D /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */; }; + F468B22F24C2399900979F8D /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */; }; + F468B23424C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; + F468B23524C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; + F468B23624C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; + F468B23724C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; + F468B23E24C2399900979F8D /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22024C2399800979F8D /* FBSDKCrashObserving.h */; }; + F468B23F24C2399900979F8D /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22024C2399800979F8D /* FBSDKCrashObserving.h */; }; + F468B24424C2399900979F8D /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22124C2399800979F8D /* FBSDKTypeUtility.h */; }; + F468B24624C2399900979F8D /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22124C2399800979F8D /* FBSDKTypeUtility.h */; }; + F468B24724C2399900979F8D /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22124C2399800979F8D /* FBSDKTypeUtility.h */; }; + F468B26624C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */; }; + F468B26724C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */; }; + F468B2A024C2457000979F8D /* FBSDKRestrictiveData.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */; }; + F468B2A124C2457000979F8D /* FBSDKRestrictiveData.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */; }; + F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; + F468B2A724C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; + F468B30A24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30B24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30C24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30D24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30E24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30F24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B31024C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B31124C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B31A24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31B24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31C24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31D24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31E24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31F24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B32024C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B32124C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B32224C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32424C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32524C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32624C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32724C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32824C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32924C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B34224C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34424C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34524C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34624C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34724C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34824C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34924C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34B24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34C24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34D24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34E24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34F24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B35024C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B35124C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35324C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35624C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35724C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35824C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35924C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m */; }; F46FA62D24533F450060C902 /* AccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBD9231EC293008416A9 /* AccessToken.swift */; }; F46FA63C24533F450060C902 /* AccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBD9231EC293008416A9 /* AccessToken.swift */; }; @@ -917,7 +905,14 @@ F46FA63F24533F690060C902 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBCD231EC20E008416A9 /* Settings.swift */; }; F46FA64024533F690060C902 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBCD231EC20E008416A9 /* Settings.swift */; }; F4713D7D2375DA8200748692 /* FBSDKSuggestedEventsIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = BF247C812374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m */; }; + F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */ = {isa = PBXBuildFile; fileRef = F47E55FB24E1EA8D001497C9 /* FakeBundle.m */; }; F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */; }; + F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */; }; + F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; + F496E58F24E49DBC006231A2 /* SampleAppEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.m */; }; + F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */; }; + F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.m */; }; + F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */; }; F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */; }; F4A52AFE242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A52AFC242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h */; }; F4A52AFF242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A52AFC242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h */; }; @@ -936,7 +931,8 @@ F4A52B15242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; F4A52B16242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; F4A52B17242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; - F4B3CA3222B3FED80098ADF5 /* ExampleSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4B3CA3122B3FED80098ADF5 /* ExampleSwiftTests.swift */; }; + F4A826B524EC6F9900EB2CD4 /* SampleUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */; }; + F4A826B724EC6FAD00EB2CD4 /* FBSDKProfileTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */; }; F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */; }; F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF2292241954B400BFB494 /* FBSDKMonitorStoreTests.m */; }; F4BF22A3241954D800BFB494 /* FBSDKMonitorStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F4BF22A1241954D800BFB494 /* FBSDKMonitorStore.h */; }; @@ -956,51 +952,80 @@ F4D8D8E42422887600C28384 /* FBSDKMonitorNetworker.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */; }; F4D8D8E52422887600C28384 /* FBSDKMonitorNetworker.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */; }; F4D8D8FA242293ED00C28384 /* FBSDKMonitorNetworkerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */; }; + F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DE31F524DB695100297C18 /* FBSDKTestCase.m */; }; F4E50155243648A100C99262 /* FBSDKServerConfigurationFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */; }; F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */; }; - F9098FC322BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FC422BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FC522BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FC622BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FC722BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FC822BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FC922BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FCA22BC332C00857C2D /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F9098FC122BC332C00857C2D /* FBSDKURLSession.h */; }; - F9098FCB22BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FCC22BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FCD22BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FCE22BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FCF22BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FD022BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FD122BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9098FD222BC332C00857C2D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F9098FC222BC332C00857C2D /* FBSDKURLSession.m */; }; - F9169B842155A03C00FA1789 /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */; }; + F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */; }; + F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5624CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5724CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5824CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5924CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5A24CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998124D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998224D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998324D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998424D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998524D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998624D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; + F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; + F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; + F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; + F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */; }; + F916581624F6BB4D00BB759A /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9DE56B824F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h */; }; + F916581724F6BB5100BB759A /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9DE56B924F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m */; }; F91BA4DD216D6CF200CDDFE0 /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B081A702194009137EF /* FBSDKCrypto.m */; }; F91BA4F4216D6CF300CDDFE0 /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B081A702194009137EF /* FBSDKCrypto.m */; }; - F92F8F7E22BA274300494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F7F22BA274300494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F8022BA274300494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F8122BA274300494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8222BA274300494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8322BA274300494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8422BA275200494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8522BA275300494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8622BA275400494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8722BA275500494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8822BA275600494727 /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */; }; - F92F8F8922BA275900494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F8A22BA275A00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F8B22BA275B00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F8C22BA275C00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; - F92F8F8D22BA275D00494727 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */; }; + F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */; }; F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F93680D4249D490600446E35 /* FBSDKSettingsTests.m */; }; + F94310F424F8D608002441F1 /* FBSDKSKAdNetworkRule.h in Headers */ = {isa = PBXBuildFile; fileRef = F94310F224F8D608002441F1 /* FBSDKSKAdNetworkRule.h */; }; + F94310F524F8D608002441F1 /* FBSDKSKAdNetworkRule.m in Sources */ = {isa = PBXBuildFile; fileRef = F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */; }; + F943110424F8D613002441F1 /* FBSDKSKAdNetworkRule.h in Headers */ = {isa = PBXBuildFile; fileRef = F94310F224F8D608002441F1 /* FBSDKSKAdNetworkRule.h */; }; + F943110524F8D615002441F1 /* FBSDKSKAdNetworkRule.m in Sources */ = {isa = PBXBuildFile; fileRef = F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */; }; + F943112124FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F943111F24FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h */; }; + F943112224FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */; }; + F943113124FB25A3002441F1 /* FBSDKSKAdNetworkEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F943111F24FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h */; }; + F943113224FB25A7002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */; }; + F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m */; }; F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; }; F952EA482339403900B20652 /* FBSDKMetadataIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */; }; F952EA492339405D00B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; }; F952EA4B2339406400B20652 /* FBSDKMetadataIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */; }; F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */; }; F96ADE7A21E6ABB400F6043F /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F96ADE6321E6ABB400F6043F /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */; }; + F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m */; }; + F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */; }; + F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */; }; + F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; + F9A06DB82510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; + F9A06DB92510FAD3007E6386 /* FBSDKAppEventsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */; }; + F9A06DBA2510FAD3007E6386 /* FBSDKAppEventsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */; }; + F9A06DC92510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */; }; + F9A06DCA2510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */; }; + F9A06DCB2510FAF6007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; + F9A06DCC2510FAF7007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; + F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */; }; + F9A06DD02510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */; }; + F9A06DD12510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */; }; + F9A06DD22510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */; }; + F9A06DD32510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; + F9A06DD42510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; + F9A06DD52510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; + F9A06DD62510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; F9A80C9E237D02860019D7E0 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9A80C9D237D02860019D7E0 /* Accelerate.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + F9CBE51124E085CD0097B442 /* FBSDKSKAdNetworkReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = F9CBE50F24E085CD0097B442 /* FBSDKSKAdNetworkReporter.h */; }; + F9CBE51224E085CD0097B442 /* FBSDKSKAdNetworkReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = F9CBE51024E085CD0097B442 /* FBSDKSKAdNetworkReporter.m */; }; + F9CBE51324E085E70097B442 /* FBSDKSKAdNetworkReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = F9CBE50F24E085CD0097B442 /* FBSDKSKAdNetworkReporter.h */; }; + F9CBE51424E090590097B442 /* FBSDKSKAdNetworkReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = F9CBE51024E085CD0097B442 /* FBSDKSKAdNetworkReporter.m */; }; + F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F9CEF1EA24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m */; }; + F9DE56BA24F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9DE56B824F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h */; }; + F9DE56BB24F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9DE56B924F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m */; }; F9FD9A6221659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */; }; F9FD9A6321659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */; }; F9FD9A6421659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */; }; @@ -1179,6 +1204,7 @@ 033429B020894D4700C94913 /* FBSDKAccessTokenExpirer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessTokenExpirer.h; sourceTree = ""; }; 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessTokenExpirer.m; sourceTree = ""; }; 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkUtilityTests.m; sourceTree = ""; }; + 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValueTests.m; sourceTree = ""; }; 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKDeviceUtilities.m; sourceTree = ""; }; 4AF47CF21F42468D00A57A67 /* FBSDKDeviceUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKDeviceUtilities.h; sourceTree = ""; }; 4AF47CFE1F424A8700A57A67 /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.0.sdk/System/Library/Frameworks/CoreImage.framework; sourceTree = DEVELOPER_DIR; }; @@ -1212,7 +1238,6 @@ 5D411319229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveDataFilterManager.h; sourceTree = ""; }; 5D4360DA23219F7900254DF7 /* FBSDKCrashObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashObserver.h; sourceTree = ""; }; 5D4360DF23219F8E00254DF7 /* FBSDKCrashObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashObserver.m; sourceTree = ""; }; - 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashObserving.h; sourceTree = ""; }; 5D497701244A3E6A00BD45C6 /* FBSDKIntegrityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKIntegrityTests.m; sourceTree = ""; }; 5D59BFFC23A705010008CA5A /* FBSDKCrashHandlerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashHandlerTests.m; sourceTree = ""; }; 5D59BFFE23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLibAnalyzerTests.m; sourceTree = ""; }; @@ -1223,10 +1248,6 @@ 5D81B422238739E600B02B2E /* FBSDKIntegrityManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKIntegrityManager.m; sourceTree = ""; }; 5D90CDDE2343D4BD00AF326A /* FBSDKCrashShield.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashShield.m; sourceTree = ""; }; 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashShield.h; sourceTree = ""; }; - 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashHandler.m; sourceTree = ""; }; - 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashHandler.h; sourceTree = ""; }; - 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKLibAnalyzer.h; sourceTree = ""; }; - 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLibAnalyzer.m; sourceTree = ""; }; 5DAB01F023A1831A005495FB /* FBSDKCrashObserverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashObserverTests.m; sourceTree = ""; }; 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKEventDeactivationTests.m; sourceTree = ""; }; 5DB612A723593AB600150851 /* FBSDKCrashShieldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashShieldTests.m; sourceTree = ""; }; @@ -1235,7 +1256,6 @@ 5DBB0446227FEF700009E0A6 /* FBSDKBasicUtilityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBasicUtilityTests.m; sourceTree = ""; }; 5DBC72D02373792A00A9D859 /* FBSDKModelManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKModelManager.h; sourceTree = ""; }; 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = FBSDKModelManager.mm; sourceTree = ""; }; - 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBasicUtility.m; sourceTree = ""; }; 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsDeviceInfo.h; sourceTree = ""; }; 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsDeviceInfo.m; sourceTree = ""; }; 6BE0966D1AAE687F00CCD61A /* FBSDKServerConfigurationManager+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKServerConfigurationManager+Internal.h"; sourceTree = ""; }; @@ -1443,6 +1463,7 @@ 9DF2A3FE1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestMetadata.m; sourceTree = ""; }; ADEA17711B7ECA1A0070EDC0 /* FBSDKMonotonicTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMonotonicTime.h; sourceTree = ""; }; ADEA17721B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonotonicTime.m; sourceTree = ""; }; + B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKAccessToken+Internal.h"; sourceTree = ""; }; BF1C64E524039AD50052C580 /* FBSDKViewHierarchyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKViewHierarchyTests.m; sourceTree = ""; }; BF247C802374E1B100A522C0 /* FBSDKSuggestedEventsIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKSuggestedEventsIndexer.h; sourceTree = ""; }; BF247C812374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSuggestedEventsIndexer.m; sourceTree = ""; }; @@ -1475,11 +1496,10 @@ C5696F32209BBC35009C931F /* FBSDKCodelessParameterComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCodelessParameterComponent.h; sourceTree = ""; }; C5696FA1209CCEB3009C931F /* FBSDKSwizzler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKSwizzler.h; sourceTree = ""; }; C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSwizzler.m; sourceTree = ""; }; + C57044CD24E26678009637AD /* FBSDKUserDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKUserDataStore.h; sourceTree = ""; }; + C57044CE24E26678009637AD /* FBSDKUserDataStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUserDataStore.m; sourceTree = ""; }; C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKTypeUtility.h; sourceTree = ""; }; - C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKBasicUtility.h; sourceTree = ""; }; - C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKFeatureManager.h; sourceTree = ""; }; @@ -1497,8 +1517,6 @@ F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntryTests.m; sourceTree = ""; }; F40F655F241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMethodUsageMonitorEntry.h; sourceTree = ""; }; F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntry.m; sourceTree = ""; }; - F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSafeCast.h; sourceTree = ""; }; - F413883424C76E78001BC075 /* FBSDKSafeCast.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSafeCast.m; sourceTree = ""; }; F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCastTests.m; path = Internal/Basics/FBSDKSafeCastTests.m; sourceTree = ""; }; F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorTests.m; sourceTree = ""; }; F41979272475A20E003007CC /* FBSDKTypeUtilityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtilityTests.m; sourceTree = ""; }; @@ -1514,20 +1532,67 @@ F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationManagerTests.m; sourceTree = ""; }; F43960CE2425513100C1868F /* FakeMonitorStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeMonitorStore.h; sourceTree = ""; }; F43960CF2425513100C1868F /* FakeMonitorStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeMonitorStore.m; sourceTree = ""; }; + F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKBasicUtility.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKBasicUtility.h; sourceTree = ""; }; + F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCoreKit_Basics.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCoreKit_Basics.h; sourceTree = ""; }; + F468B22024C2399800979F8D /* FBSDKCrashObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCrashObserving.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCrashObserving.h; sourceTree = ""; }; + F468B22124C2399800979F8D /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKTypeUtility.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKTypeUtility.h; sourceTree = ""; }; + F468B22224C2399800979F8D /* FBSDKLibAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKLibAnalyzer.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKLibAnalyzer.m; sourceTree = ""; }; + F468B22324C2399800979F8D /* FBSDKURLSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKURLSession.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSession.m; sourceTree = ""; }; + F468B22424C2399800979F8D /* FBSDKCrashHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKCrashHandler.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCrashHandler.m; sourceTree = ""; }; + F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKLibAnalyzer.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKLibAnalyzer.h; sourceTree = ""; }; + F468B22624C2399900979F8D /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKURLSessionTask.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSessionTask.h; sourceTree = ""; }; + F468B22724C2399900979F8D /* FBSDKURLSessionTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKURLSessionTask.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSessionTask.m; sourceTree = ""; }; + F468B22824C2399900979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKTypeUtility.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKTypeUtility.m; sourceTree = ""; }; + F468B22924C2399900979F8D /* FBSDKBasicUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKBasicUtility.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKBasicUtility.m; sourceTree = ""; }; + F468B22A24C2399900979F8D /* FBSDKURLSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKURLSession.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSession.h; sourceTree = ""; }; + F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; + F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; + F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; + F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKURLSessionTask.m; sourceTree = ""; }; + F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashHandler.m; sourceTree = ""; }; + F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKBasicUtility.m; sourceTree = ""; }; + F468B2E824C25AB600979F8D /* FBSDKURLSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKURLSession.m; sourceTree = ""; }; + F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLibAnalyzer.m; sourceTree = ""; }; F46C4847243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKMonitoringConfigurationTestHelper.h; path = FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h; sourceTree = SOURCE_ROOT; }; F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKMonitoringConfigurationTestHelper.m; path = FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m; sourceTree = SOURCE_ROOT; }; + F47E55FB24E1EA8D001497C9 /* FakeBundle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FakeBundle.m; sourceTree = ""; }; + F47E560C24E1EA8D001497C9 /* FakeBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FakeBundle.h; sourceTree = ""; }; F487DBCB231EC1A0008416A9 /* Permission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Permission.swift; sourceTree = ""; }; F487DBCD231EC20E008416A9 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; F487DBD9231EC293008416A9 /* AccessToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessToken.swift; sourceTree = ""; }; F48A6AEB24170D29002C6CA1 /* TestMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestMonitorEntry.h; sourceTree = ""; }; F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestMonitorEntry.m; sourceTree = ""; }; + F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainStoreSpy.h; sourceTree = ""; }; + F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDefaultsSpy.h; sourceTree = ""; }; + F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainStoreSpy.m; sourceTree = ""; }; + F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; + F496E58D24E49DBC006231A2 /* SampleAppEvents.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SampleAppEvents.h; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h; sourceTree = SOURCE_ROOT; }; + F496E58E24E49DBC006231A2 /* SampleAppEvents.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SampleAppEvents.m; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m; sourceTree = SOURCE_ROOT; }; + F496E5FC24E5D0D5006231A2 /* FakeAccessTokenCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeAccessTokenCache.h; sourceTree = ""; }; + F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeAccessTokenCache.m; sourceTree = ""; }; + F496E60D24E5D195006231A2 /* SampleAccessToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleAccessToken.h; sourceTree = ""; }; + F496E60E24E5D195006231A2 /* SampleAccessToken.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAccessToken.m; sourceTree = ""; }; + F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegateObserverFake.h; sourceTree = ""; }; + F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegateObserverFake.m; sourceTree = ""; }; + F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTypeUtility.h; sourceTree = ""; }; + F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKURLSessionTask.h; sourceTree = ""; }; + F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSafeCast.h; sourceTree = ""; }; + F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashHandler.h; sourceTree = ""; }; + F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKLibAnalyzer.h; sourceTree = ""; }; + F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKBasicUtility.h; sourceTree = ""; }; + F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKJSONValue.h; sourceTree = ""; }; + F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKURLSession.h; sourceTree = ""; }; + F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKit_Basics.h; sourceTree = ""; }; + F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashObserving.h; sourceTree = ""; }; F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPerformanceMonitorEntryTests.m; sourceTree = ""; }; F4A52AFC242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKPerformanceMonitorEntry.h; sourceTree = ""; }; F4A52AFD242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPerformanceMonitorEntry.m; sourceTree = ""; }; F4A52B0A242A99C8005F65CE /* FBSDKPerformanceMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPerformanceMonitorTests.m; sourceTree = ""; }; F4A52B0C242AA532005F65CE /* FBSDKPerformanceMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKPerformanceMonitor.h; sourceTree = ""; }; F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPerformanceMonitor.m; sourceTree = ""; }; - F4B3CA3122B3FED80098ADF5 /* ExampleSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleSwiftTests.swift; sourceTree = ""; }; + F4A826A524EC6F9900EB2CD4 /* SampleUserProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleUserProfile.h; sourceTree = ""; }; + F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SampleUserProfile.m; sourceTree = ""; }; + F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKProfileTests.m; sourceTree = ""; }; F4BD4022241EEDE500B45D39 /* FBSDKTestCoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTestCoder.h; sourceTree = ""; }; F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKTestCoder.m; sourceTree = ""; }; F4BF2292241954B400BFB494 /* FBSDKMonitorStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStoreTests.m; sourceTree = ""; }; @@ -1537,22 +1602,48 @@ F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworker.m; sourceTree = ""; }; F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworkerTests.m; sourceTree = ""; }; F4D8D8FB2422B88B00C28384 /* FBSDKMonitorHeaders.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorHeaders.h; sourceTree = ""; }; + F4DE31F424DB695100297C18 /* FBSDKTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTestCase.h; sourceTree = ""; }; + F4DE31F524DB695100297C18 /* FBSDKTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKTestCase.m; sourceTree = ""; }; F4E1EB9F2444E0AB006FB48E /* Analyzer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Analyzer.xcconfig; path = ../../../Configurations/Analyzer.xcconfig; sourceTree = ""; }; F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKServerConfigurationFixtures.h; sourceTree = ""; }; F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationFixtures.m; sourceTree = ""; }; F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationTests.m; sourceTree = ""; }; - F9098FC122BC332C00857C2D /* FBSDKURLSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKURLSession.h; sourceTree = ""; }; - F9098FC222BC332C00857C2D /* FBSDKURLSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKURLSession.m; sourceTree = ""; }; - F9169B822155A02000FA1789 /* FBSDKUserDataStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKUserDataStore.h; sourceTree = ""; }; - F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKUserDataStore.m; sourceTree = ""; }; - F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKURLSessionTask.h; sourceTree = ""; }; - F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKURLSessionTask.m; sourceTree = ""; }; + F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationCenterSpy.h; sourceTree = ""; }; + F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationCenterSpy.m; sourceTree = ""; }; + F4F98BB324CB77F400F0D6EC /* FBSDKSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKSafeCast.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.h; sourceTree = ""; }; + F4F98BC224CB77F400F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCast.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.m; sourceTree = ""; }; + F4F98C0F24CB7F6D00F0D6EC /* FBSDKSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKSafeCast.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.h; sourceTree = ""; }; + F4F98C1024CB7F6D00F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCast.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.m; sourceTree = ""; }; + F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSafeCast.m; sourceTree = ""; }; + F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValue.m; sourceTree = ""; }; + F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKJSONValue.h; path = ../../../Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.h; sourceTree = ""; }; + F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkConversionConfigurationTests.m; sourceTree = ""; }; + F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkRuleTests.m; sourceTree = ""; }; F93680D4249D490600446E35 /* FBSDKSettingsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSettingsTests.m; path = Internal/FBSDKSettingsTests.m; sourceTree = ""; }; + F94310F224F8D608002441F1 /* FBSDKSKAdNetworkRule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkRule.h; sourceTree = ""; }; + F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkRule.m; sourceTree = ""; }; + F943111F24FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkEvent.h; sourceTree = ""; }; + F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkEvent.m; sourceTree = ""; }; + F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkEventTests.m; sourceTree = ""; }; F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMetadataIndexer.m; sourceTree = ""; }; F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMetadataIndexer.h; sourceTree = ""; }; F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMetadataIndexerTests.m; sourceTree = ""; }; F96ADE6321E6ABB400F6043F /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; + F98D1D3625124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfigurationFixtures.h; sourceTree = ""; }; + F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationFixtures.m; sourceTree = ""; }; + F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationTests.m; sourceTree = ""; }; + F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawAppEventsConfigurationResponseFixtures.swift; sourceTree = ""; }; + F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationManagerTests.m; sourceTree = ""; }; + F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfiguration.h; sourceTree = ""; }; + F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfiguration.m; sourceTree = ""; }; + F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfigurationManager.h; sourceTree = ""; }; + F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationManager.m; sourceTree = ""; }; F9A80C9D237D02860019D7E0 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; + F9CBE50F24E085CD0097B442 /* FBSDKSKAdNetworkReporter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkReporter.h; sourceTree = ""; }; + F9CBE51024E085CD0097B442 /* FBSDKSKAdNetworkReporter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkReporter.m; sourceTree = ""; }; + F9CEF1EA24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkReporterTests.m; sourceTree = ""; }; + F9DE56B824F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkConversionConfiguration.h; sourceTree = ""; }; + F9DE56B924F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkConversionConfiguration.m; sourceTree = ""; }; F9FD9A6121659F120068DEAF /* FBSDKGateKeeperManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKGateKeeperManager.h; sourceTree = ""; }; F9FD9A7C21659F320068DEAF /* FBSDKGateKeeperManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGateKeeperManager.m; sourceTree = ""; }; F9FFE01C2252D665007B2346 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; @@ -1652,18 +1743,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 5D4361132321C2F000254DF7 /* Instrument */ = { - isa = PBXGroup; - children = ( - 5D9A704023261D6900BF9783 /* FBSDKCrashHandler.h */, - 5D9A703F23261D6900BF9783 /* FBSDKCrashHandler.m */, - 5D9A704123261D6900BF9783 /* FBSDKLibAnalyzer.h */, - 5D9A704223261D6900BF9783 /* FBSDKLibAnalyzer.m */, - 5D4361142321C30400254DF7 /* FBSDKCrashObserving.h */, - ); - path = Instrument; - sourceTree = ""; - }; 5D497700244A3E5700BD45C6 /* Integrity */ = { isa = PBXGroup; children = ( @@ -1676,8 +1755,8 @@ 5D6DF1542398E24800AC2D6C /* EventDeactivation */ = { isa = PBXGroup; children = ( - 5D6DF1622398E28000AC2D6C /* FBSDKEventDeactivationManager.m */, 5D6DF1692398E2A200AC2D6C /* FBSDKEventDeactivationManager.h */, + 5D6DF1622398E28000AC2D6C /* FBSDKEventDeactivationManager.m */, ); path = EventDeactivation; sourceTree = ""; @@ -1685,6 +1764,8 @@ 5D9031C0233AAC5D0001450C /* Integrity */ = { isa = PBXGroup; children = ( + F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */, + F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */, 5D411318229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m */, 5D411319229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.h */, 5D81B410238739B100B02B2E /* FBSDKIntegrityManager.h */, @@ -1759,15 +1840,6 @@ path = ML; sourceTree = ""; }; - 5DF60D07225DB6B200934A0E /* Basics */ = { - isa = PBXGroup; - children = ( - 5D4361132321C2F000254DF7 /* Instrument */, - C5C4B3E22276B88600CA3706 /* Internal */, - ); - path = Basics; - sourceTree = ""; - }; 7E5557391A8D833800344F86 /* AppLinks */ = { isa = PBXGroup; children = ( @@ -1871,6 +1943,7 @@ 893F44921A64448E001DB0B6 /* Internal */ = { isa = PBXGroup; children = ( + B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */, 5DB7ADCA22EA59E60012E8CB /* Instrument */, 894C0B0E1A7021F8009137EF /* Base64 */, 894C0AE11A6F1D27009137EF /* BridgeAPI */, @@ -1947,6 +2020,7 @@ 893F44A41A644552001DB0B6 /* Internal */ = { isa = PBXGroup; children = ( + 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */, 9D18A8D91A95403F00A41042 /* AppEvents */, 7E5557391A8D833800344F86 /* AppLinks */, 894C0B481A705244009137EF /* Base64 */, @@ -2107,6 +2181,7 @@ 9D18A8D91A95403F00A41042 /* AppEvents */ = { isa = PBXGroup; children = ( + F916580524F6BA9300BB759A /* SKAdNetwork */, 5D497700244A3E5700BD45C6 /* Integrity */, BF1C64E2240399180052C580 /* ViewHierarchy */, E493252B23F7C51D0000B63A /* ML */, @@ -2119,6 +2194,11 @@ C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */, 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */, 5D68D7D722BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m */, + F98D1D3625124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.h */, + F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */, + F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m */, + F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */, + F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */, ); path = AppEvents; sourceTree = ""; @@ -2141,6 +2221,7 @@ 893F44A31A644536001DB0B6 /* Frameworks */, 9D2697481A5DF40700143BFC /* Products */, 9D222B581A670D1300832F83 /* Submodules */, + F468B2B324C24A9500979F8D /* Recovered References */, ); indentWidth = 2; sourceTree = ""; @@ -2165,8 +2246,8 @@ 9D2697491A5DF40700143BFC /* FBSDKCoreKit */ = { isa = PBXGroup; children = ( + F4BD248E24C2189E00975C87 /* Basics */, E4320C3123B8943700EF2653 /* GraphAPI */, - 5DF60D07225DB6B200934A0E /* Basics */, C5188EC122371EE400F4D8BC /* AppEvents */, C5188F1C223857D700F4D8BC /* AppLink */, 9D3029081A65C4420086B9ED /* FBSDKAccessToken.h */, @@ -2217,8 +2298,8 @@ 9D2697561A5DF40700143BFC /* FBSDKCoreKitTests */ = { isa = PBXGroup; children = ( + F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */, F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */, - F4B3CA3122B3FED80098ADF5 /* ExampleSwiftTests.swift */, 7E253D841A8EB78300CCCFE7 /* FBSDKCoreKitTestUtility.h */, 7E253D821A8EB76500CCCFE7 /* FBSDKCoreKitTestUtility.m */, C511229F20A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m */, @@ -2360,6 +2441,7 @@ C5188EC322371F4000F4D8BC /* Internal */ = { isa = PBXGroup; children = ( + F9CBE50024E085A40097B442 /* SKAdNetwork */, 5D6DF1542398E24800AC2D6C /* EventDeactivation */, BFC6A2192387227800395451 /* ViewHierarchy */, 5DBC72C2237378F800A9D859 /* ML */, @@ -2382,8 +2464,10 @@ 9D0BC14B1A8D236200BE8BA4 /* FBSDKPaymentObserver.m */, 9D0BC14C1A8D236200BE8BA4 /* FBSDKTimeSpentData.h */, 9D0BC14D1A8D236200BE8BA4 /* FBSDKTimeSpentData.m */, - F9169B822155A02000FA1789 /* FBSDKUserDataStore.h */, - F9169B832155A03C00FA1789 /* FBSDKUserDataStore.m */, + F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */, + F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */, + F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */, + F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */, ); path = Internal; sourceTree = ""; @@ -2439,23 +2523,6 @@ path = Codeless; sourceTree = ""; }; - C5C4B3E22276B88600CA3706 /* Internal */ = { - isa = PBXGroup; - children = ( - 5DEF22CE226A3E06004056C1 /* FBSDKBasicUtility.m */, - C5C4B3E42276B88600CA3706 /* FBSDKBasicUtility.h */, - C5C4B3E32276B88600CA3706 /* FBSDKTypeUtility.h */, - C5C4B3E52276B88600CA3706 /* FBSDKTypeUtility.m */, - F92F8F7C22BA274300494727 /* FBSDKURLSessionTask.h */, - F92F8F7D22BA274300494727 /* FBSDKURLSessionTask.m */, - F9098FC122BC332C00857C2D /* FBSDKURLSession.h */, - F9098FC222BC332C00857C2D /* FBSDKURLSession.m */, - F413881D24C76E0A001BC075 /* FBSDKSafeCast.h */, - F413883424C76E78001BC075 /* FBSDKSafeCast.m */, - ); - path = Internal; - sourceTree = ""; - }; E4320C3123B8943700EF2653 /* GraphAPI */ = { isa = PBXGroup; children = ( @@ -2524,6 +2591,31 @@ path = Monitoring; sourceTree = ""; }; + F468B2B324C24A9500979F8D /* Recovered References */ = { + isa = PBXGroup; + children = ( + F468B22324C2399800979F8D /* FBSDKURLSession.m */, + F468B22924C2399900979F8D /* FBSDKBasicUtility.m */, + F468B22724C2399900979F8D /* FBSDKURLSessionTask.m */, + F468B22424C2399800979F8D /* FBSDKCrashHandler.m */, + F468B22824C2399900979F8D /* FBSDKTypeUtility.m */, + F468B22224C2399800979F8D /* FBSDKLibAnalyzer.m */, + F468B22A24C2399900979F8D /* FBSDKURLSession.h */, + F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */, + F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */, + F468B22624C2399900979F8D /* FBSDKURLSessionTask.h */, + F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */, + F468B22124C2399800979F8D /* FBSDKTypeUtility.h */, + F468B22024C2399800979F8D /* FBSDKCrashObserving.h */, + F4F98BC224CB77F400F0D6EC /* FBSDKSafeCast.m */, + F4F98BB324CB77F400F0D6EC /* FBSDKSafeCast.h */, + F4F98C1024CB7F6D00F0D6EC /* FBSDKSafeCast.m */, + F4F98C0F24CB7F6D00F0D6EC /* FBSDKSafeCast.h */, + F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */, + ); + name = "Recovered References"; + sourceTree = ""; + }; F487DBCA231EBD8B008416A9 /* Swift */ = { isa = PBXGroup; children = ( @@ -2534,14 +2626,70 @@ path = Swift; sourceTree = ""; }; + F4A11B4724E36E5200D4C010 /* include */ = { + isa = PBXGroup; + children = ( + F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */, + F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */, + F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */, + F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */, + F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */, + F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */, + F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */, + F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */, + F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */, + F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */, + C57044CD24E26678009637AD /* FBSDKUserDataStore.h */, + ); + path = include; + sourceTree = ""; + }; + F4BD248E24C2189E00975C87 /* Basics */ = { + isa = PBXGroup; + children = ( + F4A11B4724E36E5200D4C010 /* include */, + F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */, + F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */, + F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */, + F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */, + F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */, + F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */, + F468B2E824C25AB600979F8D /* FBSDKURLSession.m */, + F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */, + C57044CE24E26678009637AD /* FBSDKUserDataStore.m */, + ); + name = Basics; + path = ../../Sources/FBSDKCoreKit_Basics; + sourceTree = ""; + }; F4CD7CDA243E2CF7004C27F1 /* Helpers */ = { isa = PBXGroup; children = ( + F4A826A524EC6F9900EB2CD4 /* SampleUserProfile.h */, + F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */, + F496E58D24E49DBC006231A2 /* SampleAppEvents.h */, + F496E58E24E49DBC006231A2 /* SampleAppEvents.m */, + F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */, + F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */, + F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */, + F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */, + F47E560C24E1EA8D001497C9 /* FakeBundle.h */, + F47E55FB24E1EA8D001497C9 /* FakeBundle.m */, F4BD4022241EEDE500B45D39 /* FBSDKTestCoder.h */, F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */, F46C4847243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.h */, F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m */, F40B24C124732DD90059351C /* Fuzzer.swift */, + F4DE31F424DB695100297C18 /* FBSDKTestCase.h */, + F4DE31F524DB695100297C18 /* FBSDKTestCase.m */, + F496E5FC24E5D0D5006231A2 /* FakeAccessTokenCache.h */, + F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */, + F496E60D24E5D195006231A2 /* SampleAccessToken.h */, + F496E60E24E5D195006231A2 /* SampleAccessToken.m */, + F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */, + F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */, + F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */, + F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */, ); path = Helpers; sourceTree = ""; @@ -2558,6 +2706,17 @@ path = ServerConfiguration; sourceTree = ""; }; + F916580524F6BA9300BB759A /* SKAdNetwork */ = { + isa = PBXGroup; + children = ( + F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */, + F9CEF1EA24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m */, + F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */, + F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m */, + ); + path = SKAdNetwork; + sourceTree = ""; + }; F952EA442339403900B20652 /* AAM */ = { isa = PBXGroup; children = ( @@ -2575,6 +2734,21 @@ path = AAM; sourceTree = ""; }; + F9CBE50024E085A40097B442 /* SKAdNetwork */ = { + isa = PBXGroup; + children = ( + F9CBE50F24E085CD0097B442 /* FBSDKSKAdNetworkReporter.h */, + F9CBE51024E085CD0097B442 /* FBSDKSKAdNetworkReporter.m */, + F9DE56B824F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h */, + F9DE56B924F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m */, + F94310F224F8D608002441F1 /* FBSDKSKAdNetworkRule.h */, + F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */, + F943111F24FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h */, + F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */, + ); + path = SKAdNetwork; + sourceTree = ""; + }; FD2A237F22FBF7A700DC928F /* ErrorReport */ = { isa = PBXGroup; children = ( @@ -2593,14 +2767,15 @@ files = ( 814AC8171D1B528900D61E6C /* FBSDKKeychainStoreViaBundleID.h in Headers */, 5D6DF16D2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, + F468B23724C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, 814AC8181D1B528900D61E6C /* FBSDKError.h in Headers */, 814AC8191D1B528900D61E6C /* FBSDKButton.h in Headers */, 814AC81A1D1B528900D61E6C /* FBSDKErrorRecoveryConfiguration.h in Headers */, 814AC81B1D1B528900D61E6C /* FBSDKApplicationDelegate.h in Headers */, + F468B2A124C2457000979F8D /* FBSDKRestrictiveData.h in Headers */, 814AC81C1D1B528900D61E6C /* FBSDKDeviceViewControllerBase.h in Headers */, 814AC81D1D1B528900D61E6C /* FBSDKDialogConfiguration.h in Headers */, 814AC81E1D1B528900D61E6C /* FBSDKInternalUtility.h in Headers */, - F413882124C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, FD147F692387215E000B216E /* FBSDKRestrictiveDataFilterManager.h in Headers */, 814AC81F1D1B528900D61E6C /* FBSDKModalFormPresentationController.h in Headers */, 9DC277931DAF4D6B004F4AB5 /* FBSDKSmartDeviceDialogView.h in Headers */, @@ -2617,12 +2792,14 @@ F4D8D8DF2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */, 814AC8271D1B528900D61E6C /* FBSDKDeviceButton.h in Headers */, F42004922416C30300AD7006 /* FBSDKMonitor.h in Headers */, + F468B26724C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */, 814AC8291D1B528900D61E6C /* FBSDKAccessTokenCache.h in Headers */, 814AC82A1D1B528900D61E6C /* FBSDKAppEventsState.h in Headers */, 814AC82B1D1B528900D61E6C /* FBSDKAppEvents+Internal.h in Headers */, 52D4F0D51D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */, 814AC82C1D1B528900D61E6C /* FBSDKTestUsersManager.h in Headers */, 814AC82D1D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, + F468B22F24C2399900979F8D /* FBSDKBasicUtility.h in Headers */, 814AC82E1D1B528900D61E6C /* FBSDKGraphRequestBody.h in Headers */, 033429CA208951E400C94913 /* FBSDKAccessTokenExpirer.h in Headers */, 814AC8301D1B528900D61E6C /* FBSDKGraphRequestDataAttachment.h in Headers */, @@ -2642,39 +2819,36 @@ 814AC83A1D1B528900D61E6C /* FBSDKSettings.h in Headers */, 814AC83B1D1B528900D61E6C /* FBSDKAppEventsDeviceInfo.h in Headers */, F4A52B01242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */, - 5D9A704F23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, 814AC83C1D1B528900D61E6C /* FBSDKUIUtility.h in Headers */, 814AC83D1D1B528900D61E6C /* FBSDKAppEvents.h in Headers */, + F468B23F24C2399900979F8D /* FBSDKCrashObserving.h in Headers */, F9FD9A6521659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */, + F468B24724C2399900979F8D /* FBSDKTypeUtility.h in Headers */, 814AC83E1D1B528900D61E6C /* FBSDKErrorConfiguration.h in Headers */, 814AC83F1D1B528900D61E6C /* FBSDKConstants.h in Headers */, 814AC8401D1B528900D61E6C /* FBSDKMath.h in Headers */, + F9A06DD22510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, 814AC8411D1B528900D61E6C /* FBSDKDynamicFrameworkLoader.h in Headers */, 814AC8421D1B528900D61E6C /* FBSDKServerConfiguration.h in Headers */, 814AC8431D1B528900D61E6C /* FBSDKGraphRequestPiggybackManager.h in Headers */, + C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */, 814AC8441D1B528900D61E6C /* FBSDKAppEventsUtility.h in Headers */, - F9098FC622BC332C00857C2D /* FBSDKURLSession.h in Headers */, 5D90CDE92343D4D200AF326A /* FBSDKCrashShield.h in Headers */, - 5D4361182321C30400254DF7 /* FBSDKCrashObserving.h in Headers */, 814AC8471D1B528900D61E6C /* FBSDKCopying.h in Headers */, - C5C4B3F02276B88600CA3706 /* FBSDKBasicUtility.h in Headers */, - F92F8F8922BA275900494727 /* FBSDKURLSessionTask.h in Headers */, - C5C4B3EA2276B88600CA3706 /* FBSDKTypeUtility.h in Headers */, 814AC8491D1B528900D61E6C /* FBSDKLogger.h in Headers */, 814AC84A1D1B528900D61E6C /* FBSDKGraphRequest.h in Headers */, 9D28F1961DB14DBB0057D709 /* FBSDKImageDownloader.h in Headers */, 814AC84B1D1B528900D61E6C /* FBSDKDeviceButton+Internal.h in Headers */, 814AC84C1D1B528900D61E6C /* FBSDKGraphRequest+Internal.h in Headers */, 814AC84D1D1B528900D61E6C /* FBSDKApplicationDelegate+Internal.h in Headers */, - 5263EDDA215D98BD00FAAB0C /* FBSDKUserDataStore.h in Headers */, F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */, F4210E31241B00790061F56D /* FBSDKMethodUsageMonitor.h in Headers */, 5D4360DE23219F7900254DF7 /* FBSDKCrashObserver.h in Headers */, 814AC84E1D1B528900D61E6C /* FBSDKServerConfigurationManager.h in Headers */, + F9A06DCC2510FAF7007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, F462DC0223B9578F00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */, 814AC84F1D1B528900D61E6C /* FBSDKAppEventsStateManager.h in Headers */, 814AC8501D1B528900D61E6C /* FBSDKLogo.h in Headers */, - 5D9A705823261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, F42004722416BCC700AD7006 /* FBSDKMonitorEntry.h in Headers */, F420D18B2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.h in Headers */, 814AC8511D1B528900D61E6C /* FBSDKGraphRequestMetadata.h in Headers */, @@ -2688,7 +2862,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C5C4B3E82276B88600CA3706 /* FBSDKTypeUtility.h in Headers */, + F916581624F6BB4D00BB759A /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */, + F943110424F8D613002441F1 /* FBSDKSKAdNetworkRule.h in Headers */, 81B71D481D19C87400933E93 /* FBSDKAppLinkUtility.h in Headers */, 81B71D491D19C87400933E93 /* FBSDKAppLinkResolver.h in Headers */, 52963AA6215993C100C7B252 /* FBSDKAppLink_Internal.h in Headers */, @@ -2697,6 +2872,7 @@ 5D81B412238739B100B02B2E /* FBSDKIntegrityManager.h in Headers */, 81B71D4B1D19C87400933E93 /* FBSDKBridgeAPIResponse.h in Headers */, FDAF4A8E2395D27900711C4C /* FBSDKModelUtility.h in Headers */, + F9A06DB82510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, F4BF22A4241954D800BFB494 /* FBSDKMonitorStore.h in Headers */, 81B71D4C1D19C87400933E93 /* FBSDKCoreKit+Internal.h in Headers */, BFC02453237B6B8E00A596EE /* FBSDKTensor.hpp in Headers */, @@ -2709,13 +2885,12 @@ 5D90CDE72343D4D200AF326A /* FBSDKCrashShield.h in Headers */, 81B71D4F1D19C87400933E93 /* FBSDKLogo.h in Headers */, 81B71D501D19C87400933E93 /* FBSDKProfilePictureView.h in Headers */, + F9A06DD02510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, 81B71D511D19C87400933E93 /* FBSDKButton.h in Headers */, 52963AAD2159A16E00C7B252 /* FBSDKMeasurementEvent.h in Headers */, 81B71D521D19C87400933E93 /* FBSDKBridgeAPIProtocol.h in Headers */, C5696F94209BBC35009C931F /* FBSDKEventBinding.h in Headers */, - C5C4B3EE2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */, 81B71D531D19C87400933E93 /* FBSDKGraphErrorRecoveryProcessor.h in Headers */, - F413881F24C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, F952EA4B2339406400B20652 /* FBSDKMetadataIndexer.h in Headers */, 52963A89215992F400C7B252 /* FBSDKAppLinkReturnToRefererController.h in Headers */, 81B71D551D19C87400933E93 /* FBSDKBase64.h in Headers */, @@ -2723,9 +2898,7 @@ 81B71D581D19C87400933E93 /* FBSDKAppEvents+Internal.h in Headers */, 9D28F1941DB14DBB0057D709 /* FBSDKImageDownloader.h in Headers */, 81B71D591D19C87400933E93 /* FBSDKErrorConfiguration.h in Headers */, - F92F8F7F22BA274300494727 /* FBSDKURLSessionTask.h in Headers */, 81B71D5A1D19C87400933E93 /* FBSDKTimeSpentData.h in Headers */, - 5D9A704D23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, 81B71D5B1D19C87400933E93 /* FBSDKIcon.h in Headers */, 81B71D5C1D19C87400933E93 /* FBSDKContainerViewController.h in Headers */, 81B71D5D1D19C87400933E93 /* FBSDKAppEventsState.h in Headers */, @@ -2741,6 +2914,7 @@ 81B71D621D19C87400933E93 /* FBSDKPaymentObserver.h in Headers */, E4416C1323F61911009CCBFA /* FBSDKModelParser.h in Headers */, F40F6562241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h in Headers */, + F9CBE51324E085E70097B442 /* FBSDKSKAdNetworkReporter.h in Headers */, 5DB7B07D230363190012E8CB /* FBSDKInstrumentManager.h in Headers */, 81B71D631D19C87400933E93 /* FBSDKProfile+Internal.h in Headers */, 5D41131F229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.h in Headers */, @@ -2755,10 +2929,10 @@ 5DBC72D22373793400A9D859 /* FBSDKModelManager.h in Headers */, 81B71D6B1D19C87400933E93 /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, 52963A8D215992F400C7B252 /* FBSDKAppLink.h in Headers */, - 5D9A705623261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, 5D4360DC23219F7900254DF7 /* FBSDKCrashObserver.h in Headers */, C5696F88209BBC35009C931F /* FBSDKViewHierarchyMacros.h in Headers */, C5696F84209BBC35009C931F /* FBSDKViewHierarchy.h in Headers */, + F943113124FB25A3002441F1 /* FBSDKSKAdNetworkEvent.h in Headers */, 81B71D6D1D19C87400933E93 /* FBSDKProfile.h in Headers */, BFC0245C237B6BA000A596EE /* FBSDKFeatureExtractor.h in Headers */, 81B71D6E1D19C87400933E93 /* FBSDKBridgeAPIProtocolWebV2.h in Headers */, @@ -2779,7 +2953,6 @@ 81B71D791D19C87400933E93 /* FBSDKGraphRequestMetadata.h in Headers */, 52963AA92159A13400C7B252 /* FBSDKMeasurementEvent_Internal.h in Headers */, 81B71D7B1D19C87400933E93 /* FBSDKGraphRequest+Internal.h in Headers */, - 5D4361162321C30400254DF7 /* FBSDKCrashObserving.h in Headers */, 81B71D7C1D19C87400933E93 /* FBSDKUtility.h in Headers */, F420D1892433BABD00D4FA82 /* FBSDKMonitoringConfiguration.h in Headers */, 81B71D7D1D19C87400933E93 /* FBSDKApplicationDelegate.h in Headers */, @@ -2797,13 +2970,14 @@ 81B71D871D19C87400933E93 /* FBSDKGraphRequestConnection+Internal.h in Headers */, 81B71D881D19C87400933E93 /* FBSDKButton+Subclass.h in Headers */, 81B71D8A1D19C87400933E93 /* FBSDKAccessToken.h in Headers */, - 5263EDD7215D98A400FAAB0C /* FBSDKUserDataStore.h in Headers */, 81B71D8B1D19C87400933E93 /* FBSDKCoreKit.h in Headers */, F4A52AFF242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */, 81B71D8C1D19C87400933E93 /* FBSDKGraphRequestBody.h in Headers */, 81B71D8D1D19C87400933E93 /* FBSDKGraphRequestDataAttachment.h in Headers */, 81B71D901D19C87400933E93 /* FBSDKSettings.h in Headers */, 81B71D911D19C87400933E93 /* FBSDKServerConfiguration.h in Headers */, + F468B23524C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, + C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */, BFC02456237B6B9300A596EE /* FBSDKModelRuntime.hpp in Headers */, 81B71D921D19C87400933E93 /* FBSDKAppEventsStateManager.h in Headers */, 81B71D931D19C87400933E93 /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -2818,7 +2992,6 @@ 5D6DF16B2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, 52963AA0215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h in Headers */, C5696F78209BBC35009C931F /* FBSDKCodelessPathComponent.h in Headers */, - F9098FC422BC332C00857C2D /* FBSDKURLSession.h in Headers */, 81B71D991D19C87400933E93 /* FBSDKGraphRequestConnection.h in Headers */, 81B71D9A1D19C87400933E93 /* FBSDKKeychainStore.h in Headers */, 81B71D9B1D19C87400933E93 /* FBSDKTestUsersManager.h in Headers */, @@ -2833,13 +3006,16 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, 7E30917B1AA92A95004E91D5 /* FBSDKAppLinkUtility.h in Headers */, 7E5557381A8D833100344F86 /* FBSDKAppLinkResolver.h in Headers */, 9D32A8401A69941A000A936D /* FBSDKAccessTokenCaching.h in Headers */, + F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, 894C0ADF1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h in Headers */, 890414741A647D8800617215 /* FBSDKCoreKit+Internal.h in Headers */, 7EB63DA01A9BE730003A7AED /* FBSDKMeasurementEventListener.h in Headers */, 5D81B411238739B100B02B2E /* FBSDKIntegrityManager.h in Headers */, + F9DE56BA24F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */, 89D05AA91AA1134000609300 /* FBSDKAudioResourceLoader.h in Headers */, FDAF4A7E2395D1DE00711C4C /* FBSDKModelUtility.h in Headers */, F4BF22A3241954D800BFB494 /* FBSDKMonitorStore.h in Headers */, @@ -2847,6 +3023,7 @@ 52963AAC2159A16E00C7B252 /* FBSDKMeasurementEvent.h in Headers */, 899C3CF81A8BF73A00EA8658 /* FBSDKProfilePictureView.h in Headers */, 891687EE1AB38C7C00F55364 /* FBSDKButton.h in Headers */, + F94310F424F8D608002441F1 /* FBSDKSKAdNetworkRule.h in Headers */, 52963A7E215992F400C7B252 /* FBSDKAppLinkResolving.h in Headers */, 894C0AF31A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h in Headers */, C5696F93209BBC35009C931F /* FBSDKEventBinding.h in Headers */, @@ -2856,22 +3033,17 @@ 9D0BC15B1A8D427800BE8BA4 /* FBSDKAppEventsUtility.h in Headers */, 9D0BC1541A8D23DB00BE8BA4 /* FBSDKAppEvents+Internal.h in Headers */, 9D28F1931DB14DBB0057D709 /* FBSDKImageDownloader.h in Headers */, - C5C4B3ED2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */, 9D3AF4501A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h in Headers */, 9D0BC1511A8D236200BE8BA4 /* FBSDKTimeSpentData.h in Headers */, F952EA482339403900B20652 /* FBSDKMetadataIndexer.h in Headers */, - F413881E24C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, 891687D21AB33CA200F55364 /* FBSDKIcon.h in Headers */, 52963A92215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.h in Headers */, 52963AA82159A13400C7B252 /* FBSDKMeasurementEvent_Internal.h in Headers */, 9D195CC81B9FE2E000BD6BEC /* FBSDKContainerViewController.h in Headers */, 9D0BC1661A8E892C00BE8BA4 /* FBSDKAppEventsState.h in Headers */, - F92F8F7E22BA274300494727 /* FBSDKURLSessionTask.h in Headers */, 894C0AED1A6F1DAB009137EF /* FBSDKBridgeAPIProtocolType.h in Headers */, 899C3D021A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h in Headers */, - 5D9A704C23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, 890414891A64893100617215 /* FBSDKMutableCopying.h in Headers */, - C5DFB84322CBC1EB0086E16C /* FBSDKTypeUtility.h in Headers */, C5696FA3209CCEB4009C931F /* FBSDKSwizzler.h in Headers */, 9D3AF4891A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.h in Headers */, 9D0BC14F1A8D236200BE8BA4 /* FBSDKPaymentObserver.h in Headers */, @@ -2899,7 +3071,6 @@ 5DBC72D12373793300A9D859 /* FBSDKModelManager.h in Headers */, C4FC99D9202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.h in Headers */, 52963A94215992F400C7B252 /* FBSDKWebViewAppLinkResolver.h in Headers */, - 5D9A705523261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, 5D4360DB23219F7900254DF7 /* FBSDKCrashObserver.h in Headers */, 89F2038B1AA960FA0053499E /* FBSDKBridgeAPIProtocolWebV2.h in Headers */, 893F448B1A642F11001DB0B6 /* FBSDKInternalUtility.h in Headers */, @@ -2917,23 +3088,23 @@ 89830F2B1A7805D100226ABB /* FBSDKServerConfigurationManager.h in Headers */, 033429B220894D4700C94913 /* FBSDKAccessTokenExpirer.h in Headers */, 9DF2A3FF1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.h in Headers */, + B3C20ACD250B100F00DEC008 /* FBSDKAccessToken+Internal.h in Headers */, 52963AA3215993C100C7B252 /* FBSDKURL_Internal.h in Headers */, 9DC6589B1A6EE5CD00B85AAF /* FBSDKGraphRequest+Internal.h in Headers */, 89C8B1991A8D7A15009B07F5 /* FBSDKUtility.h in Headers */, 9D34A11F1A5F038300C37317 /* FBSDKApplicationDelegate.h in Headers */, 9DBA6A371A80267400B4DE6A /* FBSDKColor.h in Headers */, - 5D4361152321C30400254DF7 /* FBSDKCrashObserving.h in Headers */, FD9E155C23777AF700A005EC /* FBSDKTensor.hpp in Headers */, 89830F331A78060A00226ABB /* FBSDKDialogConfiguration.h in Headers */, 520223F71D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h in Headers */, F420D1882433BABC00D4FA82 /* FBSDKMonitoringConfiguration.h in Headers */, - 5263EDBE215D97ED00FAAB0C /* FBSDKUserDataStore.h in Headers */, C5696F97209BBC35009C931F /* FBSDKCodelessParameterComponent.h in Headers */, 52963A9F215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h in Headers */, 894C0B091A702194009137EF /* FBSDKCrypto.h in Headers */, 89688B471AA62E3B00A98519 /* FBSDKUIUtility.h in Headers */, 81C969321C114723002FC037 /* FBSDKDynamicFrameworkLoader.h in Headers */, 9DE1F3CD1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.h in Headers */, + F9CBE51124E085CD0097B442 /* FBSDKSKAdNetworkReporter.h in Headers */, 52963AA5215993C100C7B252 /* FBSDKAppLink_Internal.h in Headers */, 894C0ACE1A6F0D3F009137EF /* FBSDKApplicationDelegate+Internal.h in Headers */, 89D4AE861A7FFEFC00DB8C72 /* FBSDKBridgeAPIRequest+Private.h in Headers */, @@ -2949,8 +3120,10 @@ 89830F2F1A7805E100226ABB /* FBSDKServerConfiguration.h in Headers */, 9D0BC15F1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.h in Headers */, 9D3AF4601A9EC24800EEF724 /* FBSDKErrorRecoveryConfiguration.h in Headers */, + F468B23424C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, FD9E154D23777AC900A005EC /* FBSDKModelRuntime.hpp in Headers */, 9D0BC1571A8D23E200BE8BA4 /* FBSDKAppEvents.h in Headers */, + C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */, 9DC658951A6EE5C500B85AAF /* FBSDKGraphRequest.h in Headers */, C5188DF9222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */, 894C0AF61A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */, @@ -2961,15 +3134,16 @@ C5D25D3621795B790037B13D /* FBSDKCodelessIndexer.h in Headers */, F4210E2E241B00790061F56D /* FBSDKMethodUsageMonitor.h in Headers */, 5D6DF16A2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, + F468B24424C2399900979F8D /* FBSDKTypeUtility.h in Headers */, 52963A88215992F400C7B252 /* FBSDKAppLinkReturnToRefererController.h in Headers */, C5696F77209BBC35009C931F /* FBSDKCodelessPathComponent.h in Headers */, - F9098FC322BC332C00857C2D /* FBSDKURLSession.h in Headers */, 9DC6589E1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.h in Headers */, 9D32A8411A69941A000A936D /* FBSDKKeychainStore.h in Headers */, 9D7E7E611ADF038800F53E38 /* FBSDKTestUsersManager.h in Headers */, C5C7B74A22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */, 5F7063FB1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h in Headers */, 9D32A8451A699459000A936D /* FBSDKAccessTokenCache.h in Headers */, + F943112124FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h in Headers */, 52963A80215992F400C7B252 /* FBSDKAppLinkNavigation.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2980,14 +3154,15 @@ files = ( 9D6DEECE1BC23A56001A94ED /* FBSDKKeychainStoreViaBundleID.h in Headers */, 5D6DF16C2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, + F468B23624C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, 9DB0FA901BC22AE9005EB8B1 /* FBSDKError.h in Headers */, 9D65383B1BF413B3008A08E9 /* FBSDKButton.h in Headers */, 9D6DEEB91BC2389F001A94ED /* FBSDKErrorRecoveryConfiguration.h in Headers */, 9DC1DD851BC462B0000D5AD5 /* FBSDKApplicationDelegate.h in Headers */, + F468B2A024C2457000979F8D /* FBSDKRestrictiveData.h in Headers */, 9D10A68F1CB38DE600F42AC1 /* FBSDKDeviceViewControllerBase.h in Headers */, 9D6DEECC1BC23A46001A94ED /* FBSDKDialogConfiguration.h in Headers */, 9DB0FA921BC22B1A005EB8B1 /* FBSDKInternalUtility.h in Headers */, - F413882024C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, FD147F682387215D000B216E /* FBSDKRestrictiveDataFilterManager.h in Headers */, 9D10A6821CB3892E00F42AC1 /* FBSDKModalFormPresentationController.h in Headers */, 9DC277921DAF4D6B004F4AB5 /* FBSDKSmartDeviceDialogView.h in Headers */, @@ -2998,19 +3173,20 @@ 9DB0FA871BC1CDA7005EB8B1 /* FBSDKGraphRequestConnection.h in Headers */, 9D10A68A1CB38CE500F42AC1 /* FBSDKDeviceViewControllerBase+Internal.h in Headers */, 9DB0FAAC1BC22DA7005EB8B1 /* FBSDKCoreKit+Internal.h in Headers */, - C5C4B3E92276B88600CA3706 /* FBSDKTypeUtility.h in Headers */, 9DA1C80F1BC3003300A76C9E /* FBSDKCoreKit.h in Headers */, F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */, F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */, 5DB7B07E230363190012E8CB /* FBSDKInstrumentManager.h in Headers */, F42004912416C30300AD7006 /* FBSDKMonitor.h in Headers */, 9D9E16AE1CB46C8900C8B68F /* FBSDKDeviceButton.h in Headers */, + F468B26624C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */, 9D6DEEB41BC23855001A94ED /* FBSDKAccessTokenCache.h in Headers */, 9D6DEEB21BC23838001A94ED /* FBSDKAppEventsState.h in Headers */, 9DB0FA8A1BC1CED0005EB8B1 /* FBSDKAppEvents+Internal.h in Headers */, 52D4F0D41D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */, 9D6DEEDB1BC24295001A94ED /* FBSDKTestUsersManager.h in Headers */, 9D6DEED11BC23A93001A94ED /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, + F468B22E24C2399900979F8D /* FBSDKBasicUtility.h in Headers */, 9DB0FAA01BC22CF5005EB8B1 /* FBSDKGraphRequestBody.h in Headers */, 033429C9208951E400C94913 /* FBSDKAccessTokenExpirer.h in Headers */, 9DB0FAA21BC22D00005EB8B1 /* FBSDKGraphRequestDataAttachment.h in Headers */, @@ -3029,39 +3205,37 @@ 9D65383C1BF413CC008A08E9 /* FBSDKButton+Subclass.h in Headers */, 9DB0FA941BC22B5F005EB8B1 /* FBSDKSettings.h in Headers */, F4A52B00242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */, - 5D9A704E23261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, 9D6DEEAB1BC236D6001A94ED /* FBSDKAppEventsDeviceInfo.h in Headers */, 9D65383F1BF44F9F008A08E9 /* FBSDKUIUtility.h in Headers */, 9DB0FA8B1BC1CED8005EB8B1 /* FBSDKAppEvents.h in Headers */, + F468B23E24C2399900979F8D /* FBSDKCrashObserving.h in Headers */, F9FD9A6421659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */, + F468B24624C2399900979F8D /* FBSDKTypeUtility.h in Headers */, 9DB0FA9A1BC22BE5005EB8B1 /* FBSDKErrorConfiguration.h in Headers */, 9DB0FA8E1BC22ACA005EB8B1 /* FBSDKConstants.h in Headers */, 9D6DEEBC1BC238EE001A94ED /* FBSDKMath.h in Headers */, + F9A06DD12510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, 81C969331C114723002FC037 /* FBSDKDynamicFrameworkLoader.h in Headers */, 9D6DEED01BC23A71001A94ED /* FBSDKServerConfiguration.h in Headers */, 9DB0FAA81BC22D6A005EB8B1 /* FBSDKGraphRequestPiggybackManager.h in Headers */, + C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */, 9DB0FA8C1BC1CEEC005EB8B1 /* FBSDKAppEventsUtility.h in Headers */, 5D90CDE82343D4D200AF326A /* FBSDKCrashShield.h in Headers */, - 5D4361172321C30400254DF7 /* FBSDKCrashObserving.h in Headers */, - F9098FC522BC332C00857C2D /* FBSDKURLSession.h in Headers */, 9DB0FA821BC1CB93005EB8B1 /* FBSDKCopying.h in Headers */, - C5C4B3EF2276B88600CA3706 /* FBSDKBasicUtility.h in Headers */, - F92F8F8022BA274300494727 /* FBSDKURLSessionTask.h in Headers */, 9DB0FAA41BC22D17005EB8B1 /* FBSDKLogger.h in Headers */, 9DB0FA9E1BC22CB0005EB8B1 /* FBSDKGraphRequest.h in Headers */, 9D28F1951DB14DBB0057D709 /* FBSDKImageDownloader.h in Headers */, 9D9E16B11CB46D3C00C8B68F /* FBSDKDeviceButton+Internal.h in Headers */, 9DB0FA9D1BC22CA2005EB8B1 /* FBSDKGraphRequest+Internal.h in Headers */, 9D65383D1BF44F7D008A08E9 /* FBSDKApplicationDelegate+Internal.h in Headers */, - 5263EDD9215D98BC00FAAB0C /* FBSDKUserDataStore.h in Headers */, F462DBFE23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */, F4210E30241B00790061F56D /* FBSDKMethodUsageMonitor.h in Headers */, 5D4360DD23219F7900254DF7 /* FBSDKCrashObserver.h in Headers */, 9D6DEECA1BC23A36001A94ED /* FBSDKServerConfigurationManager.h in Headers */, + F9A06DCB2510FAF6007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, F462DC0123B9578E00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */, 9D6DEEB61BC2386C001A94ED /* FBSDKAppEventsStateManager.h in Headers */, 9DDC112B1BEC413D00A88306 /* FBSDKLogo.h in Headers */, - 5D9A705723261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, F42004712416BCC700AD7006 /* FBSDKMonitorEntry.h in Headers */, F420D18A2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.h in Headers */, 9DB0FAA61BC22D53005EB8B1 /* FBSDKGraphRequestMetadata.h in Headers */, @@ -3075,14 +3249,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C5C4B3EB2276B88600CA3706 /* FBSDKTypeUtility.h in Headers */, - C5C4B3F12276B88600CA3706 /* FBSDKBasicUtility.h in Headers */, - 5D9A703A23261D4A00BF9783 /* FBSDKCrashObserving.h in Headers */, - 5D9A705023261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, - F92F8F8A22BA275A00494727 /* FBSDKURLSessionTask.h in Headers */, - F9098FC722BC332C00857C2D /* FBSDKURLSession.h in Headers */, - 5D9A705923261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, - F413882224C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, + F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3090,14 +3258,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C5C4B3EC2276B88600CA3706 /* FBSDKTypeUtility.h in Headers */, - C5C4B3F22276B88600CA3706 /* FBSDKBasicUtility.h in Headers */, - 5D9A703C23261D4C00BF9783 /* FBSDKCrashObserving.h in Headers */, - 5D9A705223261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, - F92F8F8C22BA275C00494727 /* FBSDKURLSessionTask.h in Headers */, - F9098FC922BC332C00857C2D /* FBSDKURLSession.h in Headers */, - 5D9A705B23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, - F413882424C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, + F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3105,14 +3267,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C5C4B4D92276BA7000CA3706 /* FBSDKBasicUtility.h in Headers */, - C5C4B4DA2276BA7000CA3706 /* FBSDKTypeUtility.h in Headers */, - 5D9A703B23261D4B00BF9783 /* FBSDKCrashObserving.h in Headers */, - 5D9A705123261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, - F92F8F8B22BA275B00494727 /* FBSDKURLSessionTask.h in Headers */, - F9098FC822BC332C00857C2D /* FBSDKURLSession.h in Headers */, - 5D9A705A23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, - F413882324C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, + F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3120,14 +3276,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - C5C4B4E42276BA8D00CA3706 /* FBSDKBasicUtility.h in Headers */, - C5C4B4E52276BA8D00CA3706 /* FBSDKTypeUtility.h in Headers */, - 5D9A703D23261D4D00BF9783 /* FBSDKCrashObserving.h in Headers */, - 5D9A705323261D6900BF9783 /* FBSDKCrashHandler.h in Headers */, - F92F8F8D22BA275D00494727 /* FBSDKURLSessionTask.h in Headers */, - F9098FCA22BC332C00857C2D /* FBSDKURLSession.h in Headers */, - 5D9A705C23261D6900BF9783 /* FBSDKLibAnalyzer.h in Headers */, - F413882524C76E0A001BC075 /* FBSDKSafeCast.h in Headers */, + F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3621,35 +3771,33 @@ 814AC7E41D1B528900D61E6C /* FBSDKAppEventsUtility.m in Sources */, 814AC7E51D1B528900D61E6C /* FBSDKServerConfigurationManager.m in Sources */, 814AC7E61D1B528900D61E6C /* FBSDKAccessTokenCache.m in Sources */, + F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E323219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 814AC7E71D1B528900D61E6C /* FBSDKUtility.m in Sources */, 814AC7E81D1B528900D61E6C /* FBSDKBase64.m in Sources */, F420D1912433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, + F468B34524C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 814AC7E91D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 814AC7EA1D1B528900D61E6C /* FBSDKGraphRequestMetadata.m in Sources */, 814AC7EB1D1B528900D61E6C /* FBSDKServerConfiguration.m in Sources */, 814AC7EC1D1B528900D61E6C /* FBSDKDynamicFrameworkLoader.m in Sources */, F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 814AC7ED1D1B528900D61E6C /* FBSDKDialogConfiguration.m in Sources */, + F468B30D24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 814AC7EE1D1B528900D61E6C /* FBSDKKeychainStoreViaBundleID.m in Sources */, - F9098FCE22BC332C00857C2D /* FBSDKURLSession.m in Sources */, FD147F672387215A000B216E /* FBSDKRestrictiveDataFilterManager.m in Sources */, - 5D9A706123261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, 814AC7EF1D1B528900D61E6C /* FBSDKInternalUtility.m in Sources */, 814AC7F01D1B528900D61E6C /* FBSDKConstants.m in Sources */, - 5D9A704623261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, 4AF47CF41F42468E00A57A67 /* FBSDKDeviceUtilities.m in Sources */, 814AC7F11D1B528900D61E6C /* FBSDKDeviceViewControllerBase.m in Sources */, F4A52B17242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */, 814AC7F21D1B528900D61E6C /* FBSDKAppEventsState.m in Sources */, + F4FE998224D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 814AC7F31D1B528900D61E6C /* FBSDKPaymentObserver.m in Sources */, - C5C4B3F72276B88600CA3706 /* FBSDKTypeUtility.m in Sources */, F9FD9A8021659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 814AC7F41D1B528900D61E6C /* FBSDKErrorRecoveryAttempter.m in Sources */, - 5DEF22D2226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */, 814AC7F51D1B528900D61E6C /* FBSDKButton.m in Sources */, - F92F8F8422BA275200494727 /* FBSDKURLSessionTask.m in Sources */, 814AC7F61D1B528900D61E6C /* FBSDKKeychainStore.m in Sources */, 814AC7F71D1B528900D61E6C /* FBSDKGraphRequestDataAttachment.m in Sources */, F4D8D8E52422887600C28384 /* FBSDKMonitorNetworker.m in Sources */, @@ -3663,20 +3811,26 @@ F42004982416C30300AD7006 /* FBSDKMonitor.m in Sources */, 814AC7FC1D1B528900D61E6C /* FBSDKAccessToken.m in Sources */, 814AC7FD1D1B528900D61E6C /* FBSDKGraphRequestBody.m in Sources */, + F468B34D24C25AB600979F8D /* FBSDKURLSession.m in Sources */, C5C7B75122D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, 814AC7FE1D1B528900D61E6C /* FBSDKErrorConfiguration.m in Sources */, + F9A06DD62510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, C554DB1A2304D11A00A32E8B /* FBSDKErrorReport.m in Sources */, 814AC7FF1D1B528900D61E6C /* FBSDKViewImpressionTracker.m in Sources */, 814AC8001D1B528900D61E6C /* FBSDKSettings.m in Sources */, + F468B31D24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 814AC8021D1B528900D61E6C /* FBSDKAppEvents.m in Sources */, 814AC8031D1B528900D61E6C /* FBSDKTestUsersManager.m in Sources */, C5696FAA209CCEB4009C931F /* FBSDKSwizzler.m in Sources */, - F413883824C76E78001BC075 /* FBSDKSafeCast.m in Sources */, 814AC8041D1B528900D61E6C /* FBSDKGraphRequest.m in Sources */, 52D4F0D21D91A18F0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 814AC8051D1B528900D61E6C /* FBSDKLogo.m in Sources */, + F4F98C5624CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, + C57044DA24E26678009637AD /* FBSDKUserDataStore.m in Sources */, 814AC8061D1B528900D61E6C /* FBSDKDeviceButton.m in Sources */, 814AC8071D1B528900D61E6C /* FBSDKGraphRequestConnection.m in Sources */, + F9A06DCA2510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, + F468B32524C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 814AC8081D1B528900D61E6C /* FBSDKErrorRecoveryConfiguration.m in Sources */, 814AC8091D1B528900D61E6C /* FBSDKApplicationDelegate.m in Sources */, 814AC80B1D1B528900D61E6C /* FBSDKDeviceDialogView.m in Sources */, @@ -3688,7 +3842,6 @@ 814AC80F1D1B528900D61E6C /* FBSDKTimeSpentData.m in Sources */, 814AC8121D1B528900D61E6C /* FBSDKGraphRequestPiggybackManager.m in Sources */, 814AC8131D1B528900D61E6C /* FBSDKError.m in Sources */, - 5263EDDC215D98C200FAAB0C /* FBSDKUserDataStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3701,22 +3854,27 @@ 81B71D021D19C87400933E93 /* FBSDKAppEventsStateManager.m in Sources */, 81B71D031D19C87400933E93 /* FBSDKServerConfigurationManager.m in Sources */, 81B71D041D19C87400933E93 /* FBSDKGraphRequest.m in Sources */, + F9CBE51424E090590097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, 81B71D051D19C87400933E93 /* FBSDKContainerViewController.m in Sources */, 81B71D061D19C87400933E93 /* FBSDKAccessTokenCache.m in Sources */, 81B71D071D19C87400933E93 /* FBSDKCrypto.m in Sources */, + F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 81B71D081D19C87400933E93 /* FBSDKAppEventsState.m in Sources */, 52963A87215992F400C7B252 /* FBSDKWebViewAppLinkResolver.m in Sources */, 81B71D091D19C87400933E93 /* FBSDKCloseIcon.m in Sources */, F4BF22AA241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 5D41131B229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m in Sources */, 81B71D0A1D19C87400933E93 /* FBSDKBase64.m in Sources */, + F468B34B24C25AB600979F8D /* FBSDKURLSession.m in Sources */, 81B71D0B1D19C87400933E93 /* FBSDKBridgeAPIProtocolWebV2.m in Sources */, 81B71D0C1D19C87400933E93 /* FBSDKGraphRequestBody.m in Sources */, + F943110524F8D615002441F1 /* FBSDKSKAdNetworkRule.m in Sources */, 81B71D0D1D19C87400933E93 /* FBSDKUtility.m in Sources */, 81B71D0E1D19C87400933E93 /* FBSDKTestUsersManager.m in Sources */, 81B71D0F1D19C87400933E93 /* FBSDKMeasurementEventListener.m in Sources */, 81B71D101D19C87400933E93 /* FBSDKProfilePictureView.m in Sources */, 81B71D111D19C87400933E93 /* FBSDKTriStateBOOL.m in Sources */, + F9A06DD42510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, 5DBC72D92373795600A9D859 /* FBSDKModelManager.mm in Sources */, 81B71D121D19C87400933E93 /* FBSDKLogger.m in Sources */, 81B71D131D19C87400933E93 /* FBSDKApplicationDelegate.m in Sources */, @@ -3736,43 +3894,47 @@ 9D28F1981DB14DBB0057D709 /* FBSDKImageDownloader.m in Sources */, 81B71D1C1D19C87400933E93 /* FBSDKViewImpressionTracker.m in Sources */, C5696F54209BBC35009C931F /* FBSDKViewHierarchy.m in Sources */, - 5D9A704423261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, C5696F6C209BBC35009C931F /* FBSDKCodelessParameterComponent.m in Sources */, + F916581724F6BB5100BB759A /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */, 81B71D1D1D19C87400933E93 /* FBSDKBridgeAPIRequest.m in Sources */, 81B71D1E1D19C87400933E93 /* FBSDKAppEventsDeviceInfo.m in Sources */, - 5DEF22D0226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */, F42004962416C30300AD7006 /* FBSDKMonitor.m in Sources */, + F468B31B24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 81B71D1F1D19C87400933E93 /* FBSDKError.m in Sources */, 81B71D231D19C87400933E93 /* FBSDKAudioResourceLoader.m in Sources */, 81B71D241D19C87400933E93 /* FBSDKLogo.m in Sources */, + F468B35324C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, F4210E35241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 81B71D251D19C87400933E93 /* FBSDKPaymentObserver.m in Sources */, 81B71D261D19C87400933E93 /* FBSDKBridgeAPIResponse.m in Sources */, 81B71D271D19C87400933E93 /* FBSDKErrorRecoveryConfiguration.m in Sources */, 81B71D291D19C87400933E93 /* FBSDKGraphErrorRecoveryProcessor.m in Sources */, - 5263EDD8215D98B000FAAB0C /* FBSDKUserDataStore.m in Sources */, 52963A8F215992F400C7B252 /* FBSDKAppLinkReturnToRefererController.m in Sources */, 81B71D2B1D19C87400933E93 /* FBSDKTimeSpentData.m in Sources */, + F9A06DBA2510FAD3007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, 81B71D2C1D19C87400933E93 /* FBSDKBridgeAPIProtocolWebV1.m in Sources */, 81B71D2D1D19C87400933E93 /* FBSDKMath.m in Sources */, 81B71D2E1D19C87400933E93 /* FBSDKWebDialog.m in Sources */, C5696F60209BBC35009C931F /* FBSDKEventBinding.m in Sources */, 0384CEBB208E60660013D404 /* FBSDKAccessTokenExpirer.m in Sources */, - C5C4B3F42276B88600CA3706 /* FBSDKTypeUtility.m in Sources */, 81B71D2F1D19C87400933E93 /* FBSDKColor.m in Sources */, + F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 81B71D301D19C87400933E93 /* FBSDKAppLinkResolver.m in Sources */, F420D18F2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 81B71D311D19C87400933E93 /* FBSDKIcon.m in Sources */, + F468B2A724C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, E4416C1623F61917009CCBFA /* FBSDKModelParser.mm in Sources */, 5D90CDE02343D4BD00AF326A /* FBSDKCrashShield.m in Sources */, 81B71D321D19C87400933E93 /* FBSDKConstants.m in Sources */, 81B71D331D19C87400933E93 /* FBSDKAppEventsUtility.m in Sources */, 5DB7B08F2303632E0012E8CB /* FBSDKInstrumentManager.m in Sources */, + F468B30B24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, C5696F48209BBC35009C931F /* FBSDKCodelessPathComponent.m in Sources */, F46FA64024533F690060C902 /* Settings.swift in Sources */, - 5D9A705F23261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, 81B71D341D19C87400933E93 /* FBSDKSettings.m in Sources */, 52963A85215992F400C7B252 /* FBSDKAppLink.m in Sources */, + C57044D824E26678009637AD /* FBSDKUserDataStore.m in Sources */, + F943113224FB25A7002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */, BFC02459237B6B9C00A596EE /* FBSDKFeatureExtractor.m in Sources */, 52963A77215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */, C5D25D3921795B790037B13D /* FBSDKCodelessIndexer.m in Sources */, @@ -3788,27 +3950,26 @@ F4D8D8E32422887600C28384 /* FBSDKMonitorNetworker.m in Sources */, 5D6DF1642398E28000AC2D6C /* FBSDKEventDeactivationManager.m in Sources */, 5D4360E123219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, + F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, F9FD9A7E21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, 81B71D3D1D19C87400933E93 /* FBSDKAppEvents.m in Sources */, FDAF4A912395D27D00711C4C /* FBSDKModelUtility.m in Sources */, 81B71D3E1D19C87400933E93 /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, F4713D7D2375DA8200748692 /* FBSDKSuggestedEventsIndexer.m in Sources */, - F9098FCC22BC332C00857C2D /* FBSDKURLSession.m in Sources */, F4A52B05242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.m in Sources */, 52963AAF2159A16E00C7B252 /* FBSDKMeasurementEvent.m in Sources */, 81B71D3F1D19C87400933E93 /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */, 81B71D401D19C87400933E93 /* FBSDKWebDialogView.m in Sources */, 81B71D411D19C87400933E93 /* FBSDKErrorConfiguration.m in Sources */, C4FC99F2202CD56D0038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, + F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 52D4F0BC1D91A18D0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 81B71D431D19C87400933E93 /* FBSDKServerConfiguration.m in Sources */, F952EA492339405D00B20652 /* FBSDKMetadataIndexer.m in Sources */, 81B71D441D19C87400933E93 /* FBSDKMaleSilhouetteIcon.m in Sources */, C5C7B74F22D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, - F413883624C76E78001BC075 /* FBSDKSafeCast.m in Sources */, C554DB0B2304D11200A32E8B /* FBSDKErrorReport.m in Sources */, - F92F8F8222BA274300494727 /* FBSDKURLSessionTask.m in Sources */, F46FA63C24533F450060C902 /* AccessToken.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3822,22 +3983,27 @@ 9D0BC1601A8D428700BE8BA4 /* FBSDKAppEventsStateManager.m in Sources */, 89830F2C1A7805D100226ABB /* FBSDKServerConfigurationManager.m in Sources */, 9DC658961A6EE5C500B85AAF /* FBSDKGraphRequest.m in Sources */, + F9CBE51224E085CD0097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */, C4FC99DA202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, 9D32A8461A699459000A936D /* FBSDKAccessTokenCache.m in Sources */, + F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 894C0B0A1A702194009137EF /* FBSDKCrypto.m in Sources */, 9D0BC1671A8E892C00BE8BA4 /* FBSDKAppEventsState.m in Sources */, + F468B31A24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 89D652851A855A6000BB651C /* FBSDKCloseIcon.m in Sources */, F4BF22A9241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 52963A86215992F400C7B252 /* FBSDKWebViewAppLinkResolver.m in Sources */, 5D41131A229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m in Sources */, 894C0B121A7021F8009137EF /* FBSDKBase64.m in Sources */, 89F2038C1AA960FA0053499E /* FBSDKBridgeAPIProtocolWebV2.m in Sources */, + F94310F524F8D608002441F1 /* FBSDKSKAdNetworkRule.m in Sources */, 9DC658A61A6EE7E200B85AAF /* FBSDKGraphRequestBody.m in Sources */, 89C8B19A1A8D7A15009B07F5 /* FBSDKUtility.m in Sources */, 9D7E7E621ADF038800F53E38 /* FBSDKTestUsersManager.m in Sources */, 7EB63D9F1A9BE730003A7AED /* FBSDKMeasurementEventListener.m in Sources */, 899C3CF91A8BF73A00EA8658 /* FBSDKProfilePictureView.m in Sources */, + F9A06DD32510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, 5DBC72D82373795600A9D859 /* FBSDKModelManager.mm in Sources */, 89D05A961AA0E89B00609300 /* FBSDKTriStateBOOL.m in Sources */, 9D6999FF1A76E166003AE384 /* FBSDKLogger.m in Sources */, @@ -3853,37 +4019,41 @@ 52963A82215992F400C7B252 /* FBSDKURL.m in Sources */, 893F448C1A642F11001DB0B6 /* FBSDKInternalUtility.m in Sources */, ADEA17741B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m in Sources */, + F468B32224C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, F46FA63D24533F610060C902 /* Permission.swift in Sources */, 7E30917A1AA907E0004E91D5 /* FBSDKAppLinkUtility.m in Sources */, 89688B631AA64C5E00A98519 /* FBSDKViewImpressionTracker.m in Sources */, 9D28F1971DB14DBB0057D709 /* FBSDKImageDownloader.m in Sources */, - 5D9A704323261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, 894C0AD21A6F15F7009137EF /* FBSDKBridgeAPIRequest.m in Sources */, C5696F53209BBC35009C931F /* FBSDKViewHierarchy.m in Sources */, C5696F6B209BBC35009C931F /* FBSDKCodelessParameterComponent.m in Sources */, F42004952416C30300AD7006 /* FBSDKMonitor.m in Sources */, - 5DEF22CF226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */, 5F7064091AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m in Sources */, 894C0B621A7150AC009137EF /* FBSDKError.m in Sources */, + F9DE56BB24F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */, F4210E34241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 89D05AAA1AA1134000609300 /* FBSDKAudioResourceLoader.m in Sources */, + F468B30A24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 893F449A1A6444DF001DB0B6 /* FBSDKLogo.m in Sources */, 9D0BC1501A8D236200BE8BA4 /* FBSDKPaymentObserver.m in Sources */, 894C0AE01A6F1D1B009137EF /* FBSDKBridgeAPIResponse.m in Sources */, 9D3AF4611A9EC24800EEF724 /* FBSDKErrorRecoveryConfiguration.m in Sources */, 9DD50A3D1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.m in Sources */, 52963A8E215992F400C7B252 /* FBSDKAppLinkReturnToRefererController.m in Sources */, + F9A06DB92510FAD3007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, 9D0BC1521A8D236200BE8BA4 /* FBSDKTimeSpentData.m in Sources */, 89D4AEA01A803F1E00DB8C72 /* FBSDKBridgeAPIProtocolWebV1.m in Sources */, 893F44AD1A644744001DB0B6 /* FBSDKMath.m in Sources */, 89FB8C421A8425C4003CAE60 /* FBSDKWebDialog.m in Sources */, C5696F5F209BBC35009C931F /* FBSDKEventBinding.m in Sources */, 033429B320894D4700C94913 /* FBSDKAccessTokenExpirer.m in Sources */, - C5C4B3F32276B88600CA3706 /* FBSDKTypeUtility.m in Sources */, F420D18E2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 9DBA6A311A80265A00B4DE6A /* FBSDKColor.m in Sources */, E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */, + F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 7E5557371A8D833100344F86 /* FBSDKAppLinkResolver.m in Sources */, + F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, + F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */, 891687D31AB33CA200F55364 /* FBSDKIcon.m in Sources */, 5D90CDDF2343D4BD00AF326A /* FBSDKCrashShield.m in Sources */, BFC02448237B6A9A00A596EE /* FBSDKFeatureExtractor.m in Sources */, @@ -3892,9 +4062,11 @@ 5DB7B08E2303632E0012E8CB /* FBSDKInstrumentManager.m in Sources */, F46FA63F24533F690060C902 /* Settings.swift in Sources */, C5696F47209BBC35009C931F /* FBSDKCodelessPathComponent.m in Sources */, - 5D9A705E23261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, + C57044D724E26678009637AD /* FBSDKUserDataStore.m in Sources */, + F943112224FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */, 9DA8303D1A6999EC00770955 /* FBSDKSettings.m in Sources */, 52963A84215992F400C7B252 /* FBSDKAppLink.m in Sources */, + F468B34224C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 52963A76215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */, 891687EF1AB38C7C00F55364 /* FBSDKButton.m in Sources */, C5D25D3821795B790037B13D /* FBSDKCodelessIndexer.m in Sources */, @@ -3912,10 +4084,8 @@ 9D0BC1581A8D23E200BE8BA4 /* FBSDKAppEvents.m in Sources */, FDAF4A8D2395D21700711C4C /* FBSDKModelUtility.m in Sources */, F9FD9A7D21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, - F9169B842155A03C00FA1789 /* FBSDKUserDataStore.m in Sources */, BF247C832374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m in Sources */, F4A52B04242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.m in Sources */, - F9098FCB22BC332C00857C2D /* FBSDKURLSession.m in Sources */, 9DF18BBA1A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 52963AAE2159A16E00C7B252 /* FBSDKMeasurementEvent.m in Sources */, 894C0AF71A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */, @@ -3924,12 +4094,11 @@ 520223F81D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m in Sources */, 9DE1F3CE1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 89830F301A7805E100226ABB /* FBSDKServerConfiguration.m in Sources */, + F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */, FD8E438122FBF8F1008B6DD3 /* FBSDKErrorReport.m in Sources */, 899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */, - F413883524C76E78001BC075 /* FBSDKSafeCast.m in Sources */, C5C7B74E22D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, - F92F8F8122BA274300494727 /* FBSDKURLSessionTask.m in Sources */, F46FA62D24533F450060C902 /* AccessToken.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3939,21 +4108,27 @@ buildActionMask = 2147483647; files = ( F4A52B0B242A99C8005F65CE /* FBSDKPerformanceMonitorTests.m in Sources */, + F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */, 9DF18BCB1A9F2517000F6748 /* FBSDKErrorConfigurationTests.m in Sources */, 9D18A8E91A95495D00A41042 /* FBSDKAppEventsUtilityTests.m in Sources */, + F4A826B524EC6F9900EB2CD4 /* SampleUserProfile.m in Sources */, F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */, + F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m in Sources */, + F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */, 7E55573C1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m in Sources */, 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */, + F496E58F24E49DBC006231A2 /* SampleAppEvents.m in Sources */, 9D18A8DB1A95405A00A41042 /* FBSDKAppEventsStateTests.m in Sources */, + F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */, F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */, E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */, + F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */, BF5D97C3242EC2D10096D7AA /* FBSDKFeatureExtractorTests.m in Sources */, 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.m in Sources */, 7E253D831A8EB76500CCCFE7 /* FBSDKCoreKitTestUtility.m in Sources */, 5D59BFFD23A705010008CA5A /* FBSDKCrashHandlerTests.m in Sources */, F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */, C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */, - F4B3CA3222B3FED80098ADF5 /* ExampleSwiftTests.swift in Sources */, F4E50155243648A100C99262 /* FBSDKServerConfigurationFixtures.m in Sources */, F4D8D8FA242293ED00C28384 /* FBSDKMonitorNetworkerTests.m in Sources */, 894C0B4A1A70524F009137EF /* FBSDKBase64Tests.m in Sources */, @@ -3961,21 +4136,29 @@ F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */, 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */, F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */, + F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */, 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m in Sources */, + F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */, 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */, + F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m in Sources */, 7E253D811A8EAEF500CCCFE7 /* FBSDKInternalUtilityTests.m in Sources */, C5F6EC861FA24FAF009EB258 /* FBSDKPaymentObserverTests.m in Sources */, F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */, 5D497702244A3E6A00BD45C6 /* FBSDKIntegrityTests.m in Sources */, F4210E1E241AFF740061F56D /* FBSDKMethodUsageMonitorTests.m in Sources */, F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */, + F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, + F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */, F40B24C224732DD90059351C /* Fuzzer.swift in Sources */, + 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */, F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */, F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */, 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.m in Sources */, F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */, C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.m in Sources */, + F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */, + F4A826B724EC6FAD00EB2CD4 /* FBSDKProfileTests.m in Sources */, 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */, F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m in Sources */, @@ -3983,12 +4166,17 @@ F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, E493252D23F7C60E0000B63A /* FBSDKModelParserTests.mm in Sources */, + F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.m in Sources */, + F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */, 5D68D7D822BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m in Sources */, 9D3AF4661A9ED47900EEF724 /* FBSDKGraphRequestConnectionTests.m in Sources */, BF1C64E624039AD50052C580 /* FBSDKViewHierarchyTests.m in Sources */, C51122A020A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m in Sources */, C51121CB20A27EF50041DC94 /* FBSDKEventBindingTests.m in Sources */, F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */, + F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m in Sources */, + F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */, + F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */, F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4003,35 +4191,33 @@ 9DB0FA8D1BC1CEF4005EB8B1 /* FBSDKAppEventsUtility.m in Sources */, 9D6DEEC91BC23A30001A94ED /* FBSDKServerConfigurationManager.m in Sources */, 9D6DEEB31BC23850001A94ED /* FBSDKAccessTokenCache.m in Sources */, + F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E223219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 9DB0FA971BC22BC0005EB8B1 /* FBSDKUtility.m in Sources */, 9DE155411C161A66005FCF5C /* FBSDKBase64.m in Sources */, F420D1902433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, + F468B34424C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 9D6DEED21BC23ADD001A94ED /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 9DB0FAA71BC22D5B005EB8B1 /* FBSDKGraphRequestMetadata.m in Sources */, 9D6DEECF1BC23A6E001A94ED /* FBSDKServerConfiguration.m in Sources */, 81C969351C114723002FC037 /* FBSDKDynamicFrameworkLoader.m in Sources */, F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 9D6DEECB1BC23A43001A94ED /* FBSDKDialogConfiguration.m in Sources */, + F468B30C24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 9D6DEECD1BC23A53001A94ED /* FBSDKKeychainStoreViaBundleID.m in Sources */, - F9098FCD22BC332C00857C2D /* FBSDKURLSession.m in Sources */, FD147F662387215A000B216E /* FBSDKRestrictiveDataFilterManager.m in Sources */, - 5D9A706023261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, 9DB0FA931BC22B49005EB8B1 /* FBSDKInternalUtility.m in Sources */, 9DB0FA8F1BC22AD6005EB8B1 /* FBSDKConstants.m in Sources */, - 5D9A704523261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, 4AF47CF31F42468E00A57A67 /* FBSDKDeviceUtilities.m in Sources */, 9D10A6901CB38DF100F42AC1 /* FBSDKDeviceViewControllerBase.m in Sources */, F4A52B16242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */, 9D6DEEB11BC23834001A94ED /* FBSDKAppEventsState.m in Sources */, + F4FE998124D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 9D6DEEBD1BC238F5001A94ED /* FBSDKPaymentObserver.m in Sources */, - C5C4B3F62276B88600CA3706 /* FBSDKTypeUtility.m in Sources */, F9FD9A7F21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, F4210E36241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 9D6DEEB71BC23890001A94ED /* FBSDKErrorRecoveryAttempter.m in Sources */, - 5DEF22D1226A3E06004056C1 /* FBSDKBasicUtility.m in Sources */, 9D65383E1BF44F88008A08E9 /* FBSDKButton.m in Sources */, - F92F8F8322BA274300494727 /* FBSDKURLSessionTask.m in Sources */, 9D6DEEC41BC239F5001A94ED /* FBSDKKeychainStore.m in Sources */, 9DB0FAA31BC22D08005EB8B1 /* FBSDKGraphRequestDataAttachment.m in Sources */, F4D8D8E42422887600C28384 /* FBSDKMonitorNetworker.m in Sources */, @@ -4045,20 +4231,25 @@ F42004972416C30300AD7006 /* FBSDKMonitor.m in Sources */, 9D6DEEAA1BC236B9001A94ED /* FBSDKAccessToken.m in Sources */, 9DB0FAA11BC22CF9005EB8B1 /* FBSDKGraphRequestBody.m in Sources */, + F468B34C24C25AB600979F8D /* FBSDKURLSession.m in Sources */, C5C7B75022D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, 9DB0FA9B1BC22BED005EB8B1 /* FBSDKErrorConfiguration.m in Sources */, + F9A06DD52510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, C554DB192304D11900A32E8B /* FBSDKErrorReport.m in Sources */, 9D6538411BF44FB4008A08E9 /* FBSDKViewImpressionTracker.m in Sources */, 9DB0FA951BC22B79005EB8B1 /* FBSDKSettings.m in Sources */, + F468B31C24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 9D6DEEA91BC2368D001A94ED /* FBSDKAppEvents.m in Sources */, 9D6DEEE81BC2429B001A94ED /* FBSDKTestUsersManager.m in Sources */, C5696FA9209CCEB4009C931F /* FBSDKSwizzler.m in Sources */, - F413883724C76E78001BC075 /* FBSDKSafeCast.m in Sources */, 9DB0FA9F1BC22CBB005EB8B1 /* FBSDKGraphRequest.m in Sources */, 52D4F0D11D91A18F0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 9DDC112A1BEC413900A88306 /* FBSDKLogo.m in Sources */, 9D9E16AF1CB46C8E00C8B68F /* FBSDKDeviceButton.m in Sources */, + C57044D924E26678009637AD /* FBSDKUserDataStore.m in Sources */, 9DB0FA891BC1CDD0005EB8B1 /* FBSDKGraphRequestConnection.m in Sources */, + F468B32424C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, + F9A06DC92510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, 9D6DEEBA1BC238A2001A94ED /* FBSDKErrorRecoveryConfiguration.m in Sources */, 9DC1DD781BC4629F000D5AD5 /* FBSDKApplicationDelegate.m in Sources */, 9D92FC641CB320430091B6F7 /* FBSDKDeviceDialogView.m in Sources */, @@ -4066,11 +4257,11 @@ 5DB7B0902303632F0012E8CB /* FBSDKInstrumentManager.m in Sources */, F40F6569241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */, 9D28F1991DB14DBB0057D709 /* FBSDKImageDownloader.m in Sources */, + F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 9DB0FAA51BC22D1C005EB8B1 /* FBSDKLogger.m in Sources */, 9D6DEEB01BC2379C001A94ED /* FBSDKTimeSpentData.m in Sources */, 9DB0FAA91BC22D6F005EB8B1 /* FBSDKGraphRequestPiggybackManager.m in Sources */, 9DB0FA911BC22AF8005EB8B1 /* FBSDKError.m in Sources */, - 5263EDDB215D98C100FAAB0C /* FBSDKUserDataStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4078,13 +4269,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5D9A706223261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, - F92F8F8522BA275300494727 /* FBSDKURLSessionTask.m in Sources */, - 5D9A704723261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, - C5C4B3BA2276B54B00CA3706 /* FBSDKBasicUtility.m in Sources */, - C5C4B3F82276B88600CA3706 /* FBSDKTypeUtility.m in Sources */, - F9098FCF22BC332C00857C2D /* FBSDKURLSession.m in Sources */, - F413883924C76E78001BC075 /* FBSDKSafeCast.m in Sources */, + F468B35624C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, + F468B31E24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, + F468B32624C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, + F468B34624C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, + F4FE998324D906BA008879A4 /* FBSDKJSONValue.m in Sources */, + F468B30E24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, + F468B34E24C25AB600979F8D /* FBSDKURLSession.m in Sources */, + F4F98C5724CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, + C57044DB24E26678009637AD /* FBSDKUserDataStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4092,13 +4285,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5D9A706423261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, - F92F8F8722BA275500494727 /* FBSDKURLSessionTask.m in Sources */, - 5D9A704923261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, - C5C4B3C22276B67200CA3706 /* FBSDKBasicUtility.m in Sources */, - C5C4B3F92276B88600CA3706 /* FBSDKTypeUtility.m in Sources */, - F9098FD122BC332C00857C2D /* FBSDKURLSession.m in Sources */, - F413883B24C76E78001BC075 /* FBSDKSafeCast.m in Sources */, + F468B35824C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, + F468B32024C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, + F468B32824C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, + F468B34824C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, + F4FE998524D906BA008879A4 /* FBSDKJSONValue.m in Sources */, + F468B31024C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, + F468B35024C25AB600979F8D /* FBSDKURLSession.m in Sources */, + F4F98C5924CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, + C57044DD24E26678009637AD /* FBSDKUserDataStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4106,13 +4301,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5D9A706323261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, - F92F8F8622BA275400494727 /* FBSDKURLSessionTask.m in Sources */, - 5D9A704823261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, - C5C4B4D72276BA5100CA3706 /* FBSDKTypeUtility.m in Sources */, - C5C4B4D82276BA5100CA3706 /* FBSDKBasicUtility.m in Sources */, - F9098FD022BC332C00857C2D /* FBSDKURLSession.m in Sources */, - F413883A24C76E78001BC075 /* FBSDKSafeCast.m in Sources */, + F468B35724C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, + F468B31F24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, + F468B32724C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, + F468B34724C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, + F4FE998424D906BA008879A4 /* FBSDKJSONValue.m in Sources */, + F468B30F24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, + F468B34F24C25AB600979F8D /* FBSDKURLSession.m in Sources */, + F4F98C5824CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, + C57044DC24E26678009637AD /* FBSDKUserDataStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4120,13 +4317,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5D9A706523261D6900BF9783 /* FBSDKLibAnalyzer.m in Sources */, - F92F8F8822BA275600494727 /* FBSDKURLSessionTask.m in Sources */, - 5D9A704A23261D6900BF9783 /* FBSDKCrashHandler.m in Sources */, - C5C4B4DF2276BA8D00CA3706 /* FBSDKTypeUtility.m in Sources */, - C5C4B4E02276BA8D00CA3706 /* FBSDKBasicUtility.m in Sources */, - F9098FD222BC332C00857C2D /* FBSDKURLSession.m in Sources */, - F413883C24C76E78001BC075 /* FBSDKSafeCast.m in Sources */, + F468B35924C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, + F468B32124C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, + F468B32924C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, + F468B34924C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, + F4FE998624D906BA008879A4 /* FBSDKJSONValue.m in Sources */, + F468B31124C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, + F468B35124C25AB600979F8D /* FBSDKURLSession.m in Sources */, + F4F98C5A24CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, + C57044DE24E26678009637AD /* FBSDKUserDataStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4309,7 +4508,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Debug; }; @@ -4317,7 +4515,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Release; }; @@ -4325,7 +4522,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Debug; }; @@ -4333,7 +4529,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Release; }; @@ -4341,7 +4536,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Debug; }; @@ -4349,7 +4543,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Release; }; @@ -4357,7 +4550,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Debug; }; @@ -4365,7 +4557,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Release; }; @@ -4373,7 +4564,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Debug; }; @@ -4381,7 +4571,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Release; }; @@ -4389,7 +4578,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Debug; }; @@ -4397,7 +4585,6 @@ isa = XCBuildConfiguration; baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { - MODULEMAP_FILE = "$(SRCROOT)/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap"; }; name = Release; }; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index e5be72cbef..8616cce40f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -18,15 +18,20 @@ #import "FBSDKAppEvents.h" #import "FBSDKAppEvents+Internal.h" -#import "FBSDKApplicationDelegate+Internal.h" -#import +#import #import +#import + #import "FBSDKAccessToken.h" +#import "FBSDKAppEventsConfiguration.h" +#import "FBSDKAppEventsConfigurationManager.h" +#import "FBSDKAppEventsDeviceInfo.h" #import "FBSDKAppEventsState.h" #import "FBSDKAppEventsStateManager.h" #import "FBSDKAppEventsUtility.h" +#import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKConstants.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKError.h" @@ -35,21 +40,20 @@ #import "FBSDKGraphRequest+Internal.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" -#import "FBSDKRestrictiveDataFilterManager.h" #import "FBSDKPaymentObserver.h" +#import "FBSDKRestrictiveDataFilterManager.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" #import "FBSDKSettings.h" #import "FBSDKTimeSpentData.h" #import "FBSDKUtility.h" -#import "FBSDKUserDataStore.h" #if !TARGET_OS_TV -#import "FBSDKIntegrityManager.h" -#import "FBSDKEventBindingManager.h" -#import "FBSDKHybridAppEventsScriptMessageHandler.h" -#import "FBSDKModelManager.h" + #import "FBSDKEventBindingManager.h" + #import "FBSDKHybridAppEventsScriptMessageHandler.h" + #import "FBSDKIntegrityManager.h" + #import "FBSDKModelManager.h" #endif @@ -58,233 +62,223 @@ // // General purpose -FBSDKAppEventName FBSDKAppEventNameCompletedRegistration = @"fb_mobile_complete_registration"; -FBSDKAppEventName FBSDKAppEventNameViewedContent = @"fb_mobile_content_view"; -FBSDKAppEventName FBSDKAppEventNameSearched = @"fb_mobile_search"; -FBSDKAppEventName FBSDKAppEventNameRated = @"fb_mobile_rate"; -FBSDKAppEventName FBSDKAppEventNameCompletedTutorial = @"fb_mobile_tutorial_completion"; -FBSDKAppEventName FBSDKAppEventNameContact = @"Contact"; -FBSDKAppEventName FBSDKAppEventNameCustomizeProduct = @"CustomizeProduct"; -FBSDKAppEventName FBSDKAppEventNameDonate = @"Donate"; -FBSDKAppEventName FBSDKAppEventNameFindLocation = @"FindLocation"; -FBSDKAppEventName FBSDKAppEventNameSchedule = @"Schedule"; -FBSDKAppEventName FBSDKAppEventNameStartTrial = @"StartTrial"; -FBSDKAppEventName FBSDKAppEventNameSubmitApplication = @"SubmitApplication"; -FBSDKAppEventName FBSDKAppEventNameSubscribe = @"Subscribe"; -FBSDKAppEventName FBSDKAppEventNameSubscriptionHeartbeat = @"SubscriptionHeartbeat"; -FBSDKAppEventName FBSDKAppEventNameAdImpression = @"AdImpression"; -FBSDKAppEventName FBSDKAppEventNameAdClick = @"AdClick"; +FBSDKAppEventName FBSDKAppEventNameCompletedRegistration = @"fb_mobile_complete_registration"; +FBSDKAppEventName FBSDKAppEventNameViewedContent = @"fb_mobile_content_view"; +FBSDKAppEventName FBSDKAppEventNameSearched = @"fb_mobile_search"; +FBSDKAppEventName FBSDKAppEventNameRated = @"fb_mobile_rate"; +FBSDKAppEventName FBSDKAppEventNameCompletedTutorial = @"fb_mobile_tutorial_completion"; +FBSDKAppEventName FBSDKAppEventNameContact = @"Contact"; +FBSDKAppEventName FBSDKAppEventNameCustomizeProduct = @"CustomizeProduct"; +FBSDKAppEventName FBSDKAppEventNameDonate = @"Donate"; +FBSDKAppEventName FBSDKAppEventNameFindLocation = @"FindLocation"; +FBSDKAppEventName FBSDKAppEventNameSchedule = @"Schedule"; +FBSDKAppEventName FBSDKAppEventNameStartTrial = @"StartTrial"; +FBSDKAppEventName FBSDKAppEventNameSubmitApplication = @"SubmitApplication"; +FBSDKAppEventName FBSDKAppEventNameSubscribe = @"Subscribe"; +FBSDKAppEventName FBSDKAppEventNameSubscriptionHeartbeat = @"SubscriptionHeartbeat"; +FBSDKAppEventName FBSDKAppEventNameAdImpression = @"AdImpression"; +FBSDKAppEventName FBSDKAppEventNameAdClick = @"AdClick"; // Ecommerce related -FBSDKAppEventName FBSDKAppEventNameAddedToCart = @"fb_mobile_add_to_cart"; -FBSDKAppEventName FBSDKAppEventNameAddedToWishlist = @"fb_mobile_add_to_wishlist"; -FBSDKAppEventName FBSDKAppEventNameInitiatedCheckout = @"fb_mobile_initiated_checkout"; -FBSDKAppEventName FBSDKAppEventNameAddedPaymentInfo = @"fb_mobile_add_payment_info"; -FBSDKAppEventName FBSDKAppEventNameProductCatalogUpdate = @"fb_mobile_catalog_update"; -FBSDKAppEventName FBSDKAppEventNamePurchased = @"fb_mobile_purchase"; +FBSDKAppEventName FBSDKAppEventNameAddedToCart = @"fb_mobile_add_to_cart"; +FBSDKAppEventName FBSDKAppEventNameAddedToWishlist = @"fb_mobile_add_to_wishlist"; +FBSDKAppEventName FBSDKAppEventNameInitiatedCheckout = @"fb_mobile_initiated_checkout"; +FBSDKAppEventName FBSDKAppEventNameAddedPaymentInfo = @"fb_mobile_add_payment_info"; +FBSDKAppEventName FBSDKAppEventNameProductCatalogUpdate = @"fb_mobile_catalog_update"; +FBSDKAppEventName FBSDKAppEventNamePurchased = @"fb_mobile_purchase"; // Gaming related -FBSDKAppEventName FBSDKAppEventNameAchievedLevel = @"fb_mobile_level_achieved"; -FBSDKAppEventName FBSDKAppEventNameUnlockedAchievement = @"fb_mobile_achievement_unlocked"; -FBSDKAppEventName FBSDKAppEventNameSpentCredits = @"fb_mobile_spent_credits"; +FBSDKAppEventName FBSDKAppEventNameAchievedLevel = @"fb_mobile_level_achieved"; +FBSDKAppEventName FBSDKAppEventNameUnlockedAchievement = @"fb_mobile_achievement_unlocked"; +FBSDKAppEventName FBSDKAppEventNameSpentCredits = @"fb_mobile_spent_credits"; // // Public event parameter names // -FBSDKAppEventParameterName FBSDKAppEventParameterNameCurrency = @"fb_currency"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameRegistrationMethod = @"fb_registration_method"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameContentType = @"fb_content_type"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameContent = @"fb_content"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameContentID = @"fb_content_id"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameSearchString = @"fb_search_string"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameSuccess = @"fb_success"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameMaxRatingValue = @"fb_max_rating_value"; -FBSDKAppEventParameterName FBSDKAppEventParameterNamePaymentInfoAvailable = @"fb_payment_info_available"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameNumItems = @"fb_num_items"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameLevel = @"fb_level"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameDescription = @"fb_description"; -FBSDKAppEventParameterName FBSDKAppEventParameterLaunchSource = @"fb_mobile_launch_source"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameAdType = @"ad_type"; -FBSDKAppEventParameterName FBSDKAppEventParameterNameOrderID = @"fb_order_id"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameCurrency = @"fb_currency"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameRegistrationMethod = @"fb_registration_method"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameContentType = @"fb_content_type"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameContent = @"fb_content"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameContentID = @"fb_content_id"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameSearchString = @"fb_search_string"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameSuccess = @"fb_success"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameMaxRatingValue = @"fb_max_rating_value"; +FBSDKAppEventParameterName FBSDKAppEventParameterNamePaymentInfoAvailable = @"fb_payment_info_available"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameNumItems = @"fb_num_items"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameLevel = @"fb_level"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameDescription = @"fb_description"; +FBSDKAppEventParameterName FBSDKAppEventParameterLaunchSource = @"fb_mobile_launch_source"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameAdType = @"ad_type"; +FBSDKAppEventParameterName FBSDKAppEventParameterNameOrderID = @"fb_order_id"; // // Public event parameter names for DPA Catalog // -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel0 = @"fb_product_custom_label_0"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel1 = @"fb_product_custom_label_1"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel2 = @"fb_product_custom_label_2"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel3 = @"fb_product_custom_label_3"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel4 = @"fb_product_custom_label_4"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCategory = @"fb_product_category"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSUrl = @"fb_product_applink_ios_url"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppStoreID = @"fb_product_applink_ios_app_store_id"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppName = @"fb_product_applink_ios_app_name"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneUrl = @"fb_product_applink_iphone_url"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppStoreID = @"fb_product_applink_iphone_app_store_id"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppName = @"fb_product_applink_iphone_app_name"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadUrl = @"fb_product_applink_ipad_url"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppStoreID = @"fb_product_applink_ipad_app_store_id"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppName = @"fb_product_applink_ipad_app_name"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidUrl = @"fb_product_applink_android_url"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidPackage = @"fb_product_applink_android_package"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidAppName = @"fb_product_applink_android_app_name"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneUrl = @"fb_product_applink_windows_phone_url"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppID = @"fb_product_applink_windows_phone_app_id"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel0 = @"fb_product_custom_label_0"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel1 = @"fb_product_custom_label_1"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel2 = @"fb_product_custom_label_2"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel3 = @"fb_product_custom_label_3"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCustomLabel4 = @"fb_product_custom_label_4"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCategory = @"fb_product_category"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSUrl = @"fb_product_applink_ios_url"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppStoreID = @"fb_product_applink_ios_app_store_id"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIOSAppName = @"fb_product_applink_ios_app_name"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneUrl = @"fb_product_applink_iphone_url"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppStoreID = @"fb_product_applink_iphone_app_store_id"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPhoneAppName = @"fb_product_applink_iphone_app_name"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadUrl = @"fb_product_applink_ipad_url"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppStoreID = @"fb_product_applink_ipad_app_store_id"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkIPadAppName = @"fb_product_applink_ipad_app_name"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidUrl = @"fb_product_applink_android_url"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidPackage = @"fb_product_applink_android_package"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkAndroidAppName = @"fb_product_applink_android_app_name"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneUrl = @"fb_product_applink_windows_phone_url"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppID = @"fb_product_applink_windows_phone_app_id"; FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAppLinkWindowsPhoneAppName = @"fb_product_applink_windows_phone_app_name"; // // Public event parameter values // -FBSDKAppEventParameterValue FBSDKAppEventParameterValueNo = @"0"; -FBSDKAppEventParameterValue FBSDKAppEventParameterValueYes = @"1"; - -// -// Public event user data types -// - -FBSDKAppEventUserDataType FBSDKAppEventEmail = @"em"; -FBSDKAppEventUserDataType FBSDKAppEventFirstName = @"fn"; -FBSDKAppEventUserDataType FBSDKAppEventLastName = @"ln"; -FBSDKAppEventUserDataType FBSDKAppEventPhone = @"ph"; -FBSDKAppEventUserDataType FBSDKAppEventDateOfBirth = @"dob"; -FBSDKAppEventUserDataType FBSDKAppEventGender = @"ge"; -FBSDKAppEventUserDataType FBSDKAppEventCity = @"ct"; -FBSDKAppEventUserDataType FBSDKAppEventState = @"st"; -FBSDKAppEventUserDataType FBSDKAppEventZip = @"zp"; -FBSDKAppEventUserDataType FBSDKAppEventCountry = @"country"; +FBSDKAppEventParameterValue FBSDKAppEventParameterValueNo = @"0"; +FBSDKAppEventParameterValue FBSDKAppEventParameterValueYes = @"1"; // // Event names internal to this file // -FBSDKAppEventName FBSDKAppEventNameLoginViewUsage = @"fb_login_view_usage"; -FBSDKAppEventName FBSDKAppEventNameShareSheetLaunch = @"fb_share_sheet_launch"; -FBSDKAppEventName FBSDKAppEventNameShareSheetDismiss = @"fb_share_sheet_dismiss"; -FBSDKAppEventName FBSDKAppEventNameShareTrayDidLaunch = @"fb_share_tray_did_launch"; -FBSDKAppEventName FBSDKAppEventNameShareTrayDidSelectActivity = @"fb_share_tray_did_select_activity"; -FBSDKAppEventName FBSDKAppEventNamePermissionsUILaunch = @"fb_permissions_ui_launch"; -FBSDKAppEventName FBSDKAppEventNamePermissionsUIDismiss = @"fb_permissions_ui_dismiss"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialog = @"fb_dialogs_present_share"; +FBSDKAppEventName FBSDKAppEventNameLoginViewUsage = @"fb_login_view_usage"; +FBSDKAppEventName FBSDKAppEventNameShareSheetLaunch = @"fb_share_sheet_launch"; +FBSDKAppEventName FBSDKAppEventNameShareSheetDismiss = @"fb_share_sheet_dismiss"; +FBSDKAppEventName FBSDKAppEventNameShareTrayDidLaunch = @"fb_share_tray_did_launch"; +FBSDKAppEventName FBSDKAppEventNameShareTrayDidSelectActivity = @"fb_share_tray_did_select_activity"; +FBSDKAppEventName FBSDKAppEventNamePermissionsUILaunch = @"fb_permissions_ui_launch"; +FBSDKAppEventName FBSDKAppEventNamePermissionsUIDismiss = @"fb_permissions_ui_dismiss"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialog = @"fb_dialogs_present_share"; FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialogPhoto = @"fb_dialogs_present_share_photo"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialogOG = @"fb_dialogs_present_share_og"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentLikeDialogOG = @"fb_dialogs_present_like_og"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentMessageDialog = @"fb_dialogs_present_message"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentShareDialogOG = @"fb_dialogs_present_share_og"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentLikeDialogOG = @"fb_dialogs_present_like_og"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentMessageDialog = @"fb_dialogs_present_message"; FBSDKAppEventName FBSDKAppEventNameFBDialogsPresentMessageDialogPhoto = @"fb_dialogs_present_message_photo"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsNativeLoginDialogStart = @"fb_dialogs_native_login_dialog_start"; -NSString *const FBSDKAppEventsNativeLoginDialogStartTime = @"fb_native_login_dialog_start_time"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsNativeLoginDialogStart = @"fb_dialogs_native_login_dialog_start"; +NSString *const FBSDKAppEventsNativeLoginDialogStartTime = @"fb_native_login_dialog_start_time"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsNativeLoginDialogEnd = @"fb_dialogs_native_login_dialog_end"; -NSString *const FBSDKAppEventsNativeLoginDialogEndTime = @"fb_native_login_dialog_end_time"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsNativeLoginDialogEnd = @"fb_dialogs_native_login_dialog_end"; +NSString *const FBSDKAppEventsNativeLoginDialogEndTime = @"fb_native_login_dialog_end_time"; -FBSDKAppEventName FBSDKAppEventNameFBDialogsWebLoginCompleted = @"fb_dialogs_web_login_dialog_complete"; -NSString *const FBSDKAppEventsWebLoginE2E = @"fb_web_login_e2e"; +FBSDKAppEventName FBSDKAppEventNameFBDialogsWebLoginCompleted = @"fb_dialogs_web_login_dialog_complete"; +NSString *const FBSDKAppEventsWebLoginE2E = @"fb_web_login_e2e"; -FBSDKAppEventName FBSDKAppEventNameFBSessionAuthStart = @"fb_mobile_login_start"; -FBSDKAppEventName FBSDKAppEventNameFBSessionAuthEnd = @"fb_mobile_login_complete"; -FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodStart = @"fb_mobile_login_method_start"; -FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodEnd = @"fb_mobile_login_method_complete"; +FBSDKAppEventName FBSDKAppEventNameFBSessionAuthStart = @"fb_mobile_login_start"; +FBSDKAppEventName FBSDKAppEventNameFBSessionAuthEnd = @"fb_mobile_login_complete"; +FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodStart = @"fb_mobile_login_method_start"; +FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodEnd = @"fb_mobile_login_method_complete"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeButtonImpression = @"fb_like_button_impression"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLoginButtonImpression = @"fb_login_button_impression"; -FBSDKAppEventName FBSDKAppEventNameFBSDKSendButtonImpression = @"fb_send_button_impression"; -FBSDKAppEventName FBSDKAppEventNameFBSDKShareButtonImpression = @"fb_share_button_impression"; +FBSDKAppEventName FBSDKAppEventNameFBReferralStart = @"fb_referral_start"; +FBSDKAppEventName FBSDKAppEventNameFBReferralEnd = @"fb_referral_end"; + +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeButtonImpression = @"fb_like_button_impression"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLoginButtonImpression = @"fb_login_button_impression"; +FBSDKAppEventName FBSDKAppEventNameFBSDKSendButtonImpression = @"fb_send_button_impression"; +FBSDKAppEventName FBSDKAppEventNameFBSDKShareButtonImpression = @"fb_share_button_impression"; FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingButtonImpression = @"fb_live_streaming_button_impression"; -FBSDKAppEventName FBSDKAppEventNameFBSDKSmartLoginService = @"fb_smart_login_service"; +FBSDKAppEventName FBSDKAppEventNameFBSDKSmartLoginService = @"fb_smart_login_service"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeButtonDidTap = @"fb_like_button_did_tap"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLoginButtonDidTap = @"fb_login_button_did_tap"; -FBSDKAppEventName FBSDKAppEventNameFBSDKSendButtonDidTap = @"fb_send_button_did_tap"; -FBSDKAppEventName FBSDKAppEventNameFBSDKShareButtonDidTap = @"fb_share_button_did_tap"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingButtonDidTap = @"fb_live_streaming_button_did_tap"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeButtonDidTap = @"fb_like_button_did_tap"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLoginButtonDidTap = @"fb_login_button_did_tap"; +FBSDKAppEventName FBSDKAppEventNameFBSDKSendButtonDidTap = @"fb_send_button_did_tap"; +FBSDKAppEventName FBSDKAppEventNameFBSDKShareButtonDidTap = @"fb_share_button_did_tap"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingButtonDidTap = @"fb_live_streaming_button_did_tap"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidDisable = @"fb_like_control_did_disable"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidLike = @"fb_like_control_did_like"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidPresentDialog = @"fb_like_control_did_present_dialog"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidTap = @"fb_like_control_did_tap"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidUnlike = @"fb_like_control_did_unlike"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlError = @"fb_like_control_error"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlImpression = @"fb_like_control_impression"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable = @"fb_like_control_network_unavailable"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidDisable = @"fb_like_control_did_disable"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidLike = @"fb_like_control_did_like"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidPresentDialog = @"fb_like_control_did_present_dialog"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidTap = @"fb_like_control_did_tap"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlDidUnlike = @"fb_like_control_did_unlike"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlError = @"fb_like_control_error"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlImpression = @"fb_like_control_impression"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable = @"fb_like_control_network_unavailable"; -FBSDKAppEventName FBSDKAppEventNameFBSDKEventShareDialogResult = @"fb_dialog_share_result"; -FBSDKAppEventName FBSDKAppEventNameFBSDKEventMessengerShareDialogResult = @"fb_messenger_dialog_share_result"; -FBSDKAppEventName FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult = @"fb_app_invite_dialog_share_result"; +FBSDKAppEventName FBSDKAppEventNameFBSDKEventShareDialogResult = @"fb_dialog_share_result"; +FBSDKAppEventName FBSDKAppEventNameFBSDKEventMessengerShareDialogResult = @"fb_messenger_dialog_share_result"; +FBSDKAppEventName FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult = @"fb_app_invite_dialog_share_result"; -FBSDKAppEventName FBSDKAppEventNameFBSDKEventShareDialogShow = @"fb_dialog_share_show"; -FBSDKAppEventName FBSDKAppEventNameFBSDKEventMessengerShareDialogShow = @"fb_messenger_dialog_share_show"; -FBSDKAppEventName FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow = @"fb_app_invite_share_show"; +FBSDKAppEventName FBSDKAppEventNameFBSDKEventShareDialogShow = @"fb_dialog_share_show"; +FBSDKAppEventName FBSDKAppEventNameFBSDKEventMessengerShareDialogShow = @"fb_messenger_dialog_share_show"; +FBSDKAppEventName FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow = @"fb_app_invite_share_show"; FBSDKAppEventName FBSDKAppEventNameFBSessionFASLoginDialogResult = @"fb_mobile_login_fas_dialog_result"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStart = @"fb_sdk_live_streaming_start"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStop = @"fb_sdk_live_streaming_stop"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingPause = @"fb_sdk_live_streaming_pause"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingResume = @"fb_sdk_live_streaming_resume"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingError = @"fb_sdk_live_streaming_error"; +FBSDKAppEventName FBSDKAppEventNameImplementsApplicationDidFinishLaunching = @"fb_sdk_implements_did_finish_launching"; + +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStart = @"fb_sdk_live_streaming_start"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStop = @"fb_sdk_live_streaming_stop"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingPause = @"fb_sdk_live_streaming_pause"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingResume = @"fb_sdk_live_streaming_resume"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingError = @"fb_sdk_live_streaming_error"; FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingUpdateStatus = @"fb_sdk_live_streaming_update_status"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingVideoID = @"fb_sdk_live_streaming_video_id"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingMic = @"fb_sdk_live_streaming_mic"; -FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingCamera = @"fb_sdk_live_streaming_camera"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingVideoID = @"fb_sdk_live_streaming_video_id"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingMic = @"fb_sdk_live_streaming_mic"; +FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingCamera = @"fb_sdk_live_streaming_camera"; // Event Parameters internal to this file -NSString *const FBSDKAppEventParameterDialogOutcome = @"fb_dialog_outcome"; -NSString *const FBSDKAppEventParameterDialogErrorMessage = @"fb_dialog_outcome_error_message"; -NSString *const FBSDKAppEventParameterDialogMode = @"fb_dialog_mode"; -NSString *const FBSDKAppEventParameterDialogShareContentType = @"fb_dialog_share_content_type"; -NSString *const FBSDKAppEventParameterDialogShareContentUUID = @"fb_dialog_share_content_uuid"; -NSString *const FBSDKAppEventParameterDialogShareContentPageID = @"fb_dialog_share_content_page_id"; -NSString *const FBSDKAppEventParameterShareTrayActivityName = @"fb_share_tray_activity"; -NSString *const FBSDKAppEventParameterShareTrayResult = @"fb_share_tray_result"; +NSString *const FBSDKAppEventParameterDialogOutcome = @"fb_dialog_outcome"; +NSString *const FBSDKAppEventParameterDialogErrorMessage = @"fb_dialog_outcome_error_message"; +NSString *const FBSDKAppEventParameterDialogMode = @"fb_dialog_mode"; +NSString *const FBSDKAppEventParameterDialogShareContentType = @"fb_dialog_share_content_type"; +NSString *const FBSDKAppEventParameterDialogShareContentUUID = @"fb_dialog_share_content_uuid"; +NSString *const FBSDKAppEventParameterDialogShareContentPageID = @"fb_dialog_share_content_page_id"; +NSString *const FBSDKAppEventParameterShareTrayActivityName = @"fb_share_tray_activity"; +NSString *const FBSDKAppEventParameterShareTrayResult = @"fb_share_tray_result"; NSString *const FBSDKAppEventParameterLogTime = @"_logTime"; NSString *const FBSDKAppEventParameterEventName = @"_eventName"; NSString *const FBSDKAppEventParameterImplicitlyLogged = @"_implicitlyLogged"; NSString *const FBSDKAppEventParameterInBackground = @"_inBackground"; -NSString *const FBSDKAppEventParameterLiveStreamingPrevStatus = @"live_streaming_prev_status"; -NSString *const FBSDKAppEventParameterLiveStreamingStatus = @"live_streaming_status"; -NSString *const FBSDKAppEventParameterLiveStreamingError = @"live_streaming_error"; -NSString *const FBSDKAppEventParameterLiveStreamingVideoID = @"live_streaming_video_id"; -NSString *const FBSDKAppEventParameterLiveStreamingMicEnabled = @"live_streaming_mic_enabled"; +NSString *const FBSDKAppEventParameterLiveStreamingPrevStatus = @"live_streaming_prev_status"; +NSString *const FBSDKAppEventParameterLiveStreamingStatus = @"live_streaming_status"; +NSString *const FBSDKAppEventParameterLiveStreamingError = @"live_streaming_error"; +NSString *const FBSDKAppEventParameterLiveStreamingVideoID = @"live_streaming_video_id"; +NSString *const FBSDKAppEventParameterLiveStreamingMicEnabled = @"live_streaming_mic_enabled"; NSString *const FBSDKAppEventParameterLiveStreamingCameraEnabled = @"live_streaming_camera_enabled"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductItemID = @"fb_product_item_id"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAvailability = @"fb_product_availability"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCondition = @"fb_product_condition"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductDescription = @"fb_product_description"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductImageLink = @"fb_product_image_link"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductLink = @"fb_product_link"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductTitle = @"fb_product_title"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductGTIN = @"fb_product_gtin"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductMPN = @"fb_product_mpn"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductBrand = @"fb_product_brand"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductPriceAmount = @"fb_product_price_amount"; -FBSDKAppEventParameterProduct FBSDKAppEventParameterProductPriceCurrency = @"fb_product_price_currency"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductItemID = @"fb_product_item_id"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductAvailability = @"fb_product_availability"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductCondition = @"fb_product_condition"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductDescription = @"fb_product_description"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductImageLink = @"fb_product_image_link"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductLink = @"fb_product_link"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductTitle = @"fb_product_title"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductGTIN = @"fb_product_gtin"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductMPN = @"fb_product_mpn"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductBrand = @"fb_product_brand"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductPriceAmount = @"fb_product_price_amount"; +FBSDKAppEventParameterProduct FBSDKAppEventParameterProductPriceCurrency = @"fb_product_price_currency"; // Event parameter values internal to this file NSString *const FBSDKAppEventsDialogOutcomeValue_Completed = @"Completed"; NSString *const FBSDKAppEventsDialogOutcomeValue_Cancelled = @"Cancelled"; -NSString *const FBSDKAppEventsDialogOutcomeValue_Failed = @"Failed"; +NSString *const FBSDKAppEventsDialogOutcomeValue_Failed = @"Failed"; -NSString *const FBSDKAppEventsDialogShareModeAutomatic = @"Automatic"; -NSString *const FBSDKAppEventsDialogShareModeBrowser = @"Browser"; -NSString *const FBSDKAppEventsDialogShareModeNative = @"Native"; -NSString *const FBSDKAppEventsDialogShareModeShareSheet = @"ShareSheet"; -NSString *const FBSDKAppEventsDialogShareModeWeb = @"Web"; -NSString *const FBSDKAppEventsDialogShareModeFeedBrowser = @"FeedBrowser"; -NSString *const FBSDKAppEventsDialogShareModeFeedWeb = @"FeedWeb"; -NSString *const FBSDKAppEventsDialogShareModeUnknown = @"Unknown"; +NSString *const FBSDKAppEventsDialogShareModeAutomatic = @"Automatic"; +NSString *const FBSDKAppEventsDialogShareModeBrowser = @"Browser"; +NSString *const FBSDKAppEventsDialogShareModeNative = @"Native"; +NSString *const FBSDKAppEventsDialogShareModeShareSheet = @"ShareSheet"; +NSString *const FBSDKAppEventsDialogShareModeWeb = @"Web"; +NSString *const FBSDKAppEventsDialogShareModeFeedBrowser = @"FeedBrowser"; +NSString *const FBSDKAppEventsDialogShareModeFeedWeb = @"FeedWeb"; +NSString *const FBSDKAppEventsDialogShareModeUnknown = @"Unknown"; -NSString *const FBSDKAppEventsDialogShareContentTypeStatus = @"Status"; -NSString *const FBSDKAppEventsDialogShareContentTypePhoto = @"Photo"; -NSString *const FBSDKAppEventsDialogShareContentTypeVideo = @"Video"; -NSString *const FBSDKAppEventsDialogShareContentTypeCamera = @"Camera"; -NSString *const FBSDKAppEventsDialogShareContentTypeUnknown = @"Unknown"; +NSString *const FBSDKAppEventsDialogShareContentTypeStatus = @"Status"; +NSString *const FBSDKAppEventsDialogShareContentTypePhoto = @"Photo"; +NSString *const FBSDKAppEventsDialogShareContentTypeVideo = @"Video"; +NSString *const FBSDKAppEventsDialogShareContentTypeCamera = @"Camera"; +NSString *const FBSDKAppEventsDialogShareContentTypeUnknown = @"Unknown"; -NSString *const FBSDKGateKeeperAppEventsKillSwitch = @"app_events_killswitch"; +NSString *const FBSDKGateKeeperAppEventsKillSwitch = @"app_events_killswitch"; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 @@ -334,7 +328,7 @@ @interface FBSDKAppEvents () @property (nonatomic, assign) FBSDKAppEventsFlushBehavior flushBehavior; -//for testing only. +// for testing only. @property (nonatomic, assign) BOOL disableTimer; @property (nonatomic, copy) NSString *pushNotificationsDeviceTokenString; @@ -375,8 +369,8 @@ - (instancetype)init __weak FBSDKAppEvents *weakSelf = self; self.flushTimer = [FBSDKUtility startGCDTimerWithInterval:FLUSH_PERIOD_IN_SECONDS block:^{ - [weakSelf flushTimerFired:nil]; - }]; + [weakSelf flushTimerFired:nil]; + }]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; _userID = [defaults stringForKey:USER_ID_USER_DEFAULTS_KEY]; @@ -386,7 +380,8 @@ - (instancetype)init return self; } -- (void)registerNotifications { +- (void)registerNotifications +{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationMovingFromActiveStateOrTerminating) @@ -482,7 +477,6 @@ + (void)logPurchase:(double)purchaseAmount parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken { - // A purchase event is just a regular logged event with a given event name // and treating the currency value as going into the parameters dictionary. NSDictionary *newParameters; @@ -645,7 +639,9 @@ + (void)activateApp // Fetch app settings and register for transaction notifications only if app supports implicit purchase // events FBSDKAppEvents *instance = [FBSDKAppEvents singleton]; - [instance publishInstall]; + [FBSDKAppEventsConfigurationManager loadAppEventsConfigurationWithBlock:^{ + [instance publishInstall]; + }]; [instance fetchServerConfiguration:NULL]; // Restore time spent data, indicating that we're being called from "activateApp", which will, @@ -697,9 +693,11 @@ + (NSString *)loggingOverrideAppID + (void)setLoggingOverrideAppID:(NSString *)appID { if (![g_overrideAppID isEqualToString:appID]) { - FBSDKConditionalLog(![FBSDKAppEvents singleton]->_explicitEventsLoggedYet, - FBSDKLoggingBehaviorDeveloperErrors, - @"[FBSDKAppEvents setLoggingOverrideAppID:] should only be called prior to any events being logged."); + FBSDKConditionalLog( + ![FBSDKAppEvents singleton]->_explicitEventsLoggedYet, + FBSDKLoggingBehaviorDeveloperErrors, + @"[FBSDKAppEvents setLoggingOverrideAppID:] should only be called prior to any events being logged." + ); g_overrideAppID = appID; } } @@ -753,7 +751,7 @@ + (void)setUserEmail:(nullable NSString *)email country:country]; } -+ (NSString*)getUserData ++ (NSString *)getUserData { return [FBSDKUserDataStore getHashedData]; } @@ -784,8 +782,7 @@ + (void)clearUserDataForType:(FBSDKAppEventUserDataType)type } + (void)updateUserProperties:(NSDictionary *)properties handler:(FBSDKGraphRequestBlock)handler -{ -} +{} + (NSString *)anonymousID { @@ -793,7 +790,8 @@ + (NSString *)anonymousID } #if !TARGET_OS_TV -+ (void)augmentHybridWKWebView:(WKWebView *)webView { ++ (void)augmentHybridWKWebView:(WKWebView *)webView +{ // Ensure we can instantiate WebKit before trying this Class WKWebViewClass = fbsdkdfl_WKWebViewClass(); if (WKWebViewClass != nil && [webView isKindOfClass:WKWebViewClass]) { @@ -803,22 +801,22 @@ + (void)augmentHybridWKWebView:(WKWebView *)webView { FBSDKHybridAppEventsScriptMessageHandler *scriptHandler = [[FBSDKHybridAppEventsScriptMessageHandler alloc] init]; [controller addScriptMessageHandler:scriptHandler name:FBSDKAppEventsWKWebViewMessagesHandlerKey]; - NSString *js = [NSString stringWithFormat:@"window.fbmq_%@={'sendEvent': function(pixel_id,event_name,custom_data){var msg={\"%@\":pixel_id, \"%@\":event_name,\"%@\":custom_data};window.webkit.messageHandlers[\"%@\"].postMessage(msg);}, 'getProtocol':function(){return \"%@\";}}", - [[self singleton] appID], - FBSDKAppEventsWKWebViewMessagesPixelIDKey, - FBSDKAppEventsWKWebViewMessagesEventKey, - FBSDKAppEventsWKWebViewMessagesParamsKey, - FBSDKAppEventsWKWebViewMessagesHandlerKey, - FBSDKAPPEventsWKWebViewMessagesProtocolKey - ]; + NSString *js = [NSString stringWithFormat:@"window.fbmq_%@={'sendEvent': function(pixel_id,event_name,custom_data){var msg={\"%@\":pixel_id, \"%@\":event_name,\"%@\":custom_data};window.webkit.messageHandlers[\"%@\"].postMessage(msg);}, 'getProtocol':function(){return \"%@\";}}", + [[self singleton] appID], + FBSDKAppEventsWKWebViewMessagesPixelIDKey, + FBSDKAppEventsWKWebViewMessagesEventKey, + FBSDKAppEventsWKWebViewMessagesParamsKey, + FBSDKAppEventsWKWebViewMessagesHandlerKey, + FBSDKAPPEventsWKWebViewMessagesProtocolKey + ]; [controller addUserScript:[[WKUserScriptClass alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]]; } - } - else { + } else { [FBSDKAppEventsUtility logAndNotify:@"You must call augmentHybridWKWebView with WebKit linked to your project and a WKWebView instance"]; } } + #endif + (void)setIsUnityInit:(BOOL)isUnityInit @@ -834,7 +832,7 @@ + (void)sendEventBindingsToUnity if ([FBSDKAppEvents singleton]->_isUnityInit && [FBSDKAppEvents singleton]->_serverConfiguration && [FBSDKTypeUtility isValidJSONObject:[FBSDKAppEvents singleton]->_serverConfiguration.eventBindings] - ) { + ) { NSData *jsonData = [FBSDKTypeUtility dataWithJSONObject:[FBSDKAppEvents singleton]->_serverConfiguration.eventBindings ?: @"" options:0 error:nil]; @@ -846,6 +844,7 @@ + (void)sendEventBindingsToUnity } } } + #pragma clang diagnostic pop #pragma mark - Internal Methods @@ -930,7 +929,6 @@ + (void)logImplicitEvent:(NSString *)eventName accessToken:accessToken]; } - #ifdef DEBUG static dispatch_once_t *onceTokenPointer; + (void)resetSingleton @@ -939,6 +937,7 @@ + (void)resetSingleton *onceTokenPointer = 0; } } + #endif + (FBSDKAppEvents *)singleton @@ -959,7 +958,7 @@ - (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason // Always flush asynchronously, even on main thread, for two reasons: // - most consistent code path for all threads. // - allow locks being held by caller to be released prior to actual flushing work being done. - @synchronized (self) { + @synchronized(self) { if (!_appEventsState) { return; } @@ -985,14 +984,18 @@ - (void)publishInstall [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents appID] for [FBSDKAppEvents publishInstall:]"]; return; } + if ([FBSDKAppEventsUtility shouldDropAppEvent]) { + return; + } NSString *lastAttributionPingString = [NSString stringWithFormat:@"com.facebook.sdk:lastAttributionPing%@", appID]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:lastAttributionPingString]) { return; } [self fetchServerConfiguration:^{ - NSDictionary *params = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:@"MOBILE_APP_INSTALL" - shouldAccessAdvertisingID:self->_serverConfiguration.isAdvertisingIDEnabled]; + NSMutableDictionary *params = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:@"MOBILE_APP_INSTALL" + shouldAccessAdvertisingID:self->_serverConfiguration.isAdvertisingIDEnabled]; + [self appendInstallTimestamp:params]; NSString *path = [NSString stringWithFormat:@"%@/activities", appID]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path parameters:params @@ -1010,8 +1013,72 @@ - (void)publishInstall }]; } +- (void)publishATE +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *appID = [self appID]; + if (appID.length == 0) { + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents appID] for [FBSDKAppEvents publishATE:]"]; + return; + } + NSString *lastATEPingString = [NSString stringWithFormat:@"com.facebook.sdk:lastATEPing%@", appID]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + id lastPublishDate = [defaults objectForKey:lastATEPingString]; + if ([lastPublishDate isKindOfClass:[NSDate class]] && [(NSDate *)lastPublishDate timeIntervalSinceNow] * -1 < 24 * 60 * 60) { + return; + } + + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + [FBSDKTypeUtility dictionary:parameters setObject:@"CUSTOM_APP_EVENTS" forKey:@"event"]; + + NSOperatingSystemVersion operatingSystemVersion = [FBSDKInternalUtility operatingSystemVersion]; + NSString *osVersion = [NSString stringWithFormat:@"%ti.%ti.%ti", + operatingSystemVersion.majorVersion, + operatingSystemVersion.minorVersion, + operatingSystemVersion.patchVersion]; + + NSArray *event = @[ + @{ + @"_eventName" : @"fb_mobile_ate_status", + @"ate_status" : @([FBSDKSettings getAdvertisingTrackingStatus]).stringValue, + @"os_version" : osVersion, + } + ]; + [FBSDKTypeUtility dictionary:parameters setObject:[FBSDKBasicUtility JSONStringForObject:event error:NULL invalidObjectHandler:NULL] forKey:@"custom_events"]; + + [FBSDKAppEventsDeviceInfo extendDictionaryWithDeviceInfo:parameters]; + + NSString *path = [NSString stringWithFormat:@"%@/activities", appID]; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path + parameters:parameters + tokenString:nil + HTTPMethod:FBSDKHTTPMethodPOST + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + if (!error) { + [defaults setObject:[NSDate date] forKey:lastATEPingString]; + } + }]; + }); +} + +- (void)appendInstallTimestamp:(NSMutableDictionary *)parameters +{ + if (@available(iOS 14.0, *)) { + if ([FBSDKSettings isSetATETimeExceedsInstallTime]) { + NSDate *setAteTimestamp = [FBSDKSettings getSetAdvertiserTrackingEnabledTimestamp]; + [FBSDKTypeUtility dictionary:parameters setObject:@([FBSDKAppEventsUtility convertToUnixTime:setAteTimestamp]) forKey:@"install_timestamp"]; + } else { + NSDate *installTimestamp = [FBSDKSettings getInstallTimestamp]; + [FBSDKTypeUtility dictionary:parameters setObject:@([FBSDKAppEventsUtility convertToUnixTime:installTimestamp]) forKey:@"install_timestamp"]; + } + } +} + #if !TARGET_OS_TV -- (void)enableCodelessEvents { +- (void)enableCodelessEvents +{ if (_serverConfiguration.isCodelessEventsEnabled) { [FBSDKCodelessIndexer enable]; @@ -1027,6 +1094,7 @@ - (void)enableCodelessEvents { } } } + #endif // app events can use a server configuration up to 24 hours old to minimize network traffic. @@ -1050,7 +1118,14 @@ - (void)fetchServerConfiguration:(FBSDKCodeBlock)callback [FBSDKEventDeactivationManager enable]; } }]; -#if !TARGET_OS_TV + if (@available(iOS 14.0, *)) { + [FBSDKFeatureManager checkFeature:FBSDKFeatureATELogging completionBlock:^(BOOL enabled) { + if (enabled) { + [self publishATE]; + } + }]; + } + #if !TARGET_OS_TV [FBSDKFeatureManager checkFeature:FBSDKFeatureCodelessEvents completionBlock:^(BOOL enabled) { if (enabled) { [self enableCodelessEvents]; @@ -1066,7 +1141,19 @@ - (void)fetchServerConfiguration:(FBSDKCodeBlock)callback [FBSDKModelManager enable]; } }]; -#endif + if (@available(iOS 11.3, *)) { + [FBSDKFeatureManager checkFeature:FBSDKFeatureSKAdNetwork completionBlock:^(BOOL SKAdNetworkEnabled) { + if (SKAdNetworkEnabled) { + [SKAdNetwork registerAppForAdNetworkAttribution]; + [FBSDKFeatureManager checkFeature:FBSDKFeatureSKAdNetworkConversionValue completionBlock:^(BOOL SKAdNetworkConversionValueEnabled) { + if (SKAdNetworkConversionValueEnabled) { + [FBSDKSKAdNetworkReporter enable]; + } + }]; + } + }]; + } + #endif if (callback) { callback(); } @@ -1090,6 +1177,15 @@ - (void)instanceLogEvent:(FBSDKAppEventName)eventName return; } +#if !TARGET_OS_TV + // Update conversion value for SKAdNetwork if needed + [FBSDKSKAdNetworkReporter recordAndUpdateEvent:eventName currency:[FBSDKTypeUtility dictionary:parameters objectForKey:FBSDKAppEventParameterNameCurrency ofType:NSString.class] value:valueToSum]; +#endif + + if ([FBSDKAppEventsUtility shouldDropAppEvent]) { + return; + } + if (isImplicitlyLogged && _serverConfiguration && !_serverConfiguration.isImplicitLoggingSupported) { return; } @@ -1165,7 +1261,7 @@ - (void)instanceLogEvent:(FBSDKAppEventName)eventName NSString *tokenString = [FBSDKAppEventsUtility tokenStringToUseFor:accessToken]; NSString *appID = [self appID]; - @synchronized (self) { + @synchronized(self) { if (!_appEventsState) { _appEventsState = [[FBSDKAppEventsState alloc] initWithToken:tokenString appID:appID]; } else if (![_appEventsState isCompatibleWithTokenString:tokenString appID:appID]) { @@ -1187,12 +1283,13 @@ - (void)instanceLogEvent:(FBSDKAppEventName)eventName [self checkPersistedEvents]; - if (_appEventsState.events.count > NUM_LOG_EVENTS_TO_TRY_TO_FLUSH_AFTER && - self.flushBehavior != FBSDKAppEventsFlushBehaviorExplicitOnly) { + if (_appEventsState.events.count > NUM_LOG_EVENTS_TO_TRY_TO_FLUSH_AFTER + && self.flushBehavior != FBSDKAppEventsFlushBehaviorExplicitOnly) { [self flushForReason:FBSDKAppEventsFlushReasonEventThreshold]; } } } + #pragma clang diagnostic pop // this fetches persisted event states. @@ -1237,7 +1334,6 @@ - (void)checkPersistedEvents - (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState forReason:(FBSDKAppEventsFlushReason)reason { - if (appEventsState.events.count == 0) { return; } @@ -1247,6 +1343,10 @@ - (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState return; } + if ([FBSDKAppEventsUtility shouldDropAppEvent]) { + return; + } + [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; [self fetchServerConfiguration:^(void) { @@ -1303,7 +1403,6 @@ - (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState loggingEntry:loggingEntry appEventsState:(FBSDKAppEventsState *)appEventsState]; }]; - }]; } @@ -1314,7 +1413,7 @@ - (void)handleActivitiesPostCompletion:(NSError *)error typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushResult) { FlushResultSuccess, FlushResultServerError, - FlushResultNoConnectivity + FlushResultNoConnectivity, }; [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; @@ -1331,7 +1430,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushResult) { if (flushResult == FlushResultServerError) { // Only log events that developer can do something with (i.e., if parameters are incorrect). - // as opposed to cases where the token is bad. + // as opposed to cases where the token is bad. if ([error.userInfo[FBSDKGraphRequestErrorKey] unsignedIntegerValue] == FBSDKGraphRequestErrorOther) { NSString *message = [NSString stringWithFormat:@"Failed to send AppEvents: %@", error]; [FBSDKAppEventsUtility logAndNotify:message allowLogAsDeveloperError:!appEventsState.areAllEventsImplicit]; @@ -1389,7 +1488,7 @@ - (void)applicationMovingFromActiveStateOrTerminating // When moving from active state, we don't have time to wait for the result of a flush, so // just persist events to storage, and we'll process them at the next activation. FBSDKAppEventsState *copy = nil; - @synchronized (self) { + @synchronized(self) { copy = [_appEventsState copy]; _appEventsState = nil; } @@ -1407,7 +1506,7 @@ + (FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(FBSD // Rules for how we use the attribution ID / advertiser ID for an 'custom_audience_third_party_id' Graph API request // 1) if the OS tells us that the user has Limited Ad Tracking, then just don't send, and return a nil in the token. // 2) if the app has set 'limitEventAndDataUsage', this effectively implies that app-initiated ad targeting shouldn't happen, - // so use that data here to return nil as well. + // so use that data here to return nil as well. // 3) if we have a user session token, then no need to send attribution ID / advertiser ID back as the udid parameter // 4) otherwise, send back the udid parameter. diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.h index 3b97764e55..941d3cc657 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m index a89e838fc1..d4298aa7ed 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m @@ -20,23 +20,23 @@ #if !TARGET_OS_TV -#import "FBSDKMetadataIndexer.h" + #import "FBSDKMetadataIndexer.h" -#import -#import -#import + #import -#import + #import + #import + #import -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" -static const int FBSDKMetadataIndexerMaxTextLength = 100; -static const int FBSDKMetadataIndexerMaxIndicatorLength = 100; -static const int FBSDKMetadataIndexerMaxValue = 5; +static const int FBSDKMetadataIndexerMaxTextLength = 100; +static const int FBSDKMetadataIndexerMaxIndicatorLength = 100; +static const int FBSDKMetadataIndexerMaxValue = 5; -static NSString * const FIELD_K = @"k"; -static NSString * const FIELD_V = @"v"; -static NSString * const FIELD_K_DELIMITER = @","; +static NSString *const FIELD_K = @"k"; +static NSString *const FIELD_V = @"v"; +static NSString *const FIELD_K_DELIMITER = @","; static NSMutableDictionary *> *_rules; static NSMutableDictionary *> *_store; @@ -52,17 +52,21 @@ + (void)initialize + (void)enable { - if (FBSDKAdvertisingTrackingAllowed != [FBSDKAppEventsUtility advertisingTrackingStatus]) { - return; - } + @try { + if (FBSDKAdvertisingTrackingAllowed != [FBSDKAppEventsUtility advertisingTrackingStatus]) { + return; + } - NSDictionary *AAMRules = [FBSDKServerConfigurationManager cachedServerConfiguration].AAMRules; - if (AAMRules) { - [FBSDKMetadataIndexer setupWithRules:AAMRules]; + NSDictionary *AAMRules = [FBSDKServerConfigurationManager cachedServerConfiguration].AAMRules; + if (AAMRules) { + [FBSDKMetadataIndexer setupWithRules:AAMRules]; + } + } @catch (NSException *exception) { + NSLog(@"Fail to enable Automatic Advanced Matching, exception reason: %@", exception.reason); } } -+ (void)setupWithRules:(NSDictionary * _Nullable)rules ++ (void)setupWithRules:(NSDictionary *_Nullable)rules { if (0 == rules.count) { return; @@ -104,7 +108,7 @@ + (void)initStore } } -+ (void)constructRules:(NSDictionary * _Nullable)rules ++ (void)constructRules:(NSDictionary *_Nullable)rules { for (NSString *key in rules) { NSDictionary *value = [FBSDKTypeUtility dictionaryValue:rules[key]]; @@ -211,10 +215,10 @@ + (void)getMetadataWithText:(NSString *)text { text = [self normalizeValue:text]; placeholder = [self normalizeField:placeholder]; - if (secureTextEntry || [placeholder containsString:@"password"] || - text.length == 0 || - text.length > FBSDKMetadataIndexerMaxTextLength || - placeholder.length >= FBSDKMetadataIndexerMaxIndicatorLength) { + if (secureTextEntry || [placeholder containsString:@"password"] + || text.length == 0 + || text.length > FBSDKMetadataIndexerMaxTextLength + || placeholder.length >= FBSDKMetadataIndexerMaxIndicatorLength) { return; } @@ -239,7 +243,7 @@ + (void)getMetadataWithText:(NSString *)text } } -#pragma mark - Helper Methods + #pragma mark - Helper Methods + (void)checkAndAppendData:(NSString *)data forKey:(NSString *)key diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessIndexer.m index 781f6986c4..18b1f01f9a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessIndexer.m @@ -20,17 +20,17 @@ #if !TARGET_OS_TV -#import "FBSDKCodelessIndexer.h" + #import "FBSDKCodelessIndexer.h" -#import -#import -#import + #import -#import + #import + #import + #import -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKGraphRequest.h" -#import "FBSDKSettings.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKGraphRequest.h" + #import "FBSDKSettings.h" @implementation FBSDKCodelessIndexer @@ -62,8 +62,8 @@ + (void)enable #endif } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" // DO NOT call this function, it is only called once in the load function + (void)loadCodelessSettingWithCompletionBlock:(FBSDKCodelessSettingLoadBlock)completionBlock { @@ -119,7 +119,8 @@ + (void)loadCodelessSettingWithCompletionBlock:(FBSDKCodelessSettingLoadBlock)co } }]; } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop + (FBSDKGraphRequest *)requestToLoadCodelessSetup:(NSString *)appID { @@ -129,9 +130,9 @@ + (FBSDKGraphRequest *)requestToLoadCodelessSetup:(NSString *)appID } NSDictionary *parameters = @{ - @"fields": CODELESS_SETUP_ENABLED_FIELD, - @"advertiser_id": advertiserID - }; + @"fields" : CODELESS_SETUP_ENABLED_FIELD, + @"advertiser_id" : advertiserID + }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID parameters:parameters @@ -153,21 +154,23 @@ + (void)setupGesture Class class = [UIApplication class]; [FBSDKSwizzler swizzleSelector:@selector(motionBegan:withEvent:) onClass:class withBlock:^{ - if ([FBSDKServerConfigurationManager cachedServerConfiguration].isCodelessEventsEnabled) { - [self checkCodelessIndexingSession]; - } - } named:@"motionBegan"]; + if ([FBSDKServerConfigurationManager cachedServerConfiguration].isCodelessEventsEnabled) { + [self checkCodelessIndexingSession]; + } + } named:@"motionBegan"]; } + (void)checkCodelessIndexingSession { - if (_isCheckingSession) return; + if (_isCheckingSession) { + return; + } _isCheckingSession = YES; NSDictionary *parameters = @{ - CODELESS_INDEXING_SESSION_ID_KEY: [self currentSessionDeviceID], - CODELESS_INDEXING_EXT_INFO_KEY: [self extInfo] - }; + CODELESS_INDEXING_SESSION_ID_KEY : [self currentSessionDeviceID], + CODELESS_INDEXING_EXT_INFO_KEY : [self extInfo] + }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/%@", [FBSDKSettings appID], CODELESS_INDEXING_SESSION_ENDPOINT] @@ -181,10 +184,10 @@ + (void)checkCodelessIndexingSession _lastTreeHash = nil; if (!_appIndexingTimer) { _appIndexingTimer = [NSTimer timerWithTimeInterval:CODELESS_INDEXING_UPLOAD_INTERVAL_IN_SECONDS - target:self - selector:@selector(startIndexing) - userInfo:nil - repeats:YES]; + target:self + selector:@selector(startIndexing) + userInfo:nil + repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:_appIndexingTimer forMode:NSDefaultRunLoopMode]; } @@ -235,7 +238,8 @@ + (NSString *)extInfo return extinfo ?: @""; } -+ (void)startIndexing { ++ (void)startIndexing +{ if (!_isCodelessIndexingEnabled) { return; } @@ -250,10 +254,10 @@ + (void)startIndexing { Class FBUnityUtility = objc_lookUpClass("FBUnityUtility"); SEL selector = NSSelectorFromString(@"triggerUploadViewHierarchy"); if (FBUnityUtility && selector && [FBUnityUtility respondsToSelector:selector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [FBUnityUtility performSelector:selector]; -#pragma clang diagnostic pop + #pragma clang diagnostic pop } } else { [self uploadIndexing]; @@ -263,7 +267,7 @@ + (void)startIndexing { + (void)uploadIndexing { if (_isCodelessIndexing) { - return; + return; } NSString *tree = [FBSDKCodelessIndexer currentViewTree]; @@ -273,44 +277,44 @@ + (void)uploadIndexing + (void)uploadIndexing:(NSString *)tree { - if (_isCodelessIndexing) { - return; - } + if (_isCodelessIndexing) { + return; + } - if (!tree) { - return; - } + if (!tree) { + return; + } - NSString *currentTreeHash = [FBSDKUtility SHA256Hash:tree]; - if (_lastTreeHash && [_lastTreeHash isEqualToString:currentTreeHash]) { - return; - } + NSString *currentTreeHash = [FBSDKUtility SHA256Hash:tree]; + if (_lastTreeHash && [_lastTreeHash isEqualToString:currentTreeHash]) { + return; + } - _lastTreeHash = currentTreeHash; - - NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *version = [mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; - - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] - initWithGraphPath:[NSString stringWithFormat:@"%@/%@", - [FBSDKSettings appID], CODELESS_INDEXING_ENDPOINT] - parameters:@{ - CODELESS_INDEXING_TREE_KEY: tree, - CODELESS_INDEXING_APP_VERSION_KEY: version ?: @"", - CODELESS_INDEXING_PLATFORM_KEY: @"iOS", - CODELESS_INDEXING_SESSION_ID_KEY: [self currentSessionDeviceID] - } - HTTPMethod:FBSDKHTTPMethodPOST]; - _isCodelessIndexing = YES; - [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - _isCodelessIndexing = NO; - if ([result isKindOfClass:[NSDictionary class]]) { - _isCodelessIndexingEnabled = [result[CODELESS_INDEXING_STATUS_KEY] boolValue]; - if (!_isCodelessIndexingEnabled) { - _deviceSessionID = nil; - } - } - }]; + _lastTreeHash = currentTreeHash; + + NSBundle *mainBundle = [NSBundle mainBundle]; + NSString *version = [mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; + + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] + initWithGraphPath:[NSString stringWithFormat:@"%@/%@", + [FBSDKSettings appID], CODELESS_INDEXING_ENDPOINT] + parameters:@{ + CODELESS_INDEXING_TREE_KEY : tree, + CODELESS_INDEXING_APP_VERSION_KEY : version ?: @"", + CODELESS_INDEXING_PLATFORM_KEY : @"iOS", + CODELESS_INDEXING_SESSION_ID_KEY : [self currentSessionDeviceID] + } + HTTPMethod:FBSDKHTTPMethodPOST]; + _isCodelessIndexing = YES; + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + _isCodelessIndexing = NO; + if ([result isKindOfClass:[NSDictionary class]]) { + _isCodelessIndexingEnabled = [result[CODELESS_INDEXING_STATUS_KEY] boolValue]; + if (!_isCodelessIndexingEnabled) { + _deviceSessionID = nil; + } + } + }]; } + (NSString *)currentViewTree @@ -355,7 +359,8 @@ + (NSString *)currentViewTree return tree; } -+ (UIImage *)screenshot { ++ (UIImage *)screenshot +{ UIWindow *window = [UIApplication sharedApplication].delegate.window; UIGraphicsBeginImageContext(window.bounds.size); @@ -379,18 +384,19 @@ + (UIImage *)screenshot { CGRect frame = view.frame; CGPoint offset = CGPointZero; - if ([view isKindOfClass:[UIScrollView class]]) + if ([view isKindOfClass:[UIScrollView class]]) { offset = ((UIScrollView *)view).contentOffset; + } return @{ - CODELESS_VIEW_TREE_TOP_KEY: @((int)frame.origin.y), - CODELESS_VIEW_TREE_LEFT_KEY: @((int)frame.origin.x), - CODELESS_VIEW_TREE_WIDTH_KEY: @((int)frame.size.width), - CODELESS_VIEW_TREE_HEIGHT_KEY: @((int)frame.size.height), - CODELESS_VIEW_TREE_OFFSET_X_KEY: @((int)offset.x), - CODELESS_VIEW_TREE_OFFSET_Y_KEY: @((int)offset.y), - CODELESS_VIEW_TREE_VISIBILITY_KEY: view.isHidden ? @4 : @0 - }; + CODELESS_VIEW_TREE_TOP_KEY : @((int)frame.origin.y), + CODELESS_VIEW_TREE_LEFT_KEY : @((int)frame.origin.x), + CODELESS_VIEW_TREE_WIDTH_KEY : @((int)frame.size.width), + CODELESS_VIEW_TREE_HEIGHT_KEY : @((int)frame.size.height), + CODELESS_VIEW_TREE_OFFSET_X_KEY : @((int)offset.x), + CODELESS_VIEW_TREE_OFFSET_Y_KEY : @((int)offset.y), + CODELESS_VIEW_TREE_VISIBILITY_KEY : view.isHidden ? @4 : @0 + }; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessParameterComponent.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessParameterComponent.m index 63ecb0ba2a..ff2815bc63 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessParameterComponent.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessParameterComponent.m @@ -20,15 +20,16 @@ #if !TARGET_OS_TV -#import "FBSDKCodelessParameterComponent.h" + #import "FBSDKCodelessParameterComponent.h" -#import "FBSDKCodelessPathComponent.h" -#import "FBSDKViewHierarchyMacros.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKCodelessPathComponent.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKViewHierarchyMacros.h" @implementation FBSDKCodelessParameterComponent -- (instancetype)initWithJSON:(NSDictionary *)dict { +- (instancetype)initWithJSON:(NSDictionary *)dict +{ if (self = [super init]) { _name = [dict[CODELESS_MAPPING_PARAMETER_NAME_KEY] copy]; _value = [dict[CODELESS_MAPPING_PARAMETER_VALUE_KEY] copy]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessPathComponent.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessPathComponent.m index e093b020e5..c38d13ba6d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessPathComponent.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKCodelessPathComponent.m @@ -20,20 +20,20 @@ #if !TARGET_OS_TV -#import "FBSDKCodelessPathComponent.h" + #import "FBSDKCodelessPathComponent.h" -#import "FBSDKViewHierarchyMacros.h" + #import "FBSDKViewHierarchyMacros.h" @implementation FBSDKCodelessPathComponent -- (instancetype)initWithJSON:(NSDictionary *)dict { +- (instancetype)initWithJSON:(NSDictionary *)dict +{ if (self = [super init]) { _className = [dict[CODELESS_MAPPING_CLASS_NAME_KEY] copy]; _text = [dict[CODELESS_MAPPING_TEXT_KEY] copy]; _hint = [dict[CODELESS_MAPPING_HINT_KEY] copy]; _desc = [dict[CODELESS_MAPPING_DESC_KEY] copy]; - if (dict[CODELESS_MAPPING_INDEX_KEY]) { _index = [dict[CODELESS_MAPPING_INDEX_KEY] intValue]; } else { diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBinding.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBinding.m index cdf45a2397..e25ca5957d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBinding.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBinding.m @@ -20,22 +20,22 @@ #if !TARGET_OS_TV -#import "FBSDKEventBinding.h" - -#import "FBSDKAppEvents.h" -#import "FBSDKAppEventsUtility.h" -#import "FBSDKCodelessParameterComponent.h" -#import "FBSDKCodelessPathComponent.h" -#import "FBSDKSwizzler.h" -#import "FBSDKUtility.h" -#import "FBSDKViewHierarchy.h" -#import "FBSDKViewHierarchyMacros.h" -#import "FBSDKTypeUtility.h" - -#define CODELESS_PATH_TYPE_ABSOLUTE @"absolute" -#define CODELESS_PATH_TYPE_RELATIVE @"relative" -#define CODELESS_CODELESS_EVENT_KEY @"_is_fb_codeless" -#define PARAMETER_NAME_PRICE @"_valueToSum" + #import "FBSDKEventBinding.h" + + #import "FBSDKAppEvents.h" + #import "FBSDKAppEventsUtility.h" + #import "FBSDKCodelessParameterComponent.h" + #import "FBSDKCodelessPathComponent.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKSwizzler.h" + #import "FBSDKUtility.h" + #import "FBSDKViewHierarchy.h" + #import "FBSDKViewHierarchyMacros.h" + + #define CODELESS_PATH_TYPE_ABSOLUTE @"absolute" + #define CODELESS_PATH_TYPE_RELATIVE @"relative" + #define CODELESS_CODELESS_EVENT_KEY @"_is_fb_codeless" + #define PARAMETER_NAME_PRICE @"_valueToSum" @implementation FBSDKEventBinding @@ -102,8 +102,8 @@ + (BOOL)matchAnyView:(NSArray *)views return NO; } -+ (BOOL)match:(NSObject *)view -pathComponent:(FBSDKCodelessPathComponent *)component ++ (BOOL) match:(NSObject *)view + pathComponent:(FBSDKCodelessPathComponent *)component { NSString *className = NSStringFromClass([view class]); if (![className isEqualToString:component.className]) { @@ -128,7 +128,7 @@ + (BOOL)match:(NSObject *)view if ((component.matchBitmask & FBSDKCodelessMatchBitmaskFieldText) > 0) { NSString *text = [FBSDKViewHierarchy getText:view]; BOOL match = ((text.length == 0 && component.text.length == 0) - || [text isEqualToString:component.text]); + || [text isEqualToString:component.text]); if (!match) { return NO; } @@ -143,7 +143,7 @@ + (BOOL)match:(NSObject *)view if ((component.matchBitmask & FBSDKCodelessMatchBitmaskFieldHint) > 0) { NSString *hint = [FBSDKViewHierarchy getHint:view]; BOOL match = ((hint.length == 0 && component.hint.length == 0) - || [hint isEqualToString:component.hint]); + || [hint isEqualToString:component.hint]); if (!match) { return NO; } @@ -160,7 +160,8 @@ + (BOOL)isViewMatchPath:(UIView *)view path:(NSArray *)path return isMatch; } -+ (BOOL)isPath:(NSArray *)path matchViewPath:(NSArray *)viewPath { ++ (BOOL)isPath:(NSArray *)path matchViewPath:(NSArray *)viewPath +{ for (NSInteger i = 0; i < MIN(path.count, viewPath.count); i++) { NSInteger idxPath = path.count - i - 1; NSInteger idxViewPath = viewPath.count - i - 1; @@ -180,8 +181,8 @@ + (BOOL)isPath:(NSArray *)path matchViewPath:(NSArray *)viewPath { if ((pathComponent.matchBitmask & FBSDKCodelessMatchBitmaskFieldText) > 0) { NSString *text = viewPathComponent.text; BOOL match = ((text.length == 0 && pathComponent.text.length == 0) - || [text isEqualToString:pathComponent.text] - || [[FBSDKUtility SHA256Hash:text] isEqualToString:pathComponent.text]); + || [text isEqualToString:pathComponent.text] + || [[FBSDKUtility SHA256Hash:text] isEqualToString:pathComponent.text]); if (!match) { return NO; } @@ -195,8 +196,8 @@ + (BOOL)isPath:(NSArray *)path matchViewPath:(NSArray *)viewPath { if ((pathComponent.matchBitmask & FBSDKCodelessMatchBitmaskFieldHint) > 0) { NSString *hint = viewPathComponent.hint; BOOL match = ((hint.length == 0 && pathComponent.hint.length == 0) - || [hint isEqualToString:pathComponent.hint] - || [[FBSDKUtility SHA256Hash:hint] isEqualToString:pathComponent.hint]); + || [hint isEqualToString:pathComponent.hint] + || [[FBSDKUtility SHA256Hash:hint] isEqualToString:pathComponent.hint]); if (!match) { return NO; } @@ -206,14 +207,15 @@ + (BOOL)isPath:(NSArray *)path matchViewPath:(NSArray *)viewPath { return YES; } -+ (NSObject *)findViewByPath:(NSArray *)path parent:(NSObject *)parent level:(int)level { ++ (NSObject *)findViewByPath:(NSArray *)path parent:(NSObject *)parent level:(int)level +{ if (level >= path.count) { return nil; } FBSDKCodelessPathComponent *pathComponent = [FBSDKTypeUtility array:path objectAtIndex:level]; - // If found parent, skip to next level + // If found parent, skip to next level if ([pathComponent.className isEqualToString:CODELESS_MAPPING_PARENT_CLASS_NAME]) { NSObject *nextParent = [FBSDKViewHierarchy getParent:parent]; @@ -262,8 +264,8 @@ + (NSObject *)findViewByPath:(NSArray *)path parent:(NSObject *)parent level:(in - (BOOL)isEqualToBinding:(FBSDKEventBinding *)binding { - if (_path.count != binding.path.count || - _parameters.count != binding.parameters.count) { + if (_path.count != binding.path.count + || _parameters.count != binding.parameters.count) { return NO; } @@ -296,10 +298,11 @@ - (BOOL)isEqualToBinding:(FBSDKEventBinding *)binding return YES; } -// MARK: - find event parameters via relative path +// MARK: - find event parameters via relative path + (NSString *)findParameterOfPath:(NSArray *)path pathType:(NSString *)pathType - sourceView:(UIView *)sourceView { + sourceView:(UIView *)sourceView +{ if (0 == path.count) { return nil; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBindingManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBindingManager.m index d409f2ce60..3c96e33989 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBindingManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Codeless/FBSDKEventBindingManager.m @@ -20,26 +20,26 @@ #if !TARGET_OS_TV -#import "FBSDKEventBindingManager.h" + #import "FBSDKEventBindingManager.h" -#import + #import -#import + #import -#import "FBSDKCodelessPathComponent.h" -#import "FBSDKEventBinding.h" -#import "FBSDKSwizzler.h" -#import "FBSDKTypeUtility.h" -#import "FBSDKViewHierarchy.h" -#import "FBSDKViewHierarchyMacros.h" + #import "FBSDKCodelessPathComponent.h" + #import "FBSDKEventBinding.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKSwizzler.h" + #import "FBSDKViewHierarchy.h" + #import "FBSDKViewHierarchyMacros.h" -#define ReactNativeTargetKey @"target" -#define ReactNativeTouchEndEventName @"touchEnd" + #define ReactNativeTargetKey @"target" + #define ReactNativeTouchEndEventName @"touchEnd" -#define ReactNativeClassRCTTextView "RCTTextView" -#define ReactNativeClassRCTImageView "RCTImageVIew" -#define ReactNativeClassRCTTouchEvent "RCTTouchEvent" -#define ReactNativeClassRCTTouchHandler "RCTTouchHandler" + #define ReactNativeClassRCTTextView "RCTTextView" + #define ReactNativeClassRCTImageView "RCTImageVIew" + #define ReactNativeClassRCTTouchEvent "RCTTouchEvent" + #define ReactNativeClassRCTTouchHandler "RCTTouchHandler" @interface FBSDKEventBindingManager () { @@ -53,7 +53,8 @@ @interface FBSDKEventBindingManager () @implementation FBSDKEventBindingManager -- (id)init { +- (id)init +{ self = [super init]; if (self) { isStarted = NO; @@ -86,7 +87,8 @@ - (id)init { return self; } -+ (NSArray *)parseArray:(NSArray *)array { ++ (NSArray *)parseArray:(NSArray *)array +{ NSMutableArray *result = [NSMutableArray array]; for (NSDictionary *json in array) { @@ -97,7 +99,7 @@ + (NSArray *)parseArray:(NSArray *)array { return [result copy]; } -- (FBSDKEventBindingManager*)initWithJSON:(NSDictionary*)dict +- (FBSDKEventBindingManager *)initWithJSON:(NSDictionary *)dict { if ((self = [super init])) { NSArray *eventBindingsDict = [FBSDKTypeUtility arrayValue:dict[@"event_bindings"]]; @@ -111,8 +113,8 @@ - (FBSDKEventBindingManager*)initWithJSON:(NSDictionary*)dict return self; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundeclared-selector" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" - (void)start { if (isStarted) { @@ -140,7 +142,7 @@ - (void)start Class classRCTImageView = objc_lookUpClass(ReactNativeClassRCTImageView); Class classRCTTouchHandler = objc_lookUpClass(ReactNativeClassRCTTouchHandler); - // All react-native views would be added tp RCTRootView, so no need to check didMoveToWindow + // All react-native views would be added tp RCTRootView, so no need to check didMoveToWindow [FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:classRCTView withBlock:blockToWindow @@ -155,38 +157,37 @@ - (void)start named:@"match_react_native"]; // RCTTouchHandler handles with touch events, like touchEnd and uses RCTEventDispather to dispatch events, so we can check _updateAndDispatchTouches to fire events - [FBSDKSwizzler swizzleSelector:@selector(_updateAndDispatchTouches:eventName:) onClass:classRCTTouchHandler withBlock:^(id touchHandler, SEL command, id touches, id eventName){ - if ([touches isKindOfClass:[NSSet class]] && [eventName isKindOfClass:[NSString class]]) { - @try { - NSString *reactEventName = (NSString *)eventName; - NSSet *reactTouches = (NSSet *)touches; - if ([reactEventName isEqualToString:ReactNativeTouchEndEventName]) { - for (UITouch *touch in reactTouches) { - UIView *targetView = ((UITouch *)touch).view.superview; - NSNumber *reactTag = nil; - // Find the closest React-managed touchable view like RCTTouchHandler - while(targetView) { - reactTag = [FBSDKViewHierarchy getViewReactTag:targetView]; - if (reactTag != nil && targetView.userInteractionEnabled) { - break; - } - targetView = targetView.superview; - } - FBSDKEventBinding *eventBinding = self->reactBindings[reactTag]; - if (reactTag != nil && eventBinding != nil) { - [eventBinding trackEvent:nil]; - } - } - } - } - @catch(NSException *exception) { - // Catch exception here to prevent LytroKit from crashing app - } - } - } named:@"dispatch_rn_event"]; + [FBSDKSwizzler swizzleSelector:@selector(_updateAndDispatchTouches:eventName:) onClass:classRCTTouchHandler withBlock:^(id touchHandler, SEL command, id touches, id eventName) { + if ([touches isKindOfClass:[NSSet class]] && [eventName isKindOfClass:[NSString class]]) { + @try { + NSString *reactEventName = (NSString *)eventName; + NSSet *reactTouches = (NSSet *)touches; + if ([reactEventName isEqualToString:ReactNativeTouchEndEventName]) { + for (UITouch *touch in reactTouches) { + UIView *targetView = ((UITouch *)touch).view.superview; + NSNumber *reactTag = nil; + // Find the closest React-managed touchable view like RCTTouchHandler + while (targetView) { + reactTag = [FBSDKViewHierarchy getViewReactTag:targetView]; + if (reactTag != nil && targetView.userInteractionEnabled) { + break; + } + targetView = targetView.superview; + } + FBSDKEventBinding *eventBinding = self->reactBindings[reactTag]; + if (reactTag != nil && eventBinding != nil) { + [eventBinding trackEvent:nil]; + } + } + } + } @catch (NSException *exception) { + // Catch exception here to prevent LytroKit from crashing app + } + } + } named:@"dispatch_rn_event"]; } - // UITableView + // UITableView void (^tableViewBlock)(UITableView *tableView, SEL cmd, id delegate) = @@ -201,7 +202,7 @@ - (void)start onClass:[UITableView class] withBlock:tableViewBlock named:@"match_table_view"]; - // UICollectionView + // UICollectionView void (^collectionViewBlock)(UICollectionView *collectionView, SEL cmd, id delegate) = @@ -218,7 +219,8 @@ - (void)start named:@"handle_collection_view"]; } -- (void)rematchBindings { +- (void)rematchBindings +{ if (0 == eventBindings.count) { return; } @@ -229,7 +231,8 @@ - (void)rematchBindings { } } -- (void)matchSubviewsIn:(UIView *)view { +- (void)matchSubviewsIn:(UIView *)view +{ if (!view) { return; } @@ -266,7 +269,8 @@ - (void)matchSubviewsIn:(UIView *)view { } // check if the view is matched to any event -- (void)matchView:(UIView *)view delegate:(id)delegate { +- (void)matchView:(UIView *)view delegate:(id)delegate +{ if (0 == eventBindings.count) { return; } @@ -361,7 +365,7 @@ - (void)matchView:(UIView *)view delegate:(id)delegate { for (FBSDKEventBinding *binding in bindings) { FBSDKCodelessPathComponent *component = binding.path.lastObject; if ((component.section == -1 || component.section == indexPath.section) - && (component.row == -1 || component.row == indexPath.row)) { + && (component.row == -1 || component.row == indexPath.row)) { UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; [binding trackEvent:cell]; } @@ -379,8 +383,9 @@ - (void)matchView:(UIView *)view delegate:(id)delegate { }); } -#pragma clang diagnostic pop -- (void)updateBindings:(NSArray *)bindings { + #pragma clang diagnostic pop +- (void)updateBindings:(NSArray *)bindings +{ if (eventBindings.count > 0 && eventBindings.count == bindings.count) { // Check whether event bindings are the same BOOL isSame = YES; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.h index 8c958fdd41..9c15759c7e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.h @@ -30,4 +30,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END - diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m index 936601a893..2e72a4faa9 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m @@ -17,7 +17,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKEventDeactivationManager.h" -#import "FBSDKTypeUtility.h" + +#import "FBSDKInternalUtility.h" #import "FBSDKServerConfigurationManager.h" static NSString *const DEPRECATED_PARAM_KEY = @"deprecated_param"; @@ -26,17 +27,17 @@ @interface FBSDKDeactivatedEvent : NSObject @property (nonatomic, readonly, copy) NSString *eventName; -@property (nonatomic, readonly, copy, nullable) NSSet *deactivatedParams; +@property (nullable, nonatomic, readonly, copy) NSSet *deactivatedParams; --(instancetype)initWithEventName:(NSString *)eventName - deactivatedParams:(NSSet *)deactivatedParams; +- (instancetype)initWithEventName:(NSString *)eventName + deactivatedParams:(NSSet *)deactivatedParams; @end @implementation FBSDKDeactivatedEvent --(instancetype)initWithEventName:(NSString *)eventName - deactivatedParams:(NSSet *)deactivatedParams +- (instancetype)initWithEventName:(NSString *)eventName + deactivatedParams:(NSSet *)deactivatedParams { self = [super init]; if (self) { @@ -54,21 +55,23 @@ @implementation FBSDKEventDeactivationManager static BOOL isEventDeactivationEnabled = NO; static NSMutableSet *_deactivatedEvents; -static NSMutableArray *_eventsWithDeactivatedParams; +static NSMutableArray *_eventsWithDeactivatedParams; + (void)enable { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSDictionary *restrictiveParams = [FBSDKServerConfigurationManager cachedServerConfiguration].restrictiveParams; - if (restrictiveParams) { - [FBSDKEventDeactivationManager updateDeactivatedEvents:restrictiveParams]; - isEventDeactivationEnabled = YES; - } - }); + @try { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *restrictiveParams = [FBSDKServerConfigurationManager cachedServerConfiguration].restrictiveParams; + if (restrictiveParams) { + [FBSDKEventDeactivationManager _updateDeactivatedEvents:restrictiveParams]; + isEventDeactivationEnabled = YES; + } + }); + } @catch (NSException *exception) {} } -+ (void)updateDeactivatedEvents:(nullable NSDictionary *)events ++ (void)_updateDeactivatedEvents:(nullable NSDictionary *)events { events = [FBSDKTypeUtility dictionaryValue:events]; if (events.count == 0) { @@ -98,32 +101,38 @@ + (void)updateDeactivatedEvents:(nullable NSDictionary *)events + (void)processEvents:(NSMutableArray *> *)events { - if (!isEventDeactivationEnabled) { - return; - } - NSArray *> *eventArray = [events copy]; - for (NSDictionary *> *event in eventArray) { - if ([_deactivatedEvents containsObject:event[@"event"][@"_eventName"]]) { - [events removeObject:event]; + @try { + if (!isEventDeactivationEnabled) { + return; } - } + NSArray *> *eventArray = [events copy]; + for (NSDictionary *> *event in eventArray) { + if ([_deactivatedEvents containsObject:event[@"event"][@"_eventName"]]) { + [events removeObject:event]; + } + } + } @catch (NSException *exception) {} } + (nullable NSDictionary *)processParameters:(nullable NSDictionary *)parameters eventName:(NSString *)eventName { - if (!isEventDeactivationEnabled || parameters.count == 0 || _eventsWithDeactivatedParams.count == 0) { - return parameters; - } - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters]; - for (NSString *key in [parameters keyEnumerator]) { - for (FBSDKDeactivatedEvent *event in _eventsWithDeactivatedParams) { - if ([event.eventName isEqualToString:eventName] && [event.deactivatedParams containsObject:key]) { - [params removeObjectForKey:key]; + @try { + if (!isEventDeactivationEnabled || parameters.count == 0 || _eventsWithDeactivatedParams.count == 0) { + return parameters; + } + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters]; + for (NSString *key in [parameters keyEnumerator]) { + for (FBSDKDeactivatedEvent *event in _eventsWithDeactivatedParams) { + if ([event.eventName isEqualToString:eventName] && [event.deactivatedParams containsObject:key]) { + [params removeObjectForKey:key]; + } } } + return [params copy]; + } @catch (NSException *exception) { + return parameters; } - return [params copy]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h index 432207fcbb..d099b7ce1e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h @@ -17,9 +17,9 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if SWIFT_PACKAGE -#import "FBSDKAppEvents.h" + #import "FBSDKAppEvents.h" #else -#import + #import #endif #import "FBSDKAppEventsUtility.h" @@ -79,6 +79,12 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionAuthMethodStart; /** Use to log the end of the last tried auth method as part of an auth request */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionAuthMethodEnd; +/** Use to log the start of a referral request */ +FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBReferralStart; + +/** Use to log the end of a referral request */ +FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBReferralEnd; + /** Use to log the timestamp for the transition to the Facebook native login dialog */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogStart; @@ -91,6 +97,9 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBDialogsWebLoginCompleted; /** Use to log the result of the App Switch OS AlertView. Only available on OS >= iOS10 */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionFASLoginDialogResult; +/** Use to log whether the app implements `applicationDidFinishLaunching:withOptions:` */ +FOUNDATION_EXPORT NSString *const FBSDKAppEventNameImplementsApplicationDidFinishLaunching; + /** Use to log the live streaming events from sdk */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKLiveStreamingStart; FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKLiveStreamingStop; @@ -140,7 +149,6 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventsDialogShareContentTypeVideo; FOUNDATION_EXPORT NSString *const FBSDKAppEventsDialogShareContentTypeCamera; FOUNDATION_EXPORT NSString *const FBSDKAppEventsDialogShareContentTypeUnknown; - FOUNDATION_EXPORT NSString *const FBSDKAppEventsDialogShareModeAutomatic; FOUNDATION_EXPORT NSString *const FBSDKAppEventsDialogShareModeBrowser; FOUNDATION_EXPORT NSString *const FBSDKAppEventsDialogShareModeNative; @@ -193,7 +201,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventsWKWebViewMessagesPixelIDKey; @interface FBSDKAppEvents (Internal) -@property (class, nonatomic, strong, readonly) FBSDKAppEvents *singleton; +@property (class, nonatomic, readonly, strong) FBSDKAppEvents *singleton; #ifdef DEBUG + (void)resetSingleton; @@ -224,7 +232,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventsWKWebViewMessagesPixelIDKey; valueToSum:(NSNumber *)valueToSum parameters:(NSDictionary *)parameters isImplicitlyLogged:(BOOL)isImplicitlyLogged - accessToken:(FBSDKAccessToken *)accessToken; + accessToken:(FBSDKAccessToken *)accessToken; + (void)logImplicitEvent:(NSString *)eventName valueToSum:(NSNumber *)valueToSum diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.h new file mode 100644 index 0000000000..db42b8eba8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.h @@ -0,0 +1,46 @@ +// 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 + +#if SWIFT_PACKAGE +#import "FBSDKCopying.h" +#else +#import +#endif + +#import "FBSDKAppEventsUtility.h" + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(AppEventsConfiguration) +@interface FBSDKAppEventsConfiguration : NSObject + +@property (nonatomic, readonly, assign) FBSDKAdvertisingTrackingStatus defaultATEStatus; + +@property (nonatomic, readonly, assign) BOOL advertiserIDCollectionEnabled; + +@property (nonatomic, readonly, assign) BOOL eventCollectionEnabled; + +- (instancetype)initWithJSON:(nullable NSDictionary *)dict; + ++ (instancetype)defaultConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m new file mode 100644 index 0000000000..383ce13123 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m @@ -0,0 +1,105 @@ +// 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 "FBSDKAppEventsConfiguration.h" + +#import "FBSDKCoreKit+Internal.h" + +#define FBSDK_APP_EVENTS_CONFIGURATION_DEFAULT_ATE_STATUS_KEY @"default_ate_status" +#define FBSDK_APP_EVENTS_CONFIGURATION_ADVERTISER_ID_TRACKING_ENABLED_KEY @"advertiser_id_collection_enabled" +#define FBSDK_APP_EVENTS_CONFIGURATION_EVENT_COLLECTION_ENABLED_KEY @"event_collection_enabled" + +@implementation FBSDKAppEventsConfiguration + +- (instancetype)initWithJSON:(nullable NSDictionary *)dict +{ + if ((self = [super init])) { + @try { + dict = [FBSDKTypeUtility dictionaryValue:dict]; + if (!dict) { + return FBSDKAppEventsConfiguration.defaultConfiguration; + } + NSDictionary *configs = [FBSDKTypeUtility dictionary:dict objectForKey:@"app_events_config" ofType:NSDictionary.class]; + if (!configs) { + return FBSDKAppEventsConfiguration.defaultConfiguration; + } + NSNumber *defaultATEStatus = [FBSDKTypeUtility numberValue:configs[FBSDK_APP_EVENTS_CONFIGURATION_DEFAULT_ATE_STATUS_KEY]] ?: @(FBSDKAdvertisingTrackingUnspecified); + NSNumber *advertiserIDCollectionEnabled = [FBSDKTypeUtility numberValue:configs[FBSDK_APP_EVENTS_CONFIGURATION_ADVERTISER_ID_TRACKING_ENABLED_KEY]] ?: @(YES); + NSNumber *eventCollectionEnabled = [FBSDKTypeUtility numberValue:configs[FBSDK_APP_EVENTS_CONFIGURATION_EVENT_COLLECTION_ENABLED_KEY]] ?: @(NO); + _defaultATEStatus = [defaultATEStatus integerValue]; + _advertiserIDCollectionEnabled = [advertiserIDCollectionEnabled boolValue]; + _eventCollectionEnabled = [eventCollectionEnabled boolValue]; + } @catch (NSException *exception) { + return FBSDKAppEventsConfiguration.defaultConfiguration; + } + } + return self; +} + +- (instancetype)initWithDefaultATEStatus:(FBSDKAdvertisingTrackingStatus)defaultATEStatus + advertiserIDCollectionEnabled:(BOOL)advertiserIDCollectionEnabled + eventCollectionEnabled:(BOOL)eventCollectionEnabled +{ + if ((self = [super init])) { + _defaultATEStatus = defaultATEStatus; + _advertiserIDCollectionEnabled = advertiserIDCollectionEnabled; + _eventCollectionEnabled = eventCollectionEnabled; + } + return self; +} + ++ (instancetype)defaultConfiguration +{ + FBSDKAppEventsConfiguration *config = [[FBSDKAppEventsConfiguration alloc] initWithDefaultATEStatus:FBSDKAdvertisingTrackingUnspecified + advertiserIDCollectionEnabled:YES + eventCollectionEnabled:NO]; + return config; +} + +#pragma mark - NSCoding + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + +- (instancetype)initWithCoder:(NSCoder *)decoder +{ + FBSDKAdvertisingTrackingStatus defaultATEStatus = [decoder decodeIntegerForKey:FBSDK_APP_EVENTS_CONFIGURATION_DEFAULT_ATE_STATUS_KEY]; + BOOL advertisingIDCollectionEnabled = [decoder decodeBoolForKey:FBSDK_APP_EVENTS_CONFIGURATION_ADVERTISER_ID_TRACKING_ENABLED_KEY]; + BOOL eventCollectionEnabled = [decoder decodeBoolForKey:FBSDK_APP_EVENTS_CONFIGURATION_EVENT_COLLECTION_ENABLED_KEY]; + return [[FBSDKAppEventsConfiguration alloc] initWithDefaultATEStatus:defaultATEStatus + advertiserIDCollectionEnabled:advertisingIDCollectionEnabled + eventCollectionEnabled:eventCollectionEnabled]; +} + +- (void)encodeWithCoder:(NSCoder *)encoder +{ + [encoder encodeInteger:_defaultATEStatus forKey:FBSDK_APP_EVENTS_CONFIGURATION_DEFAULT_ATE_STATUS_KEY]; + [encoder encodeBool:_advertiserIDCollectionEnabled forKey:FBSDK_APP_EVENTS_CONFIGURATION_ADVERTISER_ID_TRACKING_ENABLED_KEY]; + [encoder encodeBool:_eventCollectionEnabled forKey:FBSDK_APP_EVENTS_CONFIGURATION_EVENT_COLLECTION_ENABLED_KEY]; +} + +#pragma mark - NSCopying + +- (instancetype)copyWithZone:(NSZone *)zone +{ + return self; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.h new file mode 100644 index 0000000000..4f85e255d8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.h @@ -0,0 +1,36 @@ +// 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 "FBSDKAppEventsConfiguration.h" + +typedef void (^FBSDKAppEventsConfigurationManagerBlock)(void); + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(AppEventsConfigurationManager) +@interface FBSDKAppEventsConfigurationManager : NSObject + ++ (FBSDKAppEventsConfiguration *)cachedAppEventsConfiguration; + ++ (void)loadAppEventsConfigurationWithBlock:(FBSDKAppEventsConfigurationManagerBlock)block; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.m new file mode 100644 index 0000000000..28cb18d046 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfigurationManager.m @@ -0,0 +1,120 @@ +// 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 "FBSDKAppEventsConfigurationManager.h" + +#import "FBSDKCoreKit+Internal.h" + +static NSString *const FBSDKAppEventsConfigurationKey = @"com.facebook.sdk:FBSDKAppEventsConfiguration"; +static NSString *const FBSDKAppEventsConfigurationTimestampKey = @"com.facebook.sdk:FBSDKAppEventsConfigurationTimestamp"; +static const NSTimeInterval kTimeout = 4.0; + +static FBSDKAppEventsConfiguration *g_configuration; +static NSMutableArray *g_completionBlocks; +static NSDate *g_timestamp; +static BOOL g_requeryFinishedForAppStart; +static BOOL g_loadingConfiguration; + +@implementation FBSDKAppEventsConfigurationManager + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" ++ (void)initialize +{ + if (self == FBSDKAppEventsConfigurationManager.class) { + id data = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKAppEventsConfigurationKey]; + if ([data isKindOfClass:NSData.class]) { + g_configuration = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + } + if (!g_configuration) { + g_configuration = [FBSDKAppEventsConfiguration defaultConfiguration]; + } + g_completionBlocks = [NSMutableArray new]; + g_timestamp = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKAppEventsConfigurationTimestampKey]; + } +} + +#pragma clang diagnostic pop + ++ (FBSDKAppEventsConfiguration *)cachedAppEventsConfiguration +{ + return g_configuration; +} + ++ (void)loadAppEventsConfigurationWithBlock:(FBSDKAppEventsConfigurationManagerBlock)block +{ + NSString *appID = [FBSDKSettings appID]; + @synchronized(self) { + [FBSDKTypeUtility array:g_completionBlocks addObject:block]; + if (!appID || (g_requeryFinishedForAppStart && [self _isTimestampValid])) { + for (FBSDKAppEventsConfigurationManagerBlock completionBlock in g_completionBlocks) { + completionBlock(); + } + [g_completionBlocks removeAllObjects]; + return; + } + if (g_loadingConfiguration) { + return; + } + g_loadingConfiguration = true; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] + initWithGraphPath:appID + parameters:@{ + @"fields" : [NSString stringWithFormat:@"app_events_config.os_version(%@)", [UIDevice currentDevice].systemVersion] + }]; + FBSDKGraphRequestConnection *requestConnection = [FBSDKGraphRequestConnection new]; + requestConnection.timeout = kTimeout; + [requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + [self _processResponse:result error:error]; + }]; + [requestConnection start]; + } +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" ++ (void)_processResponse:(id)response + error:(NSError *)error +{ + NSDate *date = [NSDate date]; + @synchronized(self) { + g_loadingConfiguration = NO; + g_requeryFinishedForAppStart = YES; + if (error) { + return; + } + g_configuration = [[FBSDKAppEventsConfiguration alloc] initWithJSON:response]; + g_timestamp = date; + for (FBSDKAppEventsConfigurationManagerBlock completionBlock in g_completionBlocks) { + completionBlock(); + } + [g_completionBlocks removeAllObjects]; + } + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:g_configuration]; + [[NSUserDefaults standardUserDefaults] setObject:data forKey:FBSDKAppEventsConfigurationKey]; + [[NSUserDefaults standardUserDefaults] setObject:date forKey:FBSDKAppEventsConfigurationTimestampKey]; +} + +#pragma clang diagnostic pop + ++ (BOOL)_isTimestampValid +{ + return g_timestamp && [[NSDate date] timeIntervalSinceDate:g_timestamp] < 3600; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsDeviceInfo.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsDeviceInfo.m index 1d56868c0e..49c5a7fffb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsDeviceInfo.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsDeviceInfo.m @@ -22,8 +22,8 @@ #import #if !TARGET_OS_TV -#import -#import + #import + #import #endif #import @@ -36,10 +36,10 @@ #define FB_ARRAY_COUNT(x) sizeof(x) / sizeof(x[0]) -static const u_int FB_GROUP1_RECHECK_DURATION = 30 * 60; // seconds +static const u_int FB_GROUP1_RECHECK_DURATION = 30 * 60; // seconds // Apple reports storage in binary gigabytes (1024^3) in their About menus, etc. -static const u_int FB_GIGABYTE = 1024 * 1024 * 1024; // bytes +static const u_int FB_GIGABYTE = 1024 * 1024 * 1024; // bytes @implementation FBSDKAppEventsDeviceInfo { @@ -106,10 +106,9 @@ - (instancetype)init - (NSString *)encodedDeviceInfo { - @synchronized (self) { - + @synchronized(self) { BOOL isGroup1Expired = [self _isGroup1Expired]; - BOOL isEncodingExpired = isGroup1Expired; // Can || other groups in if we add them + BOOL isEncodingExpired = isGroup1Expired; // Can || other groups in if we add them // As long as group1 hasn't expired, we can just return the last generated value if (_encodedDeviceInfo && !isEncodingExpired) { @@ -131,7 +130,7 @@ - (NSString *)encodedDeviceInfo - (void)setEncodedDeviceInfo:(NSString *)encodedDeviceInfo { - @synchronized (self) { + @synchronized(self) { if (![_encodedDeviceInfo isEqualToString:encodedDeviceInfo]) { _encodedDeviceInfo = [encodedDeviceInfo copy]; } @@ -211,23 +210,23 @@ - (NSString *)_generateEncoding NSString *densityString = _density ? [NSString stringWithFormat:@"%.02f", _density] : @""; NSArray *arr = @[ - @"i2", // version - starts with 'i' for iOS, we'll use 'a' for Android - _bundleIdentifier ?: @"", - _longVersion ?: @"", - _shortVersion ?: @"", - _sysVersion ?: @"", - _machine ?: @"", - _language ?: @"", - _timeZoneAbbrev ?: @"", - _carrierName ?: @"", - _width ? @((unsigned long)_width) : @"", - _height ? @((unsigned long)_height) : @"", - densityString, - @(_coreCount) ?: @"", - @(_totalDiskSpaceGB) ?: @"", - @(_remainingDiskSpaceGB) ?: @"", - _timeZoneName ?: @"" - ]; + @"i2", // version - starts with 'i' for iOS, we'll use 'a' for Android + _bundleIdentifier ?: @"", + _longVersion ?: @"", + _shortVersion ?: @"", + _sysVersion ?: @"", + _machine ?: @"", + _language ?: @"", + _timeZoneAbbrev ?: @"", + _carrierName ?: @"", + _width ? @((unsigned long)_width) : @"", + _height ? @((unsigned long)_height) : @"", + densityString, + @(_coreCount) ?: @"", + @(_totalDiskSpaceGB) ?: @"", + @(_remainingDiskSpaceGB) ?: @"", + _timeZoneName ?: @"" + ]; return [FBSDKBasicUtility JSONStringForObject:arr error:NULL invalidObjectHandler:NULL]; } @@ -277,6 +276,7 @@ + (NSString *)_getCarrier return carrier.carrierName ?: @"NoCarrier"; #endif } + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsState.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsState.m index c2c0949778..c13b42393d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsState.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsState.m @@ -18,10 +18,9 @@ #import "FBSDKAppEventsState.h" -#import "FBSDKBasicUtility.h" #import "FBSDKEventDeactivationManager.h" +#import "FBSDKInternalUtility.h" #import "FBSDKRestrictiveDataFilterManager.h" -#import "FBSDKTypeUtility.h" #define FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY @"isImplicit" @@ -109,30 +108,32 @@ - (void)addEventsFromAppEventState:(FBSDKAppEventsState *)appEventsState } - (void)addEvent:(NSDictionary *)eventDictionary - isImplicit:(BOOL)isImplicit { + isImplicit:(BOOL)isImplicit +{ if (_mutableEvents.count >= FBSDK_APPEVENTSSTATE_MAX_EVENTS) { _numSkipped++; } else { [FBSDKTypeUtility array:_mutableEvents addObject:@{ - @"event" : [eventDictionary mutableCopy], - FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY : @(isImplicit) - }]; + @"event" : [eventDictionary mutableCopy], + FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY : @(isImplicit) + }]; } } -- (NSString *)extractReceiptData { +- (NSString *)extractReceiptData +{ NSMutableString *receipts_string = [NSMutableString string]; NSInteger transactionId = 1; - for (NSMutableDictionary* events in _mutableEvents) { + for (NSMutableDictionary *events in _mutableEvents) { NSMutableDictionary *event = events[@"event"]; - NSString* receipt = event[@"receipt_data"]; + NSString *receipt = event[@"receipt_data"]; // Add receipt id as the identifier for receipt data in event parameter. // Receipt data will be sent as post parameter rather than the event parameter if (receipt) { - NSString* idKey = [NSString stringWithFormat:@"receipt_%ld", (long)transactionId]; + NSString *idKey = [NSString stringWithFormat:@"receipt_%ld", (long)transactionId]; [FBSDKTypeUtility dictionary:event setObject:idKey forKey:FBSDK_APPEVENTSTATE_RECEIPTID_KEY]; - NSString* receiptWithId = [NSString stringWithFormat:@"%@::%@;;;", idKey, receipt]; + NSString *receiptWithId = [NSString stringWithFormat:@"%@::%@;;;", idKey, receipt]; [receipts_string appendString:receiptWithId]; transactionId++; } @@ -158,10 +159,10 @@ - (BOOL)isCompatibleWithAppEventsState:(FBSDKAppEventsState *)appEventsState - (BOOL)isCompatibleWithTokenString:(NSString *)tokenString appID:(NSString *)appID { // token strings can be nil (e.g., no user token) but appIDs should not. - BOOL tokenCompatible = ([self.tokenString isEqualToString:tokenString] || - (self.tokenString == nil && tokenString == nil)); - return (tokenCompatible && - [self.appID isEqualToString:appID]); + BOOL tokenCompatible = ([self.tokenString isEqualToString:tokenString] + || (self.tokenString == nil && tokenString == nil)); + return (tokenCompatible + && [self.appID isEqualToString:appID]); } - (NSString *)JSONStringForEvents:(BOOL)includeImplicitEvents diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsStateManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsStateManager.m index 95741839d5..1d8de63b1f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsStateManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsStateManager.m @@ -71,6 +71,7 @@ + (NSArray *)retrievePersistedAppEventsStates } return eventsStates; } + #pragma clang diagnostic pop #pragma mark - Private Helpers @@ -79,4 +80,5 @@ + (NSString *)filePath { return [FBSDKBasicUtility persistenceFilePath:@"com-facebook-sdk-AppEventsPersistedEvents.json"]; } + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h index 82ac6021d4..e257216113 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h @@ -57,8 +57,10 @@ NS_SWIFT_NAME(AppEventsUtility) + (void)logAndNotify:(NSString *)msg; + (NSString *)tokenStringToUseFor:(FBSDKAccessToken *)token; + (BOOL)validateIdentifier:(NSString *)identifier; -+ (id)getVariable:(NSString *)variableName fromInstance:(NSObject *)instance; + (NSNumber *)getNumberValue:(NSString *)text; ++ (BOOL)shouldDropAppEvent; + (BOOL)isSensitiveUserData:(NSString *)text; ++ (BOOL)isStandardEvent:(NSString *)event; ++ (long)convertToUnixTime:(NSDate *)date; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index 29664d6720..a4c01edeb5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -18,12 +18,14 @@ #import "FBSDKAppEventsUtility.h" -#import - #import +#import + #import "FBSDKAccessToken.h" #import "FBSDKAppEvents.h" +#import "FBSDKAppEventsConfiguration.h" +#import "FBSDKAppEventsConfigurationManager.h" #import "FBSDKAppEventsDeviceInfo.h" #import "FBSDKConstants.h" #import "FBSDKDynamicFrameworkLoader.h" @@ -38,10 +40,42 @@ #define FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY @"anon_id" #define FBSDK_APPEVENTSUTILITY_MAX_IDENTIFIER_LENGTH 40 +static NSArray *standardEvents; + @implementation FBSDKAppEventsUtility ++ (void)initialize +{ + standardEvents = @[ + FBSDKAppEventNameCompletedRegistration, + FBSDKAppEventNameViewedContent, + FBSDKAppEventNameSearched, + FBSDKAppEventNameRated, + FBSDKAppEventNameCompletedTutorial, + FBSDKAppEventNameAddedToCart, + FBSDKAppEventNameAddedToWishlist, + FBSDKAppEventNameInitiatedCheckout, + FBSDKAppEventNameAddedPaymentInfo, + FBSDKAppEventNamePurchased, + FBSDKAppEventNameAchievedLevel, + FBSDKAppEventNameUnlockedAchievement, + FBSDKAppEventNameSpentCredits, + FBSDKAppEventNameContact, + FBSDKAppEventNameCustomizeProduct, + FBSDKAppEventNameDonate, + FBSDKAppEventNameFindLocation, + FBSDKAppEventNameSchedule, + FBSDKAppEventNameStartTrial, + FBSDKAppEventNameSubmitApplication, + FBSDKAppEventNameSubscribe, + FBSDKAppEventNameAdImpression, + FBSDKAppEventNameAdClick + ]; +} + + (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventCategory - shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID { + shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID +{ NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; [FBSDKTypeUtility dictionary:parameters setObject:eventCategory forKey:@"event"]; @@ -52,14 +86,11 @@ + (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventC [FBSDKTypeUtility dictionary:parameters setObject:[FBSDKBasicUtility anonymousID] forKey:FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY]; - FBSDKAdvertisingTrackingStatus advertisingTrackingStatus = [[self class] advertisingTrackingStatus]; - if (advertisingTrackingStatus != FBSDKAdvertisingTrackingUnspecified) { - BOOL allowed = (advertisingTrackingStatus == FBSDKAdvertisingTrackingAllowed); - [FBSDKTypeUtility dictionary:parameters setObject:@(allowed).stringValue forKey:@"advertiser_tracking_enabled"]; - } - if (advertisingTrackingStatus == FBSDKAdvertisingTrackingAllowed) { + BOOL advertiserTrackingEnabled = [FBSDKSettings isAdvertiserTrackingEnabled]; + [FBSDKTypeUtility dictionary:parameters setObject:@(advertiserTrackingEnabled).stringValue forKey:@"advertiser_tracking_enabled"]; + if (advertiserTrackingEnabled) { NSString *userData = [FBSDKAppEvents getUserData]; - if (userData){ + if (userData) { [FBSDKTypeUtility dictionary:parameters setObject:userData forKey:@"ud"]; } } @@ -118,6 +149,12 @@ + (NSString *)advertiserID return nil; } + if (@available(iOS 14.0, *)) { + if (![FBSDKAppEventsConfigurationManager cachedAppEventsConfiguration].advertiserIDCollectionEnabled) { + return nil; + } + } + NSString *result = nil; Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); @@ -148,6 +185,14 @@ + (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus return status; } ++ (BOOL)isStandardEvent:(nullable NSString *)event +{ + if (!event) { + return NO; + } + return [standardEvents containsObject:event]; +} + #pragma mark - Internal, for testing + (void)clearLibraryFiles @@ -160,11 +205,13 @@ + (void)clearLibraryFiles + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)className { - FBSDKConditionalLog([NSThread isMainThread], - FBSDKLoggingBehaviorDeveloperErrors, - @"*** <%@, %@> is not called on the main thread. This can lead to errors.", - methodName, - className); + FBSDKConditionalLog( + [NSThread isMainThread], + FBSDKLoggingBehaviorDeveloperErrors, + @"*** <%@, %@> is not called on the main thread. This can lead to errors.", + methodName, + className + ); } + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason @@ -213,9 +260,9 @@ + (void)logAndNotify:(NSString *)msg allowLogAsDeveloperError:(BOOL)allowLogAsDe [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAppEventsLoggingResultNotification object:error]; } -+ (BOOL)matchString:(NSString *)string - firstCharacterSet:(NSCharacterSet *)firstCharacterSet -restOfStringCharacterSet:(NSCharacterSet *)restOfStringCharacterSet ++ (BOOL) matchString:(NSString *)string + firstCharacterSet:(NSCharacterSet *)firstCharacterSet + restOfStringCharacterSet:(NSCharacterSet *)restOfStringCharacterSet { if (string.length == 0) { return NO; @@ -254,8 +301,8 @@ + (BOOL)regexValidateIdentifier:(NSString *)identifier @synchronized(self) { if (![cachedIdentifiers containsObject:identifier]) { if ([self matchString:identifier - firstCharacterSet:firstCharacterSet - restOfStringCharacterSet:restOfStringCharacterSet]) { + firstCharacterSet:firstCharacterSet + restOfStringCharacterSet:restOfStringCharacterSet]) { [cachedIdentifiers addObject:identifier]; } else { return NO; @@ -290,7 +337,7 @@ + (NSString *)tokenStringToUseFor:(FBSDKAccessToken *)token // If there's an logging override app id present, then we don't want to use the client token since the client token // is intended to match up with the primary app id (and AppEvents doesn't require a client token). NSString *clientTokenString = [FBSDKSettings clientToken]; - if (clientTokenString && appID && [appID isEqualToString:token.appID]){ + if (clientTokenString && appID && [appID isEqualToString:token.appID]) { tokenString = [NSString stringWithFormat:@"%@|%@", appID, clientTokenString]; } else if (appID) { tokenString = nil; @@ -304,19 +351,13 @@ + (long)unixTimeNow return (long)round([NSDate date].timeIntervalSince1970); } -+ (id)getVariable:(NSString *)variableName fromInstance:(NSObject *)instance { - Ivar ivar = class_getInstanceVariable([instance class], variableName.UTF8String); - if (ivar != NULL) { - const char *encoding = ivar_getTypeEncoding(ivar); - if (encoding != NULL && encoding[0] == '@') { - return object_getIvar(instance, ivar); - } - } - - return nil; ++ (time_t)convertToUnixTime:(NSDate *)date +{ + return (time_t)round([date timeIntervalSince1970]); } -+ (NSNumber *)getNumberValue:(NSString *)text { ++ (NSNumber *)getNumberValue:(NSString *)text +{ NSNumber *value = @0; NSLocale *locale = [NSLocale currentLocale]; @@ -347,15 +388,15 @@ + (NSNumber *)getNumberValue:(NSString *)text { return value; } -+ (BOOL)isDebugBuild { ++ (BOOL)isDebugBuild +{ #if TARGET_IPHONE_SIMULATOR return YES; #else BOOL isDevelopment = NO; // There is no provisioning profile in AppStore Apps. - @try - { + @try { NSData *data = [NSData dataWithContentsOfFile:[NSBundle.mainBundle pathForResource:@"embedded" ofType:@"mobileprovision"]]; if (data) { const char *bytes = [data bytes]; @@ -369,16 +410,22 @@ + (BOOL)isDebugBuild { } return isDevelopment; - } - @catch(NSException *exception) - { - - } + } @catch (NSException *exception) {} return NO; #endif } ++ (BOOL)shouldDropAppEvent +{ + if (@available(iOS 14.0, *)) { + if ([FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingDisallowed && ![FBSDKAppEventsConfigurationManager cachedAppEventsConfiguration].eventCollectionEnabled) { + return YES; + } + } + return NO; +} + + (BOOL)isSensitiveUserData:(NSString *)text { if (0 == text.length) { @@ -412,10 +459,11 @@ + (BOOL)isCreditCardNumber:(NSString *)text for (int i = (int)text.length - 1; i >= 0; i--) { int digit = chars[i] - '0'; - if (isOdd) + if (isOdd) { oddSum += digit; - else + } else { evenSum += digit / 5 + (2 * digit) % 10; + } isOdd = !isOdd; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKHybridAppEventsScriptMessageHandler.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKHybridAppEventsScriptMessageHandler.m index a42268fc25..b4c594b51e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKHybridAppEventsScriptMessageHandler.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKHybridAppEventsScriptMessageHandler.m @@ -20,16 +20,16 @@ #if !TARGET_OS_TV -#import "FBSDKHybridAppEventsScriptMessageHandler.h" + #import "FBSDKHybridAppEventsScriptMessageHandler.h" -#if SWIFT_PACKAGE -#import "FBSDKAppEvents.h" -#else -#import -#endif + #if SWIFT_PACKAGE + #import "FBSDKAppEvents.h" + #else + #import + #endif -#import "FBSDKAppEvents+Internal.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKAppEvents+Internal.h" + #import "FBSDKInternalUtility.h" NSString *const FBSDKAppEventsWKWebViewMessagesPixelReferralParamKey = @"_fb_pixel_referral_id"; @@ -37,19 +37,19 @@ @implementation FBSDKHybridAppEventsScriptMessageHandler -- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { - +- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message +{ if ([message.name isEqualToString:FBSDKAppEventsWKWebViewMessagesHandlerKey]) { NSString *event = message.body[FBSDKAppEventsWKWebViewMessagesEventKey]; if (event.length > 0) { NSString *stringedParams = message.body[FBSDKAppEventsWKWebViewMessagesParamsKey]; - NSMutableDictionary *params = nil; + NSMutableDictionary *params = nil; NSError *jsonParseError = nil; if ([stringedParams isKindOfClass:[NSString class]]) { params = [FBSDKTypeUtility JSONObjectWithData:[stringedParams dataUsingEncoding:NSUTF8StringEncoding] - options:NSJSONReadingMutableContainers - error:&jsonParseError - ]; + options:NSJSONReadingMutableContainers + error:&jsonParseError + ]; } NSString *pixelID = message.body[FBSDKAppEventsWKWebViewMessagesPixelIDKey]; if (pixelID == nil) { @@ -59,8 +59,7 @@ - (void)userContentController:(WKUserContentController *)userContentController d if (jsonParseError != nil || ![params isKindOfClass:[NSDictionary class]] || params == nil) { [FBSDKAppEventsUtility logAndNotify:@"Could not find parameters for your Pixel request. Check your webview Pixel configuration."]; params = [[NSMutableDictionary alloc] initWithObjectsAndKeys:pixelID, FBSDKAppEventsWKWebViewMessagesPixelReferralParamKey, nil]; - } - else { + } else { [FBSDKTypeUtility dictionary:params setObject:pixelID forKey:FBSDKAppEventsWKWebViewMessagesPixelReferralParamKey]; } [FBSDKAppEvents logInternalEvent:event diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKPaymentObserver.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKPaymentObserver.m index f7b35462d5..ceb6bc294c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKPaymentObserver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKPaymentObserver.m @@ -20,9 +20,8 @@ #import -#import "FBSDKCoreKit+Internal.h" - #import "FBSDKAppEvents+Internal.h" +#import "FBSDKCoreKit+Internal.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" @@ -48,16 +47,16 @@ static NSString *const FBSDKGateKeeperAppEventsIfAutoLogSubs = @"app_events_if_auto_log_subs"; -@interface FBSDKPaymentProductRequestor : NSObject +@interface FBSDKPaymentProductRequestor : NSObject @property (nonatomic, retain) SKPaymentTransaction *transaction; -- (instancetype)initWithTransaction:(SKPaymentTransaction*)transaction; +- (instancetype)initWithTransaction:(SKPaymentTransaction *)transaction; - (void)resolveProducts; @end -@interface FBSDKPaymentObserver() +@interface FBSDKPaymentObserver () @end @implementation FBSDKPaymentObserver @@ -88,7 +87,7 @@ + (FBSDKPaymentObserver *)singleton return shared; } -- (instancetype) init +- (instancetype)init { self = [super init]; if (self) { @@ -99,7 +98,7 @@ - (instancetype) init - (void)startObservingTransactions { - @synchronized (self) { + @synchronized(self) { if (!_observingTransactions) { [(SKPaymentQueue *)[fbsdkdfl_SKPaymentQueueClass() defaultQueue] addTransactionObserver:self]; _observingTransactions = YES; @@ -109,7 +108,7 @@ - (void)startObservingTransactions - (void)stopObservingTransactions { - @synchronized (self) { + @synchronized(self) { if (_observingTransactions) { [(SKPaymentQueue *)[fbsdkdfl_SKPaymentQueueClass() defaultQueue] removeTransactionObserver:self]; _observingTransactions = NO; @@ -141,7 +140,7 @@ - (void)handleTransaction:(SKPaymentTransaction *)transaction @end -@interface FBSDKPaymentProductRequestor() +@interface FBSDKPaymentProductRequestor () @property (nonatomic, retain) SKProductsRequest *productRequest; @end @@ -159,7 +158,7 @@ + (void)initialize } } -- (instancetype)initWithTransaction:(SKPaymentTransaction*)transaction +- (instancetype)initWithTransaction:(SKPaymentTransaction *)transaction { self = [super init]; if (self) { @@ -211,9 +210,9 @@ - (NSString *)getTruncatedString:(NSString *)inputString - (void)logTransactionEvent:(SKProduct *)product { - if ([self isSubscription:product] && - [FBSDKGateKeeperManager boolForKey:FBSDKGateKeeperAppEventsIfAutoLogSubs - defaultValue:NO]) { + if ([self isSubscription:product] + && [FBSDKGateKeeperManager boolForKey:FBSDKGateKeeperAppEventsIfAutoLogSubs + defaultValue:NO]) { [self logImplicitSubscribeTransaction:self.transaction ofProduct:product]; } else { [self logImplicitPurchaseTransaction:self.transaction ofProduct:product]; @@ -252,18 +251,18 @@ - (BOOL)isSubscription:(SKProduct *)product default: break; } SKPayment *payment = transaction.payment; - NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary: @{ - FBSDKAppEventParameterNameContentID: payment.productIdentifier ?: @"", - FBSDKAppEventParameterNameNumItems: @(payment.quantity), - FBSDKAppEventParameterNameTransactionDate: transactionDate ?: @"", - }]; + NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary:@{ + FBSDKAppEventParameterNameContentID : payment.productIdentifier ?: @"", + FBSDKAppEventParameterNameNumItems : @(payment.quantity), + FBSDKAppEventParameterNameTransactionDate : transactionDate ?: @"", + }]; if (product) { - [eventParameters addEntriesFromDictionary: @{ - FBSDKAppEventParameterNameCurrency: [product.priceLocale objectForKey:NSLocaleCurrencyCode], - FBSDKAppEventParameterNameNumItems: @(payment.quantity), - FBSDKAppEventParameterNameProductTitle: [self getTruncatedString:product.localizedTitle], - FBSDKAppEventParameterNameDescription: [self getTruncatedString:product.localizedDescription], - }]; + [eventParameters addEntriesFromDictionary:@{ + FBSDKAppEventParameterNameCurrency : [product.priceLocale objectForKey:NSLocaleCurrencyCode], + FBSDKAppEventParameterNameNumItems : @(payment.quantity), + FBSDKAppEventParameterNameProductTitle : [self getTruncatedString:product.localizedTitle], + FBSDKAppEventParameterNameDescription : [self getTruncatedString:product.localizedDescription], + }]; if (transactionID) { [FBSDKTypeUtility dictionary:eventParameters setObject:transactionID forKey:FBSDKAppEventParameterNameTransactionID]; } @@ -330,8 +329,8 @@ - (BOOL)isStartTrial:(SKPaymentTransaction *)transaction if (paymentDiscount) { NSArray *discounts = product.discounts; for (SKProductDiscount *discount in discounts) { - if (discount.paymentMode == SKProductDiscountPaymentModeFreeTrial && - [paymentDiscount.identifier isEqualToString:discount.identifier]) { + if (discount.paymentMode == SKProductDiscountPaymentModeFreeTrial + && [paymentDiscount.identifier isEqualToString:discount.identifier]) { return YES; } } @@ -341,8 +340,8 @@ - (BOOL)isStartTrial:(SKPaymentTransaction *)transaction #endif // introductory offer starting from iOS 11.2 if (@available(iOS 11.2, *)) { - if (product.introductoryPrice && - product.introductoryPrice.paymentMode == SKProductDiscountPaymentModeFreeTrial) { + if (product.introductoryPrice + && product.introductoryPrice.paymentMode == SKProductDiscountPaymentModeFreeTrial) { NSString *originalTransactionID = transaction.originalTransaction.transactionIdentifier; // only consider the very first trial transaction as start trial if (!originalTransactionID) { @@ -407,8 +406,8 @@ - (NSString *)durationOfSubscriptionPeriod:(id)subcriptionPeriod - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { - NSArray* products = response.products; - NSArray* invalidProductIdentifiers = response.invalidProductIdentifiers; + NSArray *products = response.products; + NSArray *invalidProductIdentifiers = response.invalidProductIdentifiers; if (products.count + invalidProductIdentifiers.count != 1) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKPaymentObserver: Expect to resolve one product per request"]; @@ -517,7 +516,7 @@ - (void)logImplicitTransactionEvent:(NSString *)eventName NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary:parameters]; if ([_eventsWithReceipt containsObject:eventName]) { - NSData* receipt = [self fetchDeviceReceipt]; + NSData *receipt = [self fetchDeviceReceipt]; if (receipt) { NSString *base64encodedReceipt = [receipt base64EncodedStringWithOptions:0]; [FBSDKTypeUtility dictionary:eventParameters setObject:base64encodedReceipt forKey:@"receipt_data"]; @@ -537,7 +536,7 @@ - (void)logImplicitTransactionEvent:(NSString *)eventName } // Fetch the current receipt for this application. -- (NSData*)fetchDeviceReceipt +- (NSData *)fetchDeviceReceipt { NSURL *receiptURL = [NSBundle bundleForClass:[self class]].appStoreReceiptURL; NSData *receipt = [NSData dataWithContentsOfURL:receiptURL]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m index 7188789d20..7a9d9d2541 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m @@ -26,24 +26,22 @@ #import "FBSDKServerConfigurationManager.h" #import "FBSDKSettings.h" - // Filename and keys for session length -NSString *const FBSDKTimeSpentFilename = @"com-facebook-sdk-AppEventsTimeSpent.json"; -static NSString *const FBSDKTimeSpentPersistKeySessionSecondsSpent = @"secondsSpentInCurrentSession"; -static NSString *const FBSDKTimeSpentPersistKeySessionNumInterruptions = @"numInterruptions"; -static NSString *const FBSDKTimeSpentPersistKeyLastSuspendTime = @"lastSuspendTime"; -static NSString *const FBSDKTimeSpentPersistKeySessionID = @"sessionID"; - -static NSString *const FBSDKAppEventNameActivatedApp = @"fb_mobile_activate_app"; -static NSString *const FBSDKAppEventNameDeactivatedApp = @"fb_mobile_deactivate_app"; -static NSString *const FBSDKAppEventParameterNameSessionInterruptions = @"fb_mobile_app_interruptions"; -static NSString *const FBSDKAppEventParameterNameTimeBetweenSessions = @"fb_mobile_time_between_sessions"; -static NSString *const FBSDKAppEventParameterNameSessionID = @"_session_id"; - - -static const int SECS_PER_MIN = 60; -static const int SECS_PER_HOUR = 60 * SECS_PER_MIN; -static const int SECS_PER_DAY = 24 * SECS_PER_HOUR; +NSString *const FBSDKTimeSpentFilename = @"com-facebook-sdk-AppEventsTimeSpent.json"; +static NSString *const FBSDKTimeSpentPersistKeySessionSecondsSpent = @"secondsSpentInCurrentSession"; +static NSString *const FBSDKTimeSpentPersistKeySessionNumInterruptions = @"numInterruptions"; +static NSString *const FBSDKTimeSpentPersistKeyLastSuspendTime = @"lastSuspendTime"; +static NSString *const FBSDKTimeSpentPersistKeySessionID = @"sessionID"; + +static NSString *const FBSDKAppEventNameActivatedApp = @"fb_mobile_activate_app"; +static NSString *const FBSDKAppEventNameDeactivatedApp = @"fb_mobile_deactivate_app"; +static NSString *const FBSDKAppEventParameterNameSessionInterruptions = @"fb_mobile_app_interruptions"; +static NSString *const FBSDKAppEventParameterNameTimeBetweenSessions = @"fb_mobile_time_between_sessions"; +static NSString *const FBSDKAppEventParameterNameSessionID = @"_session_id"; + +static const int SECS_PER_MIN = 60; +static const int SECS_PER_HOUR = 60 * SECS_PER_MIN; +static const int SECS_PER_DAY = 24 * SECS_PER_HOUR; static NSString *g_sourceApplication; static BOOL g_isOpenedFromAppLink; @@ -70,7 +68,7 @@ 150 * SECS_PER_DAY, 180 * SECS_PER_DAY, 365 * SECS_PER_DAY, - LONG_MAX, // keep as LONG_MAX to guarantee loop will terminate + LONG_MAX, // keep as LONG_MAX to guarantee loop will terminate }; /** @@ -88,9 +86,9 @@ @implementation FBSDKTimeSpentData BOOL _isCurrentlyLoaded; BOOL _shouldLogActivateEvent; BOOL _shouldLogDeactivateEvent; - long _secondsSpentInCurrentSession; - long _timeSinceLastSuspend; - int _numInterruptionsInCurrentSession; + long _secondsSpentInCurrentSession; + long _timeSinceLastSuspend; + int _numInterruptionsInCurrentSession; long _lastRestoreTime; long _lastSuspendTime; NSString *_sessionID; @@ -127,7 +125,6 @@ + (FBSDKTimeSpentData *)singleton // Calculate and persist time spent data for this instance of the app activation. - (void)instanceSuspend { - [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; if (!_isCurrentlyLoaded) { FBSDKConditionalLog(YES, FBSDKLoggingBehaviorInformational, @"[FBSDKTimeSpentData suspend] invoked without corresponding restore"); @@ -152,7 +149,7 @@ - (void)instanceSuspend FBSDKTimeSpentPersistKeySessionNumInterruptions : @(_numInterruptionsInCurrentSession), FBSDKTimeSpentPersistKeyLastSuspendTime : @(now), FBSDKTimeSpentPersistKeySessionID : _sessionID, - }; + }; NSString *content = [FBSDKBasicUtility JSONStringForObject:timeSpentData error:NULL invalidObjectHandler:NULL]; @@ -167,19 +164,16 @@ - (void)instanceSuspend _isCurrentlyLoaded = NO; } - // Called during activation - either through an explicit 'activateApp' call or implicitly when the app is foregrounded. // In both cases, we restore the persisted event data. In the case of the activateApp, we log an 'app activated' // event if there's been enough time between the last deactivation and now. - (void)instanceRestore:(BOOL)calledFromActivateApp { - [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; // It's possible to call this multiple times during the time the app is in the foreground. If this is the case, // just restore persisted data the first time. if (!_isCurrentlyLoaded) { - NSString *content = [[NSString alloc] initWithContentsOfFile:[FBSDKBasicUtility persistenceFilePath:FBSDKTimeSpentFilename] usedEncoding:nil @@ -190,7 +184,6 @@ - (void)instanceRestore:(BOOL)calledFromActivateApp long now = [FBSDKAppEventsUtility unixTimeNow]; if (!content) { - // Nothing persisted, so this is the first launch. _sessionID = [NSUUID UUID].UUIDString; _secondsSpentInCurrentSession = 0; @@ -200,16 +193,14 @@ - (void)instanceRestore:(BOOL)calledFromActivateApp // We want to log the app activation event on the first launch, but not the deactivate event _shouldLogActivateEvent = YES; _shouldLogDeactivateEvent = NO; - } else { - NSDictionary *results = [FBSDKBasicUtility objectForJSONString:content error:NULL]; _lastSuspendTime = [results[FBSDKTimeSpentPersistKeyLastSuspendTime] longValue]; _timeSinceLastSuspend = now - _lastSuspendTime; _secondsSpentInCurrentSession = [results[FBSDKTimeSpentPersistKeySessionSecondsSpent] intValue]; - _sessionID = results[FBSDKTimeSpentPersistKeySessionID] ? : [NSUUID UUID].UUIDString; + _sessionID = results[FBSDKTimeSpentPersistKeySessionID] ?: [NSUUID UUID].UUIDString; _numInterruptionsInCurrentSession = [results[FBSDKTimeSpentPersistKeySessionNumInterruptions] intValue]; _shouldLogActivateEvent = (_timeSinceLastSuspend > [FBSDKServerConfigurationManager cachedServerConfiguration].sessionTimoutInterval); @@ -221,7 +212,6 @@ - (void)instanceRestore:(BOOL)calledFromActivateApp // so errant or test uses doesn't blow out the cardinality on the backend processing _numInterruptionsInCurrentSession = MIN(_numInterruptionsInCurrentSession + 1, 200); } - } _lastRestoreTime = now; @@ -256,9 +246,9 @@ - (void)instanceRestore:(BOOL)calledFromActivateApp - (NSDictionary *)appEventsParametersForActivate { return @{ - FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication], - FBSDKAppEventParameterNameSessionID: _sessionID, - }; + FBSDKAppEventParameterLaunchSource : [[self class] getSourceApplication], + FBSDKAppEventParameterNameSessionID : _sessionID, + }; } - (NSDictionary *)appEventsParametersForDeactivate @@ -270,9 +260,8 @@ - (NSDictionary *)appEventsParametersForDeactivate NSMutableDictionary *params = [@{ FBSDKAppEventParameterNameSessionInterruptions : @(_numInterruptionsInCurrentSession), FBSDKAppEventParameterNameTimeBetweenSessions : [NSString stringWithFormat:@"session_quanta_%d", quantaIndex], - FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication], - FBSDKAppEventParameterNameSessionID : _sessionID ?: @"", - } mutableCopy]; + FBSDKAppEventParameterLaunchSource : [[self class] getSourceApplication], + FBSDKAppEventParameterNameSessionID : _sessionID ?: @"", } mutableCopy]; if (_lastSuspendTime) { [FBSDKTypeUtility dictionary:params setObject:@(_lastSuspendTime) forKey:FBSDKAppEventParameterLogTime]; } @@ -297,9 +286,9 @@ + (NSString *)getSourceApplication if (g_isOpenedFromAppLink) { openType = @"AppLink"; } - return (g_sourceApplication ? - [NSString stringWithFormat:@"%@(%@)", openType, g_sourceApplication] - : openType); + return (g_sourceApplication + ? [NSString stringWithFormat:@"%@(%@)", openType, g_sourceApplication] + : openType); } + (void)resetSourceApplication diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.h index 8993e43781..b976866078 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import @interface FBSDKIntegrityManager : NSObject diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.m index 1339a0a48b..3b7e749555 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKIntegrityManager.m @@ -20,13 +20,12 @@ #if !TARGET_OS_TV -#import "FBSDKIntegrityManager.h" + #import "FBSDKIntegrityManager.h" -#import "FBSDKBasicUtility.h" -#import "FBSDKGateKeeperManager.h" -#import "FBSDKModelManager.h" -#import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKGateKeeperManager.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKModelManager.h" + #import "FBSDKSettings.h" static BOOL isIntegrityEnabled = NO; static BOOL isSampleEnabled = NO; @@ -48,7 +47,7 @@ + (void)enable NSMutableDictionary *restrictiveParams = [NSMutableDictionary dictionary]; for (NSString *key in [parameters keyEnumerator]) { - NSString *valueString =[FBSDKTypeUtility stringValue:parameters[key]]; + NSString *valueString = [FBSDKTypeUtility stringValue:parameters[key]]; BOOL shouldFilter = [FBSDKModelManager processIntegrity:key] || [FBSDKModelManager processIntegrity:valueString]; if (shouldFilter) { [FBSDKTypeUtility dictionary:restrictiveParams setObject:isSampleEnabled ? valueString : @"" forKey:key]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveData.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveData.m index c7bb652f57..a07bfa17de 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveData.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveData.m @@ -20,7 +20,7 @@ #import -#import "FBSDKTypeUtility.h" +#import "FBSDKInternalUtility.h" #define RESTRICTIVE_PARAM @"restrictive_param" #define DEPRECATED_PARAM @"deprecated_param" diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m index f907dce6e4..4bceefd88c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m @@ -18,8 +18,7 @@ #import "FBSDKRestrictiveDataFilterManager.h" -#import "FBSDKBasicUtility.h" -#import "FBSDKTypeUtility.h" +#import "FBSDKInternalUtility.h" #import "FBSDKServerConfigurationManager.h" @interface FBSDKRestrictiveEventFilter : NSObject @@ -30,15 +29,15 @@ @interface FBSDKRestrictiveEventFilter : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; --(instancetype)initWithEventName:(NSString *)eventName - restrictiveParams:(NSDictionary *)restrictiveParams; +- (instancetype)initWithEventName:(NSString *)eventName + restrictiveParams:(NSDictionary *)restrictiveParams; @end @implementation FBSDKRestrictiveEventFilter --(instancetype)initWithEventName:(NSString *)eventName - restrictiveParams:(NSDictionary *)restrictiveParams +- (instancetype)initWithEventName:(NSString *)eventName + restrictiveParams:(NSDictionary *)restrictiveParams { self = [super init]; if (self) { @@ -54,43 +53,43 @@ -(instancetype)initWithEventName:(NSString *)eventName @implementation FBSDKRestrictiveDataFilterManager static BOOL g_isRestrictiveEventFilterEnabled; -static NSMutableArray *_params; +static NSMutableArray *_params; static NSMutableSet *_restrictedEvents; -+ (void)updateFilters:(nullable NSDictionary *)restrictiveParams ++ (void)_updateFilters:(nullable NSDictionary *)restrictiveParams { static NSString *const RESTRICTIVE_PARAM_KEY = @"restrictive_param"; static NSString *const PROCESS_EVENT_NAME_KEY = @"process_event_name"; restrictiveParams = [FBSDKTypeUtility dictionaryValue:restrictiveParams]; if (restrictiveParams.count > 0) { - @synchronized (self) { - [_params removeAllObjects]; - [_restrictedEvents removeAllObjects]; - NSMutableArray *eventFilterArray = [NSMutableArray array]; - NSMutableSet *restrictedEventSet = [NSMutableSet set]; - for (NSString *eventName in restrictiveParams.allKeys) { - NSDictionary *eventInfo = restrictiveParams[eventName]; - if (!eventInfo) { - continue; - } - if (eventInfo[RESTRICTIVE_PARAM_KEY]) { - FBSDKRestrictiveEventFilter *restrictiveEventFilter = [[FBSDKRestrictiveEventFilter alloc] initWithEventName:eventName - restrictiveParams:eventInfo[RESTRICTIVE_PARAM_KEY]]; - [FBSDKTypeUtility array:eventFilterArray addObject:restrictiveEventFilter]; - } - if (restrictiveParams[eventName][PROCESS_EVENT_NAME_KEY]) { - [restrictedEventSet addObject:eventName]; - } - } - _params = eventFilterArray; - _restrictedEvents = restrictedEventSet; - } + @synchronized(self) { + [_params removeAllObjects]; + [_restrictedEvents removeAllObjects]; + NSMutableArray *eventFilterArray = [NSMutableArray array]; + NSMutableSet *restrictedEventSet = [NSMutableSet set]; + for (NSString *eventName in restrictiveParams.allKeys) { + NSDictionary *eventInfo = restrictiveParams[eventName]; + if (!eventInfo) { + continue; + } + if (eventInfo[RESTRICTIVE_PARAM_KEY]) { + FBSDKRestrictiveEventFilter *restrictiveEventFilter = [[FBSDKRestrictiveEventFilter alloc] initWithEventName:eventName + restrictiveParams:eventInfo[RESTRICTIVE_PARAM_KEY]]; + [FBSDKTypeUtility array:eventFilterArray addObject:restrictiveEventFilter]; + } + if (restrictiveParams[eventName][PROCESS_EVENT_NAME_KEY]) { + [restrictedEventSet addObject:eventName]; + } + } + _params = eventFilterArray; + _restrictedEvents = restrictedEventSet; + } } } -+ (nullable NSString *)getMatchedDataTypeWithEventName:(NSString *)eventName - paramKey:(NSString *)paramKey ++ (nullable NSString *)_getMatchedDataTypeWithEventName:(NSString *)eventName + paramKey:(NSString *)paramKey { // match by params in custom events with event name for (FBSDKRestrictiveEventFilter *filter in _params) { @@ -104,70 +103,78 @@ + (nullable NSString *)getMatchedDataTypeWithEventName:(NSString *)eventName return nil; } -+ (NSDictionary *)processParameters:(NSDictionary *)parameters - eventName:(NSString *)eventName ++ (NSDictionary *)processParameters:(NSDictionary *)parameters + eventName:(NSString *)eventName { if (!g_isRestrictiveEventFilterEnabled) { return parameters; } if (parameters) { - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters]; - NSMutableDictionary *restrictedParams = [NSMutableDictionary dictionary]; + @try { + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:parameters]; + NSMutableDictionary *restrictedParams = [NSMutableDictionary dictionary]; + + for (NSString *key in [parameters keyEnumerator]) { + NSString *type = [FBSDKRestrictiveDataFilterManager _getMatchedDataTypeWithEventName:eventName + paramKey:key]; + if (type) { + [FBSDKTypeUtility dictionary:restrictedParams setObject:type forKey:key]; + [params removeObjectForKey:key]; + } + } - for (NSString *key in [parameters keyEnumerator]) { - NSString *type = [FBSDKRestrictiveDataFilterManager getMatchedDataTypeWithEventName:eventName - paramKey:key]; - if (type) { - [FBSDKTypeUtility dictionary:restrictedParams setObject:type forKey:key]; - [params removeObjectForKey:key]; + if ([[restrictedParams allKeys] count] > 0) { + NSString *restrictedParamsJSONString = [FBSDKBasicUtility JSONStringForObject:restrictedParams + error:NULL + invalidObjectHandler:NULL]; + [FBSDKTypeUtility dictionary:params setObject:restrictedParamsJSONString forKey:@"_restrictedParams"]; } - } - if ([[restrictedParams allKeys] count] > 0) { - NSString *restrictedParamsJSONString = [FBSDKBasicUtility JSONStringForObject:restrictedParams - error:NULL - invalidObjectHandler:NULL]; - [FBSDKTypeUtility dictionary:params setObject:restrictedParamsJSONString forKey:@"_restrictedParams"]; + return [params copy]; + } @catch (NSException *exception) { + return parameters; } - - return [params copy]; } return nil; } -+ (void)processEvents:(NSMutableArray *> *)events ++ (void)processEvents:(NSMutableArray *> *)events { - if (!g_isRestrictiveEventFilterEnabled) { - return; - } + @try { + if (!g_isRestrictiveEventFilterEnabled) { + return; + } - static NSString *const REPLACEMENT_STRING = @"_removed_"; + static NSString *const REPLACEMENT_STRING = @"_removed_"; - for (NSDictionary *> *event in events) { - if ([FBSDKRestrictiveDataFilterManager isRestrictedEvent:event[@"event"][@"_eventName"]]) { - [event[@"event"] setValue:REPLACEMENT_STRING forKey:@"_eventName"]; + for (NSDictionary *> *event in events) { + if ([FBSDKRestrictiveDataFilterManager _isRestrictedEvent:event[@"event"][@"_eventName"]]) { + [FBSDKTypeUtility dictionary:event[@"event"] setObject:REPLACEMENT_STRING forKey:@"_eventName"]; + } } - } + } @catch (NSException *exception) {} } + (void)enable { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSDictionary *restrictiveParams = [FBSDKServerConfigurationManager cachedServerConfiguration].restrictiveParams; - if (restrictiveParams) { - [FBSDKRestrictiveDataFilterManager updateFilters:restrictiveParams]; - g_isRestrictiveEventFilterEnabled = YES; - } - }); + @try { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *restrictiveParams = [FBSDKServerConfigurationManager cachedServerConfiguration].restrictiveParams; + if (restrictiveParams) { + [FBSDKRestrictiveDataFilterManager _updateFilters:restrictiveParams]; + g_isRestrictiveEventFilterEnabled = YES; + } + }); + } @catch (NSException *exception) {} } #pragma mark Helper functions -+ (BOOL)isRestrictedEvent:(NSString *)eventName ++ (BOOL)_isRestrictedEvent:(NSString *)eventName { - @synchronized (self) { + @synchronized(self) { return [_restrictedEvents containsObject:eventName]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKMLMacros.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKMLMacros.h index df56151f24..991691a9c3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKMLMacros.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKMLMacros.h @@ -19,7 +19,7 @@ #ifndef FBSDKMLMacros_h #define FBSDKMLMacros_h -// keys for ML +// keys for ML #define MODEL_REQUEST_INTERVAL (60 * 60 * 24 * 3) #define MODEL_REQUEST_TIMESTAMP_KEY @"com.facebook.sdk:FBSDKModelRequestTimestamp" @@ -36,7 +36,7 @@ #define MTMLTaskAppEventPredKey @"MTML_APP_EVENT_PRED" #define MTMLTaskIntegrityDetectKey @"MTML_INTEGRITY_DETECT" -// keys for Suggested Event +// keys for Suggested Event #define SUGGEST_EVENT_KEY @"SUGGEST_EVENT" #define DENSE_FEATURE_KEY @"DENSE_FEATURE" #define SUGGESTED_EVENT_OTHER @"other" diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.h index 4b9873288e..307f9d75ad 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.mm b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.mm index 717b9262f3..c79d8d46fe 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.mm +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelManager.mm @@ -20,22 +20,21 @@ #if !TARGET_OS_TV -#import "FBSDKModelManager.h" - -#import "FBSDKAppEvents+Internal.h" -#import "FBSDKIntegrityManager.h" -#import "FBSDKFeatureExtractor.h" -#import "FBSDKFeatureManager.h" -#import "FBSDKGraphRequest.h" -#import "FBSDKGraphRequestConnection.h" -#import "FBSDKSettings.h" -#import "FBSDKSuggestedEventsIndexer.h" -#import "FBSDKTypeUtility.h" -#import "FBSDKMLMacros.h" -#import "FBSDKModelParser.h" -#import "FBSDKModelRuntime.hpp" -#import "FBSDKModelUtility.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKModelManager.h" + + #import "FBSDKAppEvents+Internal.h" + #import "FBSDKFeatureExtractor.h" + #import "FBSDKFeatureManager.h" + #import "FBSDKGraphRequest.h" + #import "FBSDKGraphRequestConnection.h" + #import "FBSDKIntegrityManager.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKMLMacros.h" + #import "FBSDKModelParser.h" + #import "FBSDKModelRuntime.hpp" + #import "FBSDKModelUtility.h" + #import "FBSDKSettings.h" + #import "FBSDKSuggestedEventsIndexer.h" static NSString *const INTEGRITY_NONE = @"none"; static NSString *const INTEGRITY_ADDRESS = @"address"; @@ -54,60 +53,68 @@ @implementation FBSDKModelManager -#pragma mark - Public methods + #pragma mark - Public methods + (void)enable { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *languageCode = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; - // If the languageCode could not be fetched successfully, it's regarded as "en" by default. - if (languageCode && ![languageCode isEqualToString:@"en"]) { - return; - } + @try { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *languageCode = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; + // If the languageCode could not be fetched successfully, it's regarded as "en" by default. + if (languageCode && ![languageCode isEqualToString:@"en"]) { + return; + } - NSString *dirPath = [NSTemporaryDirectory() stringByAppendingPathComponent:FBSDK_ML_MODEL_PATH]; - if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) { - [[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:NULL error:NULL]; - } - _directoryPath = dirPath; - _modelInfo = [[NSUserDefaults standardUserDefaults] objectForKey:MODEL_INFO_KEY]; - NSDate *timestamp = [[NSUserDefaults standardUserDefaults] objectForKey:MODEL_REQUEST_TIMESTAMP_KEY]; - if ([_modelInfo count] == 0 || ![FBSDKFeatureManager isEnabled:FBSDKFeatureModelRequest] || ![self isValidTimestamp:timestamp]) { - // fetch api - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] - initWithGraphPath:[NSString stringWithFormat:@"%@/model_asset", [FBSDKSettings appID]]]; - - [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - if (!error) { - NSDictionary *resultDictionary = [FBSDKTypeUtility dictionaryValue:result]; - NSDictionary *modelInfo = [self convertToDictionary:resultDictionary[MODEL_DATA_KEY]]; - if (modelInfo) { - _modelInfo = [modelInfo mutableCopy]; - [self processMTML]; - // update cache for model info and timestamp - [[NSUserDefaults standardUserDefaults] setObject:_modelInfo forKey:MODEL_INFO_KEY]; - [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:MODEL_REQUEST_TIMESTAMP_KEY]; + NSString *dirPath = [NSTemporaryDirectory() stringByAppendingPathComponent:FBSDK_ML_MODEL_PATH]; + if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) { + [[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:NULL error:NULL]; + } + _directoryPath = dirPath; + _modelInfo = [[NSUserDefaults standardUserDefaults] objectForKey:MODEL_INFO_KEY]; + NSDate *timestamp = [[NSUserDefaults standardUserDefaults] objectForKey:MODEL_REQUEST_TIMESTAMP_KEY]; + if ([_modelInfo count] == 0 || ![FBSDKFeatureManager isEnabled:FBSDKFeatureModelRequest] || ![self isValidTimestamp:timestamp]) { + // fetch api + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] + initWithGraphPath:[NSString stringWithFormat:@"%@/model_asset", [FBSDKSettings appID]]]; + + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + if (!error) { + NSDictionary *resultDictionary = [FBSDKTypeUtility dictionaryValue:result]; + NSDictionary *modelInfo = [self convertToDictionary:resultDictionary[MODEL_DATA_KEY]]; + if (modelInfo) { + _modelInfo = [modelInfo mutableCopy]; + [self processMTML]; + // update cache for model info and timestamp + [[NSUserDefaults standardUserDefaults] setObject:_modelInfo forKey:MODEL_INFO_KEY]; + [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:MODEL_REQUEST_TIMESTAMP_KEY]; + } } - } + [self checkFeaturesAndExecuteForMTML]; + }]; + } else { [self checkFeaturesAndExecuteForMTML]; - }]; - } else { - [self checkFeaturesAndExecuteForMTML]; - } - }); + } + }); + } @catch (NSException *exception) { + NSLog(@"Fail to enable model manager, exception reason: %@", exception.reason); + } } + (nullable NSDictionary *)getRulesForKey:(NSString *)useCase { - NSDictionary *model = [FBSDKTypeUtility dictionary:_modelInfo objectForKey:useCase ofType:NSObject.class]; - if (model && model[VERSION_ID_KEY]) { - NSString *filePath = [_directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@.rules", useCase, model[VERSION_ID_KEY]]]; - if (filePath) { - NSData *ruelsData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:nil]; - NSDictionary *rules = [FBSDKTypeUtility JSONObjectWithData:ruelsData options:0 error:nil]; - return rules; + @try { + NSDictionary *model = [FBSDKTypeUtility dictionary:_modelInfo objectForKey:useCase ofType:NSObject.class]; + if (model && model[VERSION_ID_KEY]) { + NSString *filePath = [_directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@.rules", useCase, model[VERSION_ID_KEY]]]; + if (filePath) { + NSData *ruelsData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:nil]; + NSDictionary *rules = [FBSDKTypeUtility JSONObjectWithData:ruelsData options:0 error:nil]; + return rules; + } } + } @catch (NSException *exception) { + NSLog(@"Fail to get rules for usecase %@ from ml model, exception reason: %@", useCase, exception.reason); } return nil; } @@ -138,71 +145,79 @@ + (nullable NSArray *)getThresholdsForKey:(NSString *)useCase if (!_modelInfo) { return nil; } - NSDictionary * modelInfo = _modelInfo[useCase]; + NSDictionary *modelInfo = _modelInfo[useCase]; if (!modelInfo) { return nil; } return modelInfo[THRESHOLDS_KEY]; } -#pragma mark - Integrity Inferencer method + #pragma mark - Integrity Inferencer method + (BOOL)processIntegrity:(nullable NSString *)param { - if (param.length == 0 || _MTMLWeights.size() == 0) { - return false; - } - NSArray *integrityMapping = [self getIntegrityMapping]; - NSString *text = [FBSDKModelUtility normalizeText:param]; - const char *bytes = [text UTF8String]; - if ((int)strlen(bytes) == 0) { - return false; - } - NSArray *thresholds = [FBSDKModelManager getThresholdsForKey:MTMLTaskIntegrityDetectKey]; - if (thresholds.count != integrityMapping.count) { - return false; - } - const fbsdk::MTensor& res = fbsdk::predictOnMTML("integrity_detect", bytes, _MTMLWeights, nullptr); - const float *res_data = res.data(); NSString *integrityType = INTEGRITY_NONE; - for (int i = 0; i < thresholds.count; i++) { - if ((float)res_data[i] >= (float)[[FBSDKTypeUtility array:thresholds objectAtIndex:i] floatValue]) { - integrityType = [FBSDKTypeUtility array:integrityMapping objectAtIndex:i]; - break; + @try { + if (param.length == 0 || _MTMLWeights.size() == 0) { + return false; + } + NSArray *integrityMapping = [self getIntegrityMapping]; + NSString *text = [FBSDKModelUtility normalizeText:param]; + const char *bytes = [text UTF8String]; + if ((int)strlen(bytes) == 0) { + return false; } + NSArray *thresholds = [FBSDKModelManager getThresholdsForKey:MTMLTaskIntegrityDetectKey]; + if (thresholds.count != integrityMapping.count) { + return false; + } + const fbsdk::MTensor &res = fbsdk::predictOnMTML("integrity_detect", bytes, _MTMLWeights, nullptr); + const float *res_data = res.data(); + for (int i = 0; i < thresholds.count; i++) { + if ((float)res_data[i] >= (float)[[FBSDKTypeUtility array:thresholds objectAtIndex:i] floatValue]) { + integrityType = [FBSDKTypeUtility array:integrityMapping objectAtIndex:i]; + break; + } + } + } @catch (NSException *exception) { + NSLog(@"Fail to process parameter for integrity usecase, exception reason: %@", exception.reason); } return ![integrityType isEqualToString:INTEGRITY_NONE]; } -#pragma mark - SuggestedEvents Inferencer method + #pragma mark - SuggestedEvents Inferencer method + (NSString *)processSuggestedEvents:(NSString *)textFeature denseData:(nullable float *)denseData { - NSArray *eventMapping = [FBSDKModelManager getSuggestedEventsMapping]; - if (textFeature.length == 0 || _MTMLWeights.size() == 0 || !denseData) { - return SUGGESTED_EVENT_OTHER; - } - const char *bytes = [textFeature UTF8String]; - if ((int)strlen(bytes) == 0) { - return SUGGESTED_EVENT_OTHER; - } + @try { + NSArray *eventMapping = [FBSDKModelManager getSuggestedEventsMapping]; + if (textFeature.length == 0 || _MTMLWeights.size() == 0 || !denseData) { + return SUGGESTED_EVENT_OTHER; + } + const char *bytes = [textFeature UTF8String]; + if ((int)strlen(bytes) == 0) { + return SUGGESTED_EVENT_OTHER; + } - NSArray *thresholds = [FBSDKModelManager getThresholdsForKey:MTMLTaskAppEventPredKey]; - if (thresholds.count != eventMapping.count) { - return SUGGESTED_EVENT_OTHER; - } + NSArray *thresholds = [FBSDKModelManager getThresholdsForKey:MTMLTaskAppEventPredKey]; + if (thresholds.count != eventMapping.count) { + return SUGGESTED_EVENT_OTHER; + } - const fbsdk::MTensor& res = fbsdk::predictOnMTML("app_event_pred", bytes, _MTMLWeights, denseData); - const float *res_data = res.data(); - for (int i = 0; i < thresholds.count; i++) { - if ((float)res_data[i] >= (float)[[FBSDKTypeUtility array:thresholds objectAtIndex:i] floatValue]) { - return [FBSDKTypeUtility array:eventMapping objectAtIndex:i]; + const fbsdk::MTensor &res = fbsdk::predictOnMTML("app_event_pred", bytes, _MTMLWeights, denseData); + const float *res_data = res.data(); + for (int i = 0; i < thresholds.count; i++) { + if ((float)res_data[i] >= (float)[[FBSDKTypeUtility array:thresholds objectAtIndex:i] floatValue]) { + return [FBSDKTypeUtility array:eventMapping objectAtIndex:i]; + } } + } @catch (NSException *exception) { + NSLog(@"Fail to process suggested events, exception reason: %@", exception.reason); } return SUGGESTED_EVENT_OTHER; } -#pragma mark - Private methods + #pragma mark - Private methods + (BOOL)isValidTimestamp:(NSDate *)timestamp { @@ -226,10 +241,10 @@ + (void)processMTML } if (mtmlAssetUri && mtmlVersionId > 0) { [FBSDKTypeUtility dictionary:_modelInfo setObject:@{ - USE_CASE_KEY: MTMLKey, - ASSET_URI_KEY: mtmlAssetUri, - VERSION_ID_KEY: [NSNumber numberWithLong:mtmlVersionId], - } forKey:MTMLKey]; + USE_CASE_KEY : MTMLKey, + ASSET_URI_KEY : mtmlAssetUri, + VERSION_ID_KEY : [NSNumber numberWithLong:mtmlVersionId], + } forKey:MTMLKey]; } } @@ -265,7 +280,7 @@ + (void)getModelAndRules:(NSString *)useCaseKey NSDictionary *model = [FBSDKTypeUtility dictionary:_modelInfo objectForKey:useCaseKey ofType:NSObject.class]; if (!model || !_directoryPath) { - return; + return; } NSFileManager *fileManager = [NSFileManager defaultManager]; @@ -292,13 +307,14 @@ + (void)getModelAndRules:(NSString *)useCaseKey rulesFilePath = [_directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@.rules", useCaseKey, model[VERSION_ID_KEY]]]; [self download:rulesUrlString filePath:rulesFilePath queue:queue group:group]; } - dispatch_group_notify(group, dispatch_get_main_queue(), ^{ - if (handler) { - if ([fileManager fileExistsAtPath:assetFilePath] && (!rulesFilePath || [fileManager fileExistsAtPath:rulesFilePath])) { + dispatch_group_notify(group, + dispatch_get_main_queue(), ^{ + if (handler) { + if ([fileManager fileExistsAtPath:assetFilePath] && (!rulesFilePath || [fileManager fileExistsAtPath:rulesFilePath])) { handler(); + } } - } - }); + }); } + (void)clearCacheForModel:(NSDictionary *)model @@ -324,13 +340,14 @@ + (void)download:(NSString *)urlString if (!filePath || [[NSFileManager defaultManager] fileExistsAtPath:filePath]) { return; } - dispatch_group_async(group, queue, ^{ - NSURL *url = [NSURL URLWithString:urlString]; - NSData *urlData = [NSData dataWithContentsOfURL:url]; - if (urlData) { - [urlData writeToFile:filePath atomically:YES]; - } - }); + dispatch_group_async(group, + queue, ^{ + NSURL *url = [NSURL URLWithString:urlString]; + NSData *urlData = [NSData dataWithContentsOfURL:url]; + if (urlData) { + [urlData writeToFile:filePath atomically:YES]; + } + }); } + (nullable NSMutableDictionary *)convertToDictionary:(NSArray *> *)models @@ -341,7 +358,7 @@ + (void)download:(NSString *)urlString NSMutableDictionary *modelInfo = [NSMutableDictionary dictionary]; for (NSDictionary *model in models) { if (model[USE_CASE_KEY]) { - [modelInfo addEntriesFromDictionary:@{model[USE_CASE_KEY]:model}]; + [modelInfo addEntriesFromDictionary:@{model[USE_CASE_KEY] : model}]; } } return modelInfo; @@ -356,13 +373,12 @@ + (void)download:(NSString *)urlString { return @[SUGGESTED_EVENT_OTHER, - FBSDKAppEventNameCompletedRegistration, - FBSDKAppEventNameAddedToCart, - FBSDKAppEventNamePurchased, - FBSDKAppEventNameInitiatedCheckout]; + FBSDKAppEventNameCompletedRegistration, + FBSDKAppEventNameAddedToCart, + FBSDKAppEventNamePurchased, + FBSDKAppEventNameInitiatedCheckout]; } - @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.h index fa583c6e90..d1de42574e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.h @@ -20,9 +20,9 @@ #if !TARGET_OS_TV -#import + #import -#import "FBSDKTensor.hpp" + #import "FBSDKTensor.hpp" NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.mm b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.mm index 443d7acef9..fdf3566643 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.mm +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelParser.mm @@ -20,9 +20,10 @@ #if !TARGET_OS_TV -#import "FBSDKMLMacros.h" -#import "FBSDKModelParser.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKModelParser.h" + + #import "FBSDKInternalUtility.h" + #import "FBSDKMLMacros.h" NS_ASSUME_NONNULL_BEGIN @@ -36,7 +37,7 @@ @implementation FBSDKModelParser } const void *data = weightsData.bytes; - NSUInteger totalLength = weightsData.length; + NSUInteger totalLength = weightsData.length; if (totalLength < 4) { // Make sure data length is valid @@ -52,9 +53,9 @@ @implementation FBSDKModelParser char *json = (char *)data + 4; NSDictionary *info = [FBSDKTypeUtility JSONObjectWithData:[NSData dataWithBytes:json length:length] - options:0 - error:nil]; - NSArray *keys = [[info allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *key1, NSString *key2) { + options:0 + error:nil]; + NSArray *keys = [[info allKeys] sortedArrayUsingComparator:^NSComparisonResult (NSString *key1, NSString *key2) { return [key1 compare:key2]; }]; @@ -104,18 +105,19 @@ + (bool)validateWeights:(std::unordered_map)weights return [self checkWeights:weights withExpectedInfo:weightsInfoDict]; } -#pragma mark - private methods + #pragma mark - private methods + (NSDictionary *)getKeysMapping { return @{ - @"embedding.weight": @"embed.weight", - @"dense1.weight": @"fc1.weight", - @"dense2.weight": @"fc2.weight", - @"dense3.weight": @"fc3.weight", - @"dense1.bias": @"fc1.bias", - @"dense2.bias": @"fc2.bias", - @"dense3.bias": @"fc3.bias"}; + @"embedding.weight" : @"embed.weight", + @"dense1.weight" : @"fc1.weight", + @"dense2.weight" : @"fc2.weight", + @"dense3.weight" : @"fc3.weight", + @"dense1.bias" : @"fc1.bias", + @"dense2.bias" : @"fc2.bias", + @"dense3.bias" : @"fc3.bias" + }; } + (NSDictionary *)getMTMLWeightsInfo @@ -128,14 +130,15 @@ + (bool)validateWeights:(std::unordered_map)weights @"convs.1.bias" : @[@(64)], @"convs.2.weight" : @[@(64), @(64), @(3)], @"convs.2.bias" : @[@(64)], - @"fc1.weight": @[@(128), @(190)], - @"fc1.bias": @[@(128)], - @"fc2.weight": @[@(64), @(128)], - @"fc2.bias": @[@(64)], - @"integrity_detect.weight": @[@(3), @(64)], - @"integrity_detect.bias": @[@(3)], - @"app_event_pred.weight": @[@(5), @(64)], - @"app_event_pred.bias": @[@(5)]}; + @"fc1.weight" : @[@(128), @(190)], + @"fc1.bias" : @[@(128)], + @"fc2.weight" : @[@(64), @(128)], + @"fc2.bias" : @[@(64)], + @"integrity_detect.weight" : @[@(3), @(64)], + @"integrity_detect.bias" : @[@(3)], + @"app_event_pred.weight" : @[@(5), @(64)], + @"app_event_pred.bias" : @[@(5)] + }; } + (bool)checkWeights:(std::unordered_map)weights @@ -150,13 +153,13 @@ + (bool)checkWeights:(std::unordered_map)weights return false; } fbsdk::MTensor tensor = weights[std::string([key UTF8String])]; - const std::vector& actualSize = tensor.sizes(); + const std::vector &actualSize = tensor.sizes(); NSArray *expectedSize = weightsInfoDict[key]; if (actualSize.size() != expectedSize.count) { return false; } for (int i = 0; i < expectedSize.count; i++) { - if((int)actualSize[i] != (int)[[FBSDKTypeUtility array:expectedSize objectAtIndex:i] intValue]) { + if ((int)actualSize[i] != (int)[[FBSDKTypeUtility array:expectedSize objectAtIndex:i] intValue]) { return false; } } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelRuntime.hpp b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelRuntime.hpp index 8f9f8a29c0..97cd4a752c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelRuntime.hpp +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelRuntime.hpp @@ -20,314 +20,328 @@ #if !TARGET_OS_TV -#include -#include -#include -#include + #include -#import + #include + #include + #include -#include "FBSDKTensor.hpp" + #import -#define SEQ_LEN 128 -#define DENSE_FEATURE_LEN 30 + #include "FBSDKTensor.hpp" -namespace fbsdk { - -static void relu(MTensor& x) { - float min = 0; - float max = FLT_MAX; - float *x_data = x.mutable_data(); - vDSP_vclip(x_data, 1, &min, &max, x_data, 1, x.count()); -} + #define SEQ_LEN 128 + #define DENSE_FEATURE_LEN 30 -static void flatten(MTensor& x, int start_dim) { - const std::vector& shape = x.sizes(); - std::vector new_shape; - for (int i = 0; i < start_dim; i++) { - new_shape.push_back(shape[i]); - } - int count = 1; - for (int i = start_dim; i < shape.size(); i++) { - count *= shape[i]; +namespace fbsdk { + static void relu(MTensor &x) + { + float min = 0; + float max = FLT_MAX; + float *x_data = x.mutable_data(); + vDSP_vclip(x_data, 1, &min, &max, x_data, 1, x.count()); } - new_shape.push_back(count); - x.Reshape(new_shape); -} -static MTensor concatenate(std::vector& tensors) { - int n_examples = tensors[0]->size(0); - int count = 0; - for (int i = 0; i < tensors.size(); i++) { - count += tensors[i]->size(1); + static void flatten(MTensor &x, int start_dim) + { + const std::vector &shape = x.sizes(); + std::vector new_shape; + for (int i = 0; i < start_dim; i++) { + new_shape.push_back(shape[i]); + } + int count = 1; + for (int i = start_dim; i < shape.size(); i++) { + count *= shape[i]; + } + new_shape.push_back(count); + x.Reshape(new_shape); } - MTensor y({n_examples, count}); - float *y_data = y.mutable_data(); - for (int i = 0; i < tensors.size(); i++) { - int this_count = (int)tensors[i]->size(1); - const float *this_data = tensors[i]->data(); - for (int n = 0; n < n_examples; n++) { - memcpy(y_data + n * count, this_data + n * this_count, this_count * sizeof(float)); + + static MTensor concatenate(std::vector &tensors) + { + int n_examples = tensors[0]->size(0); + int count = 0; + for (int i = 0; i < tensors.size(); i++) { + count += tensors[i]->size(1); } - y_data += this_count; + MTensor y({n_examples, count}); + float *y_data = y.mutable_data(); + for (int i = 0; i < tensors.size(); i++) { + int this_count = (int)tensors[i]->size(1); + const float *this_data = tensors[i]->data(); + for (int n = 0; n < n_examples; n++) { + memcpy(y_data + n * count, this_data + n * this_count, this_count * sizeof(float)); + } + y_data += this_count; + } + return y; } - return y; -} -static void softmax(MTensor& x) { - int n_examples = x.size(0); - int n_channel = x.size(1); - float *x_data = x.mutable_data(); - float max; - float sum; - for (int n = 0; n < n_examples; n++) { - vDSP_maxv(x_data, 1, &max, n_channel); - max = -max; - vDSP_vsadd(x_data, 1, &max, x_data, 1, n_channel); - vvexpf(x_data, x_data, &n_channel); - vDSP_sve(x_data, 1, &sum, n_channel); - vDSP_vsdiv(x_data, 1, &sum, x_data, 1, n_channel); - x_data += n_channel; + static void softmax(MTensor &x) + { + int n_examples = x.size(0); + int n_channel = x.size(1); + float *x_data = x.mutable_data(); + float max; + float sum; + for (int n = 0; n < n_examples; n++) { + vDSP_maxv(x_data, 1, &max, n_channel); + max = -max; + vDSP_vsadd(x_data, 1, &max, x_data, 1, n_channel); + vvexpf(x_data, x_data, &n_channel); + vDSP_sve(x_data, 1, &sum, n_channel); + vDSP_vsdiv(x_data, 1, &sum, x_data, 1, n_channel); + x_data += n_channel; + } } -} -static std::vector vectorize(const char *texts, const int seq_length) { - int str_len = (int)strlen(texts); - std::vector vec(seq_length, 0); - for (int i = 0; i < seq_length; i++) { - if (i < str_len){ - vec[i] = static_cast(texts[i]); + static std::vector vectorize(const char *texts, const int seq_length) + { + int str_len = (int)strlen(texts); + std::vector vec(seq_length, 0); + for (int i = 0; i < seq_length; i++) { + if (i < str_len) { + vec[i] = static_cast(texts[i]); + } } + return vec; } - return vec; -} -static MTensor embedding(const char *texts, const int seq_length, const MTensor& w) { - // TODO: T65152708 support batch prediction - const std::vector& vec = vectorize(texts, seq_length); - int n_examples = 1; - int embedding_size = w.size(1); - MTensor y({n_examples, seq_length, embedding_size}); - const float* w_data = w.data(); - float *y_data = y.mutable_data(); - for (int i = 0; i < n_examples; i++) { - for (int j = 0; j < seq_length; j++) { - memcpy(y_data, w_data + vec[i * seq_length + j] * embedding_size, (size_t)(embedding_size * sizeof(float))); - y_data += embedding_size; + static MTensor embedding(const char *texts, const int seq_length, const MTensor &w) + { + // TODO: T65152708 support batch prediction + const std::vector &vec = vectorize(texts, seq_length); + int n_examples = 1; + int embedding_size = w.size(1); + MTensor y({n_examples, seq_length, embedding_size}); + const float *w_data = w.data(); + float *y_data = y.mutable_data(); + for (int i = 0; i < n_examples; i++) { + for (int j = 0; j < seq_length; j++) { + memcpy(y_data, w_data + vec[i * seq_length + j] * embedding_size, (size_t)(embedding_size * sizeof(float))); + y_data += embedding_size; + } } + return y; } - return y; -} -/* - x shape: n_examples, in_vector_size - w shape: in_vector_size, out_vector_size - b shape: out_vector_size - return shape: n_examples, out_vector_size - */ -static MTensor dense(const MTensor& x, const MTensor& w, const MTensor& b) { - int n_examples = x.size(0); - int in_vector_size = x.size(1); - int out_vector_size = w.size(1); - MTensor y({n_examples, out_vector_size}); - float *y_data = y.mutable_data(); - const float *b_data = b.data(); - vDSP_mmul(x.data(), 1, w.data(), 1, y_data, 1, n_examples, out_vector_size, in_vector_size); - for (int i = 0; i < out_vector_size; i++) { - vDSP_vsadd(y_data + i, out_vector_size, b_data + i, y_data + i, out_vector_size, n_examples); + /* + x shape: n_examples, in_vector_size + w shape: in_vector_size, out_vector_size + b shape: out_vector_size + return shape: n_examples, out_vector_size + */ + static MTensor dense(const MTensor &x, const MTensor &w, const MTensor &b) + { + int n_examples = x.size(0); + int in_vector_size = x.size(1); + int out_vector_size = w.size(1); + MTensor y({n_examples, out_vector_size}); + float *y_data = y.mutable_data(); + const float *b_data = b.data(); + vDSP_mmul(x.data(), 1, w.data(), 1, y_data, 1, n_examples, out_vector_size, in_vector_size); + for (int i = 0; i < out_vector_size; i++) { + vDSP_vsadd(y_data + i, out_vector_size, b_data + i, y_data + i, out_vector_size, n_examples); + } + return y; } - return y; -} -/* - x shape: n_examples, seq_len, input_size - w shape: kernel_size, input_size, output_size - return shape: n_examples, seq_len - kernel_size + 1, output_size - */ -static MTensor conv1D(const MTensor& x, const MTensor& w) { - int n_examples = x.size(0); - int seq_len = x.size(1); - int input_size = x.size(2); - int kernel_size = w.size(0); - int output_size = w.size(2); - MTensor y({n_examples, seq_len - kernel_size + 1, output_size}); - MTensor temp_x({kernel_size, input_size}); - MTensor temp_w({kernel_size, input_size}); - const float *x_data = x.data(); - const float *w_data = w.data(); - float *y_data = y.mutable_data(); - float *temp_x_data = temp_x.mutable_data(); - float *temp_w_data = temp_w.mutable_data(); - float sum; - for (int n = 0; n < n_examples; n++){ - for (int o = 0; o < output_size; o++){ - for (int i = 0; i < seq_len - kernel_size + 1; i++) { - for (int m = 0; m < kernel_size; m++) { - for (int k = 0; k < input_size; k++) { - temp_x_data[m * input_size + k] = x_data[n * (seq_len * input_size) + (m + i) * input_size + k]; - temp_w_data[m * input_size + k] = w_data[(m * input_size + k) * output_size + o]; + /* + x shape: n_examples, seq_len, input_size + w shape: kernel_size, input_size, output_size + return shape: n_examples, seq_len - kernel_size + 1, output_size + */ + static MTensor conv1D(const MTensor &x, const MTensor &w) + { + int n_examples = x.size(0); + int seq_len = x.size(1); + int input_size = x.size(2); + int kernel_size = w.size(0); + int output_size = w.size(2); + MTensor y({n_examples, seq_len - kernel_size + 1, output_size}); + MTensor temp_x({kernel_size, input_size}); + MTensor temp_w({kernel_size, input_size}); + const float *x_data = x.data(); + const float *w_data = w.data(); + float *y_data = y.mutable_data(); + float *temp_x_data = temp_x.mutable_data(); + float *temp_w_data = temp_w.mutable_data(); + float sum; + for (int n = 0; n < n_examples; n++) { + for (int o = 0; o < output_size; o++) { + for (int i = 0; i < seq_len - kernel_size + 1; i++) { + for (int m = 0; m < kernel_size; m++) { + for (int k = 0; k < input_size; k++) { + temp_x_data[m * input_size + k] = x_data[n * (seq_len * input_size) + (m + i) * input_size + k]; + temp_w_data[m * input_size + k] = w_data[(m * input_size + k) * output_size + o]; + } } + vDSP_dotpr(temp_x_data, 1, temp_w_data, 1, &sum, (size_t)(kernel_size * input_size)); + y_data[(n * (output_size * (seq_len - kernel_size + 1)) + i * output_size + o)] = sum; } - vDSP_dotpr(temp_x_data, 1, temp_w_data, 1, &sum, (size_t)(kernel_size * input_size)); - y_data[(n * (output_size * (seq_len - kernel_size + 1)) + i * output_size + o)] = sum; } } + return y; } - return y; -} -/* - input shape: n_examples, len, n_channel - return shape: n_examples, len - pool_size + 1, n_channel - */ -static MTensor maxPool1D(const MTensor& x, const int pool_size) { - int n_examples = x.size(0); - int input_len = x.size(1); - int n_channel = x.size(2); - int output_len = input_len - pool_size + 1; - MTensor y({n_examples, output_len, n_channel}); - const float *x_data = x.data(); - float *y_data = y.mutable_data(); - for (int n = 0; n < n_examples; n++) { - for (int c = 0; c < n_channel; c++) { - for (int i = 0; i < output_len; i++) { - float this_max = -FLT_MAX; - for (int r = i; r < i + pool_size; r++) { - this_max = fmax(this_max, x_data[n * (n_channel * input_len) + r * n_channel + c]); + /* + input shape: n_examples, len, n_channel + return shape: n_examples, len - pool_size + 1, n_channel + */ + static MTensor maxPool1D(const MTensor &x, const int pool_size) + { + int n_examples = x.size(0); + int input_len = x.size(1); + int n_channel = x.size(2); + int output_len = input_len - pool_size + 1; + MTensor y({n_examples, output_len, n_channel}); + const float *x_data = x.data(); + float *y_data = y.mutable_data(); + for (int n = 0; n < n_examples; n++) { + for (int c = 0; c < n_channel; c++) { + for (int i = 0; i < output_len; i++) { + float this_max = -FLT_MAX; + for (int r = i; r < i + pool_size; r++) { + this_max = fmax(this_max, x_data[n * (n_channel * input_len) + r * n_channel + c]); + } + y_data[n * (n_channel * output_len) + i * n_channel + c] = this_max; } - y_data[n * (n_channel * output_len) + i * n_channel + c] = this_max; } } + return y; } - return y; -} -/* - input shape: m, n - return shape: n, m - */ -static MTensor transpose2D(const MTensor& x) { - int m = x.size(0); - int n = x.size(1); - MTensor y({n, m}); - float *y_data = y.mutable_data(); - const float *x_data = x.data(); - for (int i = 0; i < m; i++){ - for (int j = 0; j < n; j++) { - y_data[j * m + i] = x_data[i * n + j]; + /* + input shape: m, n + return shape: n, m + */ + static MTensor transpose2D(const MTensor &x) + { + int m = x.size(0); + int n = x.size(1); + MTensor y({n, m}); + float *y_data = y.mutable_data(); + const float *x_data = x.data(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + y_data[j * m + i] = x_data[i * n + j]; + } } + return y; } - return y; -} -/* - input shape: m, n, p - return shape: p, n, m - */ -static MTensor transpose3D(const MTensor& x) { - int m = x.size(0); - int n = x.size(1); - int p = x.size(2); - MTensor y({p, n, m}); - float *y_data = y.mutable_data(); - const float *x_data = x.data(); - for (int i = 0; i < m; i++){ - for (int j = 0; j < n; j++) { - for (int k = 0; k < p; k++) { - y_data[k * m * n + j * m + i] = x_data[i * n * p + j * p + k]; + /* + input shape: m, n, p + return shape: p, n, m + */ + static MTensor transpose3D(const MTensor &x) + { + int m = x.size(0); + int n = x.size(1); + int p = x.size(2); + MTensor y({p, n, m}); + float *y_data = y.mutable_data(); + const float *x_data = x.data(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + for (int k = 0; k < p; k++) { + y_data[k * m * n + j * m + i] = x_data[i * n * p + j * p + k]; + } } } + return y; } - return y; -} -static void addmv(MTensor& y, const MTensor& x) { - int m = y.size(0); - int n = y.size(1); - int p = y.size(2); - float *y_data = y.mutable_data(); - const float *x_data = x.data(); - for (int i = 0; i < p; i++) { - vDSP_vsadd(y_data + i, p, x_data + i, y_data + i, p, m * n); + static void addmv(MTensor &y, const MTensor &x) + { + int m = y.size(0); + int n = y.size(1); + int p = y.size(2); + float *y_data = y.mutable_data(); + const float *x_data = x.data(); + for (int i = 0; i < p; i++) { + vDSP_vsadd(y_data + i, p, x_data + i, y_data + i, p, m * n); + } } -} -static MTensor getDenseTensor(const float *df) { - MTensor dense_tensor({1, DENSE_FEATURE_LEN}); - if (df) { - memcpy(dense_tensor.mutable_data(), df, DENSE_FEATURE_LEN * sizeof(float)); - } else { - memset(dense_tensor.mutable_data(), 0, DENSE_FEATURE_LEN * sizeof(float)); + static MTensor getDenseTensor(const float *df) + { + MTensor dense_tensor({1, DENSE_FEATURE_LEN}); + if (df) { + memcpy(dense_tensor.mutable_data(), df, DENSE_FEATURE_LEN * sizeof(float)); + } else { + memset(dense_tensor.mutable_data(), 0, DENSE_FEATURE_LEN * sizeof(float)); + } + return dense_tensor; } - return dense_tensor; -} -static MTensor predictOnMTML(const std::string task, const char *texts, const std::unordered_map& weights, const float *df) { - MTensor dense_tensor = getDenseTensor(df); - std::string final_layer_weight_key = task + ".weight"; - std::string final_layer_bias_key = task + ".bias"; + static MTensor predictOnMTML(const std::string task, const char *texts, const std::unordered_map &weights, const float *df) + { + MTensor dense_tensor = getDenseTensor(df); + std::string final_layer_weight_key = task + ".weight"; + std::string final_layer_bias_key = task + ".bias"; - const MTensor& embed_t = weights.at("embed.weight"); - const MTensor& conv0w_t = weights.at("convs.0.weight"); - const MTensor& conv1w_t = weights.at("convs.1.weight"); - const MTensor& conv2w_t = weights.at("convs.2.weight"); - const MTensor& conv0b_t = weights.at("convs.0.bias"); - const MTensor& conv1b_t = weights.at("convs.1.bias"); - const MTensor& conv2b_t = weights.at("convs.2.bias"); - const MTensor& fc1w_t = weights.at("fc1.weight"); // (128, 190) - const MTensor& fc1b_t = weights.at("fc1.bias"); // 128 - const MTensor& fc2w_t = weights.at("fc2.weight"); // (64, 128) - const MTensor& fc2b_t = weights.at("fc2.bias"); // 64 - const MTensor& final_layer_weight_t = weights.at(final_layer_weight_key); // (2, 64) or (5, 64) - const MTensor& final_layer_bias_t = weights.at(final_layer_bias_key); // 2 or 5 + const MTensor &embed_t = weights.at("embed.weight"); + const MTensor &conv0w_t = weights.at("convs.0.weight"); + const MTensor &conv1w_t = weights.at("convs.1.weight"); + const MTensor &conv2w_t = weights.at("convs.2.weight"); + const MTensor &conv0b_t = weights.at("convs.0.bias"); + const MTensor &conv1b_t = weights.at("convs.1.bias"); + const MTensor &conv2b_t = weights.at("convs.2.bias"); + const MTensor &fc1w_t = weights.at("fc1.weight"); // (128, 190) + const MTensor &fc1b_t = weights.at("fc1.bias"); // 128 + const MTensor &fc2w_t = weights.at("fc2.weight"); // (64, 128) + const MTensor &fc2b_t = weights.at("fc2.bias"); // 64 + const MTensor &final_layer_weight_t = weights.at(final_layer_weight_key); // (2, 64) or (5, 64) + const MTensor &final_layer_bias_t = weights.at(final_layer_bias_key); // 2 or 5 - const MTensor& convs_0_weight = transpose3D(conv0w_t); - const MTensor& convs_1_weight = transpose3D(conv1w_t); - const MTensor& convs_2_weight = transpose3D(conv2w_t); - const MTensor& fc1_weight = transpose2D(fc1w_t); - const MTensor& fc2_weight = transpose2D(fc2w_t); - const MTensor& final_layer_weight = transpose2D(final_layer_weight_t); + const MTensor &convs_0_weight = transpose3D(conv0w_t); + const MTensor &convs_1_weight = transpose3D(conv1w_t); + const MTensor &convs_2_weight = transpose3D(conv2w_t); + const MTensor &fc1_weight = transpose2D(fc1w_t); + const MTensor &fc2_weight = transpose2D(fc2w_t); + const MTensor &final_layer_weight = transpose2D(final_layer_weight_t); - // embedding - const MTensor& embed_x = embedding(texts, SEQ_LEN, embed_t); + // embedding + const MTensor &embed_x = embedding(texts, SEQ_LEN, embed_t); - // conv0 - MTensor c0 = conv1D(embed_x, convs_0_weight); // (1, 126, 32) - addmv(c0, conv0b_t); - relu(c0); + // conv0 + MTensor c0 = conv1D(embed_x, convs_0_weight); // (1, 126, 32) + addmv(c0, conv0b_t); + relu(c0); - // conv1 - MTensor c1 = conv1D(c0, convs_1_weight); // (1, 124, 64) - addmv(c1, conv1b_t); - relu(c1); - c1 = maxPool1D(c1, 2); // (1, 123, 64) + // conv1 + MTensor c1 = conv1D(c0, convs_1_weight); // (1, 124, 64) + addmv(c1, conv1b_t); + relu(c1); + c1 = maxPool1D(c1, 2); // (1, 123, 64) - // conv2 - MTensor c2 = conv1D(c1, convs_2_weight); // (1, 121, 64) - addmv(c2, conv2b_t); - relu(c2); + // conv2 + MTensor c2 = conv1D(c1, convs_2_weight); // (1, 121, 64) + addmv(c2, conv2b_t); + relu(c2); - // max pooling - MTensor ca = maxPool1D(c0, c0.size(1)); - MTensor cb = maxPool1D(c1, c1.size(1)); - MTensor cc = maxPool1D(c2, c2.size(1)); + // max pooling + MTensor ca = maxPool1D(c0, c0.size(1)); + MTensor cb = maxPool1D(c1, c1.size(1)); + MTensor cc = maxPool1D(c2, c2.size(1)); - // concatenate - flatten(ca, 1); - flatten(cb, 1); - flatten(cc, 1); - std::vector concat_tensors { &ca, &cb, &cc, &dense_tensor }; - const MTensor& concat = concatenate(concat_tensors); + // concatenate + flatten(ca, 1); + flatten(cb, 1); + flatten(cc, 1); + std::vector concat_tensors { &ca, &cb, &cc, &dense_tensor }; + const MTensor &concat = concatenate(concat_tensors); - // dense + relu - MTensor dense1_x = dense(concat, fc1_weight, fc1b_t); - relu(dense1_x); - MTensor dense2_x = dense(dense1_x, fc2_weight, fc2b_t); - relu(dense2_x); - MTensor final_layer_dense_x = dense(dense2_x, final_layer_weight, final_layer_bias_t); - softmax(final_layer_dense_x); - return final_layer_dense_x; -} + // dense + relu + MTensor dense1_x = dense(concat, fc1_weight, fc1b_t); + relu(dense1_x); + MTensor dense2_x = dense(dense1_x, fc2_weight, fc2b_t); + relu(dense2_x); + MTensor final_layer_dense_x = dense(dense2_x, final_layer_weight, final_layer_bias_t); + softmax(final_layer_dense_x); + return final_layer_dense_x; + } } #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.h index 3012e8e3c5..d43fcef671 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import @interface FBSDKModelUtility : NSObject diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.m index 9c1bff6761..53e4666d98 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKModelUtility.m @@ -20,9 +20,9 @@ #if !TARGET_OS_TV -#import + #import "FBSDKModelUtility.h" -#import "FBSDKModelUtility.h" + #import @implementation FBSDKModelUtility : NSObject @@ -30,7 +30,7 @@ + (NSString *)normalizeText:(NSString *)text { NSMutableArray *tokens = [[text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] mutableCopy]; [tokens removeObject:@""]; - return [tokens componentsJoinedByString: @" "]; + return [tokens componentsJoinedByString:@" "]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKTensor.hpp b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKTensor.hpp index d6bc8eb7bb..54f3a75a9f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKTensor.hpp +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ML/FBSDKTensor.hpp @@ -20,102 +20,115 @@ #if !TARGET_OS_TV -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#import + #include + #include + #include + #include + #include + #include + #include -// minimal aten implementation -#define MAT_ALWAYS_INLINE inline __attribute__((always_inline)) -namespace fbsdk { + #include + #include -static void* MAllocateMemory(size_t nbytes) { - void* ptr = nullptr; - assert(nbytes > 0); -#ifdef __ANDROID__ - ptr = memalign(64, nbytes); -#else - const int ret = posix_memalign(&ptr, 64, nbytes); - (void)ret; - assert(ret == 0); -#endif - return ptr; -} + #import -static void MFreeMemory(void* ptr) { - if (ptr) { - free(ptr); +// minimal aten implementation + #define MAT_ALWAYS_INLINE inline __attribute__((always_inline)) +namespace fbsdk { + static void *MAllocateMemory(size_t nbytes) + { + void *ptr = nullptr; + assert(nbytes > 0); + #ifdef __ANDROID__ + ptr = memalign(64, nbytes); + #else + const int ret = posix_memalign(&ptr, 64, nbytes); + (void)ret; + assert(ret == 0); + #endif + return ptr; } -} -class MTensor { -public: - MTensor(): storage_(nullptr), sizes_(), strides_(), capacity_(0){}; - explicit MTensor(const std::vector& sizes) { - std::vector strides = std::vector(sizes.size()); - strides[strides.size() - 1] = 1; - for (int i = static_cast(strides.size()) - 2; i >= 0; --i) { - strides[i] = strides[i + 1] * sizes[i + 1]; - } - strides_ = strides; - sizes_ = sizes; - capacity_ = 1; - for (int size : sizes) { - capacity_ *= size; + static void MFreeMemory(void *ptr) + { + if (ptr) { + free(ptr); } - storage_ = std::shared_ptr(MAllocateMemory((size_t)capacity_ * sizeof(float)), MFreeMemory); - } - - MAT_ALWAYS_INLINE int count() const { - return capacity_; } - MAT_ALWAYS_INLINE int size(int dim) const { - return sizes_[dim]; - } + class MTensor { + public: + MTensor() : + storage_(nullptr), + sizes_(), + strides_(), + capacity_(0) {}; + explicit MTensor(const std::vector &sizes) + { + std::vector strides = std::vector(sizes.size()); + strides[strides.size() - 1] = 1; + for (int i = static_cast(strides.size()) - 2; i >= 0; --i) { + strides[i] = strides[i + 1] * sizes[i + 1]; + } + strides_ = strides; + sizes_ = sizes; + capacity_ = 1; + for (int size : sizes) { + capacity_ *= size; + } + storage_ = std::shared_ptr(MAllocateMemory((size_t)capacity_ * sizeof(float)), MFreeMemory); + } - MAT_ALWAYS_INLINE const std::vector& sizes() const { - return sizes_; - } + MAT_ALWAYS_INLINE int count() const + { + return capacity_; + } - MAT_ALWAYS_INLINE const std::vector& strides() const { - return strides_; - } + MAT_ALWAYS_INLINE int size(int dim) const + { + return sizes_[dim]; + } - MAT_ALWAYS_INLINE const float* data() const { - return (const float*)(storage_.get()); - } + MAT_ALWAYS_INLINE const std::vector &sizes() const + { + return sizes_; + } - MAT_ALWAYS_INLINE float* mutable_data() { - return static_cast(storage_.get()); - } + MAT_ALWAYS_INLINE const std::vector &strides() const + { + return strides_; + } - MAT_ALWAYS_INLINE void Reshape(const std::vector& sizes) { - int count = 1; - for (int i = 0; i < sizes.size(); i++) { - count *= sizes[i]; + MAT_ALWAYS_INLINE const float *data() const + { + return (const float *)(storage_.get()); } - if (count > capacity_) { - capacity_ = count; - storage_.reset(MAllocateMemory((size_t)capacity_ * sizeof(float)), MFreeMemory); + + MAT_ALWAYS_INLINE float *mutable_data() + { + return static_cast(storage_.get()); } - sizes_ = sizes; - } -private: - int capacity_; - std::vector sizes_; - std::vector strides_; - std::shared_ptr storage_; -}; + MAT_ALWAYS_INLINE void Reshape(const std::vector &sizes) + { + int count = 1; + for (int i = 0; i < sizes.size(); i++) { + count *= sizes[i]; + } + if (count > capacity_) { + capacity_ = count; + storage_.reset(MAllocateMemory((size_t)capacity_ * sizeof(float)), MFreeMemory); + } + sizes_ = sizes; + } + private: + int capacity_; + std::vector sizes_; + std::vector strides_; + std::shared_ptr storage_; + }; } #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.h new file mode 100644 index 0000000000..3d2ea94eb7 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.h @@ -0,0 +1,51 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import + + #import "FBSDKSKAdNetworkRule.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKSKAdNetworkConversionConfiguration : NSObject + +@property (nonatomic, readonly, assign) NSInteger timerBuckets; + +@property (nonatomic, readonly, assign) NSTimeInterval timerInterval; + +@property (nonatomic, readonly, assign) NSInteger cutoffTime; + +@property (nonatomic, readonly, copy) NSString *defaultCurrency; + +@property (nonatomic, readonly, copy) NSArray *conversionValueRules; + +@property (nonatomic, readonly, copy) NSSet *eventSet; + +@property (nonatomic, readonly, copy) NSSet *currencySet; + +- (nullable instancetype)initWithJSON:(nullable NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.m new file mode 100644 index 0000000000..5f24ae05e5 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkConversionConfiguration.m @@ -0,0 +1,116 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKSKAdNetworkConversionConfiguration.h" + + #import "FBSDKCoreKit+Internal.h" + +@implementation FBSDKSKAdNetworkConversionConfiguration + +- (nullable instancetype)initWithJSON:(nullable NSDictionary *)dict +{ + if ((self = [super init])) { + @try { + dict = [FBSDKTypeUtility dictionaryValue:dict]; + if (!dict) { + return nil; + } + NSArray *data = [FBSDKTypeUtility dictionary:dict objectForKey:@"data" ofType:NSArray.class]; + NSDictionary *conversionRules = [FBSDKTypeUtility dictionaryValue:[FBSDKTypeUtility array:data objectAtIndex:0]]; + if (!conversionRules) { + return nil; + } + _timerBuckets = [FBSDKTypeUtility integerValue:conversionRules[@"timer_buckets"]]; + _timerInterval = (NSTimeInterval)[FBSDKTypeUtility integerValue:conversionRules[@"timer_interval"]]; + _cutoffTime = [FBSDKTypeUtility integerValue:conversionRules[@"cutoff_time"]]; + _defaultCurrency = [[FBSDKTypeUtility stringValue:conversionRules[@"default_currency"]] uppercaseString]; + _conversionValueRules = [FBSDKSKAdNetworkConversionConfiguration parseRules:conversionRules[@"conversion_value_rules"]]; + if (!_conversionValueRules || !_defaultCurrency) { + return nil; + } + _eventSet = [FBSDKSKAdNetworkConversionConfiguration getEventSetFromRules:_conversionValueRules]; + _currencySet = [FBSDKSKAdNetworkConversionConfiguration getCurrencySetFromRules:_conversionValueRules]; + } @catch (NSException *exception) { + return nil; + } + } + return self; +} + ++ (NSSet *)getEventSetFromRules:(NSArray *)rules +{ + NSMutableSet *eventSet = [NSMutableSet new]; + for (FBSDKSKAdNetworkRule *rule in rules) { + if (!rule) { + continue; + } + for (FBSDKSKAdNetworkEvent *event in rule.events) { + if (event.eventName) { + [eventSet addObject:event.eventName]; + } + } + } + return [eventSet copy]; +} + ++ (NSSet *)getCurrencySetFromRules:(NSArray *)rules +{ + NSMutableSet *currencySet = [NSMutableSet new]; + for (FBSDKSKAdNetworkRule *rule in rules) { + if (!rule) { + continue; + } + for (FBSDKSKAdNetworkEvent *event in rule.events) { + for (NSString *currency in event.values) { + [currencySet addObject:[currency uppercaseString]]; + } + } + } + return [currencySet copy]; +} + ++ (nullable NSArray *)parseRules:(nullable NSArray *)rules +{ + rules = [FBSDKTypeUtility arrayValue:rules]; + if (!rules) { + return nil; + } + NSMutableArray *parsedRules = [NSMutableArray new]; + for (id ruleEntry in rules) { + FBSDKSKAdNetworkRule *rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:ruleEntry]; + [FBSDKTypeUtility array:parsedRules addObject:rule]; + } + [parsedRules sortUsingComparator:^NSComparisonResult (FBSDKSKAdNetworkRule *obj1, FBSDKSKAdNetworkRule *obj2) { + if (obj1.conversionValue < obj2.conversionValue) { + return NSOrderedDescending; + } + if (obj1.conversionValue < obj2.conversionValue) { + return NSOrderedAscending; + } + return NSOrderedSame; + }]; + return [parsedRules copy]; +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.h new file mode 100644 index 0000000000..85e8be0b0e --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.h @@ -0,0 +1,39 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKSKAdNetworkEvent : NSObject + +@property (nonatomic, readonly, copy) NSString *eventName; + +@property (nullable, nonatomic, readonly, copy) NSDictionary *values; + +- (nullable instancetype)initWithJSON:(NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.m new file mode 100644 index 0000000000..28830075e8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkEvent.m @@ -0,0 +1,64 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKSKAdNetworkEvent.h" + + #import + + #import "FBSDKCoreKit+Internal.h" + +@implementation FBSDKSKAdNetworkEvent + +- (nullable instancetype)initWithJSON:(NSDictionary *)dict +{ + if ((self = [super init])) { + dict = [FBSDKTypeUtility dictionaryValue:dict]; + if (!dict) { + return nil; + } + _eventName = [FBSDKTypeUtility dictionary:dict objectForKey:@"event_name" ofType:NSString.class]; + // Event name is a required field + if (!_eventName) { + return nil; + } + // Values is an optional field + NSArray *> *valueEntries = [FBSDKTypeUtility dictionary:dict objectForKey:@"values" ofType:NSArray.class]; + if (valueEntries) { + NSMutableDictionary *valueDict = [NSMutableDictionary new]; + for (NSDictionary *valueEntry in valueEntries) { + NSDictionary *value = [FBSDKTypeUtility dictionaryValue:valueEntry]; + NSString *currency = [FBSDKTypeUtility dictionary:value objectForKey:@"currency" ofType:NSString.class]; + NSNumber *amount = [FBSDKTypeUtility dictionary:value objectForKey:@"amount" ofType:NSNumber.class]; + if (!currency || amount == nil) { + return nil; + } + [FBSDKTypeUtility dictionary:valueDict setObject:amount forKey:[currency uppercaseString]]; + } + _values = [valueDict copy]; + } + } + return self; +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.h new file mode 100644 index 0000000000..a33acdb1b6 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.h @@ -0,0 +1,41 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKSKAdNetworkReporter : NSObject + ++ (void)enable; + ++ (void)checkAndRevokeTimer; + ++ (void)recordAndUpdateEvent:(NSString *)event + currency:(nullable NSString *)currency + value:(nullable NSNumber *)value; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.m new file mode 100644 index 0000000000..b2d339cd17 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.m @@ -0,0 +1,299 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKSKAdNetworkReporter.h" + + #import + + #import + + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKSKAdNetworkConversionConfiguration.h" + + #define FBSDK_SKADNETWORK_CONFIG_TIME_OUT 86400 + +typedef void (*send_type)(Class, SEL, NSInteger); + +typedef void (^FBSDKSKAdNetworkReporterBlock)(void); + +static NSString *const FBSDKSKAdNetworkConversionConfigurationKey = @"com.facebook.sdk:FBSDKSKAdNetworkConversionConfiguration"; +static NSString *const FBSDKSKAdNetworkReporterKey = @"com.facebook.sdk:FBSDKSKAdNetworkReporter"; + +static BOOL g_isSKAdNetworkReportEnabled = NO; +static NSMutableArray *g_completionBlocks; +static BOOL g_isRequestStarted = NO; +static dispatch_queue_t serialQueue; +static FBSDKSKAdNetworkConversionConfiguration *config; +static NSDate *g_configRefreshTimestamp; +static NSInteger g_conversionValue = 0; +static NSDate *g_timestamp = nil; +static NSMutableSet *g_recordedEvents; +static NSMutableDictionary *g_recordedValues; + +@implementation FBSDKSKAdNetworkReporter + ++ (void)enable +{ + if (@available(iOS 14.0, *)) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [SKAdNetwork registerAppForAdNetworkAttribution]; + [self _loadReportData]; + g_completionBlocks = [NSMutableArray new]; + serialQueue = dispatch_queue_create("com.facebook.appevents.SKAdNetwork.FBSDKSKAdNetworkReporter", DISPATCH_QUEUE_SERIAL); + [self _loadConfigurationWithBlock:^{ + [self _checkAndUpdateConversionValue]; + [self _checkAndRevokeTimer]; + }]; + g_isSKAdNetworkReportEnabled = YES; + }); + } +} + ++ (void)checkAndRevokeTimer +{ + if (@available(iOS 14.0, *)) { + if (!g_isSKAdNetworkReportEnabled) { + return; + } + [self _loadConfigurationWithBlock:^() { + [self _checkAndRevokeTimer]; + }]; + } +} + ++ (void)recordAndUpdateEvent:(NSString *)event + currency:(nullable NSString *)currency + value:(nullable NSNumber *)value +{ + if (@available(iOS 14.0, *)) { + if (!g_isSKAdNetworkReportEnabled) { + return; + } + if (!event.length) { + return; + } + [self _loadConfigurationWithBlock:^() { + [self _recordAndUpdateEvent:event currency:currency value:value]; + }]; + } +} + ++ (void)_loadConfigurationWithBlock:(FBSDKSKAdNetworkReporterBlock)block +{ + if (!serialQueue) { + return; + } + // Executes block if there is cache + if ([self _isConfigRefreshTimestampValid] && [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSKAdNetworkConversionConfigurationKey]) { + dispatch_async(serialQueue, ^() { + [FBSDKTypeUtility array:g_completionBlocks addObject:block]; + for (FBSDKSKAdNetworkReporterBlock executionBlock in g_completionBlocks) { + executionBlock(); + } + [g_completionBlocks removeAllObjects]; + }); + return; + } + dispatch_async(serialQueue, ^{ + [FBSDKTypeUtility array:g_completionBlocks addObject:block]; + if (g_isRequestStarted) { + return; + } + g_isRequestStarted = YES; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] + initWithGraphPath:[NSString stringWithFormat:@"%@/ios_skadnetwork_conversion_config", [FBSDKSettings appID]]]; + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + dispatch_async(serialQueue, ^{ + if (error) { + g_isRequestStarted = NO; + return; + } + NSDictionary *json = [FBSDKTypeUtility dictionaryValue:result]; + if (json) { + [[NSUserDefaults standardUserDefaults] setObject:json forKey:FBSDKSKAdNetworkConversionConfigurationKey]; + g_configRefreshTimestamp = [NSDate date]; + config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:json]; + for (FBSDKSKAdNetworkReporterBlock executionBlock in g_completionBlocks) { + executionBlock(); + } + [g_completionBlocks removeAllObjects]; + g_isRequestStarted = NO; + } + }); + }]; + }); +} + ++ (void)_checkAndRevokeTimer +{ + if (!config) { + return; + } + if ([self _shouldCutoff]) { + return; + } + if (g_conversionValue > config.timerBuckets) { + return; + } + if (g_timestamp && [[NSDate date] timeIntervalSinceDate:g_timestamp] < config.timerInterval) { + return; + } + [FBSDKSKAdNetworkReporter _updateConversionValue:g_conversionValue]; +} + ++ (void)_recordAndUpdateEvent:(NSString *)event + currency:(nullable NSString *)currency + value:(nullable NSNumber *)value +{ + if (!config) { + return; + } + if ([self _shouldCutoff]) { + return; + } + if (![config.eventSet containsObject:event] && ![FBSDKAppEventsUtility isStandardEvent:event]) { + return; + } + BOOL isCacheUpdated = false; + if (![g_recordedEvents containsObject:event]) { + [g_recordedEvents addObject:event]; + isCacheUpdated = true; + } + // Change currency to default currency if currency is not found in currencySet + NSString *valueCurrency = [currency uppercaseString]; + if (![config.currencySet containsObject:valueCurrency]) { + valueCurrency = config.defaultCurrency; + } + if (value != nil) { + NSMutableDictionary *mapping = [[FBSDKTypeUtility dictionary:g_recordedValues objectForKey:event ofType:NSDictionary.class] mutableCopy] ?: [NSMutableDictionary new]; + NSNumber *valueInMapping = [FBSDKTypeUtility dictionary:mapping objectForKey:valueCurrency ofType:NSNumber.class] ?: [NSNumber numberWithDouble:0]; + [FBSDKTypeUtility dictionary:mapping setObject:[NSNumber numberWithDouble:(valueInMapping.doubleValue + value.doubleValue)] forKey:valueCurrency]; + [FBSDKTypeUtility dictionary:g_recordedValues setObject:mapping forKey:event]; + isCacheUpdated = true; + } + if (isCacheUpdated) { + [self _checkAndUpdateConversionValue]; + [self _saveReportData]; + } +} + ++ (void)_checkAndUpdateConversionValue +{ + // Update conversion value if a rule is matched + for (FBSDKSKAdNetworkRule *rule in config.conversionValueRules) { + if (rule.conversionValue < g_conversionValue) { + break; + } + if ([rule isMatchedWithRecordedEvents:g_recordedEvents recordedValues:g_recordedValues]) { + [self _updateConversionValue:rule.conversionValue]; + break; + } + } +} + ++ (void)_updateConversionValue:(NSInteger)value +{ + if (@available(iOS 14.0, *)) { + if ([self _shouldCutoff]) { + return; + } + SEL selector = NSSelectorFromString(@"updateConversionValue:"); + if (![[SKAdNetwork class] respondsToSelector:selector]) { + return; + } + send_type msgSend = (send_type)objc_msgSend; + msgSend([SKAdNetwork class], selector, value); + g_conversionValue = value + 1; + g_timestamp = [NSDate date]; + [self _saveReportData]; + } +} + ++ (BOOL)_shouldCutoff +{ + if (!config.cutoffTime) { + return true; + } + NSDate *installTimestamp = [[NSUserDefaults standardUserDefaults] objectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + return [installTimestamp isKindOfClass:NSDate.class] && [[NSDate date] timeIntervalSinceDate:installTimestamp] > config.cutoffTime * 86400; +} + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" ++ (void)_loadReportData +{ + id cachedJSON = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSKAdNetworkConversionConfigurationKey]; + config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:cachedJSON]; + NSData *cachedReportData = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSKAdNetworkReporterKey]; + g_recordedEvents = [NSMutableSet new]; + g_recordedValues = [NSMutableDictionary new]; + if ([cachedReportData isKindOfClass:[NSData class]]) { + NSDictionary *data = [FBSDKTypeUtility dictionaryValue:[NSKeyedUnarchiver unarchiveObjectWithData:cachedReportData]]; + if (data) { + g_conversionValue = [FBSDKTypeUtility integerValue:data[@"conversion_value"]]; + g_timestamp = [FBSDKTypeUtility dictionary:data objectForKey:@"timestamp" ofType:NSDate.class]; + g_recordedEvents = [[FBSDKTypeUtility dictionary:data objectForKey:@"recorded_events" ofType:NSSet.class] mutableCopy] ?: [NSMutableSet new]; + g_recordedValues = [[FBSDKTypeUtility dictionary:data objectForKey:@"recorded_values" ofType:NSDictionary.class] mutableCopy] ?: [NSMutableDictionary new]; + } + } +} + ++ (void)_saveReportData +{ + NSMutableDictionary *reportData = [NSMutableDictionary new]; + [FBSDKTypeUtility dictionary:reportData setObject:@(g_conversionValue) forKey:@"conversion_value"]; + [FBSDKTypeUtility dictionary:reportData setObject:g_timestamp forKey:@"timestamp"]; + [FBSDKTypeUtility dictionary:reportData setObject:g_recordedEvents forKey:@"recorded_events"]; + [FBSDKTypeUtility dictionary:reportData setObject:g_recordedValues forKey:@"recorded_values"]; + NSData *cache = [NSKeyedArchiver archivedDataWithRootObject:reportData]; + if (cache) { + [[NSUserDefaults standardUserDefaults] setObject:cache forKey:FBSDKSKAdNetworkReporterKey]; + } +} + + #pragma clang diagnostic pop + ++ (BOOL)_isConfigRefreshTimestampValid +{ + return g_configRefreshTimestamp && [[NSDate date] timeIntervalSinceDate:g_configRefreshTimestamp] < FBSDK_SKADNETWORK_CONFIG_TIME_OUT; +} + + #pragma mark - Testability + + #if DEBUG + ++ (void)setConfiguration:(FBSDKSKAdNetworkConversionConfiguration *)configuration +{ + config = configuration; +} + ++ (void)setSKAdNetworkReportEnabled:(BOOL)enabled +{ + g_isSKAdNetworkReportEnabled = enabled; +} + + #endif + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.h new file mode 100644 index 0000000000..8f8afe742c --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.h @@ -0,0 +1,44 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import + + #import "FBSDKSKAdNetworkEvent.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKSKAdNetworkRule : NSObject + +@property (nonatomic) NSInteger conversionValue; + +@property (nonatomic, copy) NSArray *events; + +- (nullable instancetype)initWithJSON:(NSDictionary *)dict; + +- (BOOL)isMatchedWithRecordedEvents:(NSSet *)recordedEvents + recordedValues:(NSDictionary *)recordedValues; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.m new file mode 100644 index 0000000000..cf4b7dcc19 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkRule.m @@ -0,0 +1,92 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKSKAdNetworkRule.h" + + #import "FBSDKCoreKit+Internal.h" + +@implementation FBSDKSKAdNetworkRule + +- (nullable instancetype)initWithJSON:(NSDictionary *)dict +{ + if ((self = [super init])) { + dict = [FBSDKTypeUtility dictionaryValue:dict]; + if (!dict) { + return nil; + } + NSNumber *value = [FBSDKTypeUtility dictionary:dict objectForKey:@"conversion_value" ofType:NSNumber.class]; + NSArray *events = [FBSDKSKAdNetworkRule parseEvents:[FBSDKTypeUtility dictionary:dict objectForKey:@"events" ofType:NSArray.class]]; + if (value == nil || !events) { + return nil; + } + _conversionValue = value.integerValue; + _events = events; + } + return self; +} + +- (BOOL)isMatchedWithRecordedEvents:(NSSet *)recordedEvents + recordedValues:(NSDictionary *)recordedValues +{ + for (FBSDKSKAdNetworkEvent *event in self.events) { + // Check if event name matches + if (![recordedEvents containsObject:event.eventName]) { + return NO; + } + // Check if event value matches when values is not nil + if (event.values) { + NSDictionary *recordedEventValues = [FBSDKTypeUtility dictionary:recordedValues objectForKey:event.eventName ofType:NSDictionary.class]; + if (!recordedEventValues) { + return NO; + } + for (NSString *currency in event.values) { + NSNumber *valueInMapping = [FBSDKTypeUtility dictionary:event.values objectForKey:currency ofType:NSNumber.class]; + NSNumber *value = [FBSDKTypeUtility dictionary:recordedEventValues objectForKey:currency ofType:NSNumber.class]; + if (value != nil && valueInMapping != nil && value.doubleValue > valueInMapping.doubleValue) { + return YES; + } + } + return NO; + } + } + return YES; +} + ++ (NSArray *)parseEvents:(nullable NSArray *> *)events +{ + if (!events) { + return nil; + } + NSMutableArray *parsedEvents = [NSMutableArray new]; + for (NSDictionary *eventEntry in events) { + FBSDKSKAdNetworkEvent *event = [[FBSDKSKAdNetworkEvent alloc] initWithJSON:eventEntry]; + if (!event) { + return nil; + } + [FBSDKTypeUtility array:parsedEvents addObject:event]; + } + return [parsedEvents copy]; +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.h index 1feade49f4..a40114a801 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.m index f6d65f81de..3354668ccd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKFeatureExtractor.m @@ -20,19 +20,20 @@ #if !TARGET_OS_TV -#import "FBSDKFeatureExtractor.h" + #import "FBSDKFeatureExtractor.h" -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKModelManager.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKModelManager.h" -#define REGEX_CR_PASSWORD_FIELD @"password" -#define REGEX_CR_HAS_CONFIRM_PASSWORD_FIELD @"(?i)(confirm.*password)|(password.*(confirmation|confirm)|confirmation)" -#define REGEX_CR_HAS_LOG_IN_KEYWORDS @"(?i)(sign in)|login|signIn" -#define REGEX_CR_HAS_SIGN_ON_KEYWORDS @"(?i)(sign.*(up|now)|registration|" \ -@"register|(create|apply).*(profile|account)|open.*account|" \ -@"account.*(open|creation|application)|enroll|join.*now)" -#define REGEX_ADD_TO_CART_BUTTON_TEXT @"(?i)add to(\\s|\\Z)|update(\\s|\\Z)|cart" -#define REGEX_ADD_TO_CART_PAGE_TITLE @"(?i)add to(\\s|\\Z)|update(\\s|\\Z)|cart|shop|buy" + #define REGEX_CR_PASSWORD_FIELD @"password" + #define REGEX_CR_HAS_CONFIRM_PASSWORD_FIELD @"(?i)(confirm.*password)|(password.*(confirmation|confirm)|confirmation)" + #define REGEX_CR_HAS_LOG_IN_KEYWORDS @"(?i)(sign in)|login|signIn" + #define REGEX_CR_HAS_SIGN_ON_KEYWORDS \ + @"(?i)(sign.*(up|now)|registration|" \ + @"register|(create|apply).*(profile|account)|open.*account|" \ + @"account.*(open|creation|application)|enroll|join.*now)" + #define REGEX_ADD_TO_CART_BUTTON_TEXT @"(?i)add to(\\s|\\Z)|update(\\s|\\Z)|cart" + #define REGEX_ADD_TO_CART_PAGE_TITLE @"(?i)add to(\\s|\\Z)|update(\\s|\\Z)|cart|shop|buy" static NSDictionary *_languageInfo; static NSDictionary *_eventInfo; @@ -46,28 +47,28 @@ @implementation FBSDKFeatureExtractor + (void)initialize { _languageInfo = @{ - @"ENGLISH" : @"1", - @"GERMAN" : @"2", - @"SPANISH" : @"3", - @"JAPANESE" : @"4" - }; + @"ENGLISH" : @"1", + @"GERMAN" : @"2", + @"SPANISH" : @"3", + @"JAPANESE" : @"4" + }; _eventInfo = @{ - @"VIEW_CONTENT" : @"0", - @"SEARCH" : @"1", - @"ADD_TO_CART" : @"2", - @"ADD_TO_WISHLIST" : @"3", - @"INITIATE_CHECKOUT" : @"4", - @"ADD_PAYMENT_INFO" : @"5", - @"PURCHASE" : @"6", - @"LEAD" : @"7", - @"COMPLETE_REGISTRATION" : @"8" - }; + @"VIEW_CONTENT" : @"0", + @"SEARCH" : @"1", + @"ADD_TO_CART" : @"2", + @"ADD_TO_WISHLIST" : @"3", + @"INITIATE_CHECKOUT" : @"4", + @"ADD_PAYMENT_INFO" : @"5", + @"PURCHASE" : @"6", + @"LEAD" : @"7", + @"COMPLETE_REGISTRATION" : @"8" + }; _textTypeInfo = @{ - @"BUTTON_TEXT": @"1", - @"PAGE_TITLE": @"2", - @"RESOLVED_DOCUMENT_LINK": @"3", - @"BUTTON_ID": @"4" - }; + @"BUTTON_TEXT" : @"1", + @"PAGE_TITLE" : @"2", + @"RESOLVED_DOCUMENT_LINK" : @"3", + @"BUTTON_ID" : @"4" + }; } + (void)loadRulesForKey:(NSString *)useCaseKey @@ -96,7 +97,7 @@ + (nullable float *)getDenseFeatures:(NSDictionary *)viewHierarchy [self pruneTree:[[FBSDKTypeUtility array:viewTree objectAtIndex:0] mutableCopy] siblings:siblings]; - float *result = [self parseFeatures:[FBSDKTypeUtility array:viewTree objectAtIndex:0]]; + float *result = [self parseFeatures:[FBSDKTypeUtility array:viewTree objectAtIndex:0]]; NSMutableDictionary *interactedNode; for (NSMutableDictionary *node in siblings) { @@ -117,7 +118,7 @@ + (nullable float *)getDenseFeatures:(NSDictionary *)viewHierarchy return result; } -#pragma mark - Helper functions + #pragma mark - Helper functions + (BOOL)pruneTree:(NSMutableDictionary *)node siblings:(NSMutableArray *)siblings { // If it's interacted, don't prune away the children and just return. @@ -164,11 +165,11 @@ + (float *)nonparseFeatures:(NSMutableDictionary *)node screenname:(NSString *)screenname viewTreeString:(NSString *)viewTreeString { - float *densefeat = (float *)calloc(30, sizeof(float)); + float *densefeat = (float *)calloc(30, sizeof(float)); densefeat[3] = MAX((float)siblings.count - 1, 0); - densefeat[9] = [siblings filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + densefeat[9] = [siblings filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL (id _Nullable evaluatedObject, NSDictionary *_Nullable bindings) { return [self isButton:evaluatedObject]; }]].count; if ([self isButton:node]) { @@ -219,7 +220,7 @@ + (float *)nonparseFeatures:(NSMutableDictionary *)node + (float *)parseFeatures:(NSMutableDictionary *)node { - float *densefeat = (float *)calloc(30, sizeof(float)); + float *densefeat = (float *)calloc(30, sizeof(float)); NSString *validText = [FBSDKTypeUtility stringValue:node[VIEW_HIERARCHY_TEXT_KEY]]; NSString *validHint = [FBSDKTypeUtility stringValue:node[VIEW_HIERARCHY_HINT_KEY]]; @@ -289,7 +290,8 @@ + (float *)parseFeatures:(NSMutableDictionary *)node return densefeat; } -void sum(float *val0, float *val1) { +void sum(float *val0, float *val1) +{ for (int i = 0; i < 30; i++) { val0[i] += val1[i]; } @@ -308,11 +310,11 @@ + (void)update:(NSDictionary *)node hint:(NSMutableString *)buttonHintString { NSString *text = [[FBSDKTypeUtility dictionary:node - objectForKey:VIEW_HIERARCHY_TEXT_KEY - ofType:NSString.class] lowercaseString]; + objectForKey:VIEW_HIERARCHY_TEXT_KEY + ofType:NSString.class] lowercaseString]; NSString *hint = [[FBSDKTypeUtility dictionary:node - objectForKey:VIEW_HIERARCHY_HINT_KEY - ofType:NSString.class] lowercaseString]; + objectForKey:VIEW_HIERARCHY_HINT_KEY + ofType:NSString.class] lowercaseString]; if (text.length > 0) { [buttonTextString appendFormat:@"%@ ", text]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.h index d8eaed6462..2e6b537808 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m index 5a13728d6e..d4e427aa3b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m @@ -20,22 +20,22 @@ #if !TARGET_OS_TV -#import "FBSDKSuggestedEventsIndexer.h" + #import "FBSDKSuggestedEventsIndexer.h" -#import -#import -#import + #import -#import + #import + #import + #import -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKFeatureExtractor.h" -#import "FBSDKMLMacros.h" -#import "FBSDKModelManager.h" -#import "FBSDKModelUtility.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKFeatureExtractor.h" + #import "FBSDKMLMacros.h" + #import "FBSDKModelManager.h" + #import "FBSDKModelUtility.h" -NSString * const OptInEvents = @"production_events"; -NSString * const UnconfirmedEvents = @"eligible_for_prediction_events"; +NSString *const OptInEvents = @"production_events"; +NSString *const UnconfirmedEvents = @"eligible_for_prediction_events"; static NSMutableSet *_optInEvents; static NSMutableSet *_unconfirmedEvents; @@ -76,15 +76,14 @@ + (void)setup static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - // swizzle UIButton [FBSDKSwizzler swizzleSelector:@selector(didMoveToWindow) onClass:[UIControl class] withBlock:^(UIControl *control) { - if (control.window && [control isKindOfClass:[UIButton class]]) { - [((UIButton *)control) addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown]; - } - } named:@"suggested_events"]; + if (control.window && [control isKindOfClass:[UIButton class]]) { + [((UIButton *)control) addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown]; + } + } named:@"suggested_events"]; - // UITableView + // UITableView void (^tableViewBlock)(UITableView *tableView, SEL cmd, id delegate) = @@ -96,7 +95,7 @@ + (void)setup withBlock:tableViewBlock named:@"suggested_events"]; - // UICollectionView + // UICollectionView void (^collectionViewBlock)(UICollectionView *collectionView, SEL cmd, id delegate) = @@ -114,20 +113,21 @@ + (void)setup }); } -+ (void)rematchBindings { ++ (void)rematchBindings +{ NSArray *windows = [UIApplication sharedApplication].windows; for (UIWindow *window in windows) { [self matchSubviewsIn:window]; } } -+ (void)matchSubviewsIn:(UIView *)view { ++ (void)matchSubviewsIn:(UIView *)view +{ if (!view) { return; } for (UIView *subview in view.subviews) { - if ([subview isKindOfClass:[UITableView class]]) { UITableView *tableView = (UITableView *)subview; [self handleView:tableView withDelegate:tableView.delegate]; @@ -183,7 +183,7 @@ + (void)handleView:(UIView *)view withDelegate:(id)delegate + (void)predictEventWithUIResponder:(UIResponder *)uiResponder text:(NSString *)text { - if (text.length > 100 || text.length == 0 || [FBSDKAppEventsUtility isSensitiveUserData: text]) { + if (text.length > 100 || text.length == 0 || [FBSDKAppEventsUtility isSensitiveUserData:text]) { return; } @@ -226,9 +226,8 @@ + (void)predictEventWithUIResponder:(UIResponder *)uiResponder text:(NSString *) } if ([_optInEvents containsObject:event]) { [FBSDKAppEvents logEvent:event - parameters:@{@"_is_suggested_event": @"1", - @"_button_text": text - }]; + parameters:@{@"_is_suggested_event" : @"1", + @"_button_text" : text}]; } else if ([_unconfirmedEvents containsObject:event]) { // Only send back not confirmed events to advertisers [self logSuggestedEvent:event withText:text withDenseFeature:[self getDenseFeaure:denseData] ?: @""]; @@ -238,14 +237,14 @@ + (void)predictEventWithUIResponder:(UIResponder *)uiResponder text:(NSString *) }); } -#pragma mark - Helper Methods + #pragma mark - Helper Methods + (NSString *)getDenseFeaure:(float *)denseData { // Get dense feature string NSMutableArray *denseDataArray = [NSMutableArray array]; for (int i = 0; i < 30; i++) { - [FBSDKTypeUtility array:denseDataArray addObject:[NSNumber numberWithFloat: denseData[i]]]; + [FBSDKTypeUtility array:denseDataArray addObject:[NSNumber numberWithFloat:denseData[i]]]; } return [denseDataArray componentsJoinedByString:@","]; } @@ -264,9 +263,8 @@ + (NSString *)getTextFromContentView:(UIView *)contentView + (void)logSuggestedEvent:(NSString *)event withText:(NSString *)text withDenseFeature:(NSString *)denseFeature { - NSString *metadata = [FBSDKBasicUtility JSONStringForObject:@{@"button_text": text, - @"dense": denseFeature, - } + NSString *metadata = [FBSDKBasicUtility JSONStringForObject:@{@"button_text" : text, + @"dense" : denseFeature, } error:nil invalidObjectHandler:nil]; if (!metadata) { @@ -275,9 +273,8 @@ + (void)logSuggestedEvent:(NSString *)event withText:(NSString *)text withDenseF FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/suggested_events", [FBSDKSettings appID]] - parameters: @{@"event_name": event, - @"metadata": metadata, - } + parameters:@{@"event_name" : event, + @"metadata" : metadata, } HTTPMethod:FBSDKHTTPMethodPOST]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {}]; return; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m index 9a14411c96..4fe87ed5e7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m @@ -20,21 +20,22 @@ #if !TARGET_OS_TV -#import "FBSDKViewHierarchy.h" + #import "FBSDKViewHierarchy.h" -#import + #import -#import + #import -#import "FBSDKCodelessPathComponent.h" -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKViewHierarchyMacros.h" + #import "FBSDKCodelessPathComponent.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKViewHierarchyMacros.h" -#define MAX_VIEW_HIERARCHY_LEVEL 35 + #define MAX_VIEW_HIERARCHY_LEVEL 35 NS_ASSUME_NONNULL_BEGIN -void fb_dispatch_on_main_thread(dispatch_block_t block) { +void fb_dispatch_on_main_thread(dispatch_block_t block) +{ if (block != nil) { if ([NSThread isMainThread]) { block(); @@ -44,15 +45,18 @@ void fb_dispatch_on_main_thread(dispatch_block_t block) { } } -void fb_dispatch_on_default_thread(dispatch_block_t block) { +void fb_dispatch_on_default_thread(dispatch_block_t block) +{ if (block != nil) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); } } +id getVariableFromInstance(NSObject *instance, NSString *variableName); + @implementation FBSDKViewHierarchy -+ (nullable NSArray*)getChildren:(NSObject*)obj ++ (nullable NSArray *)getChildren:(NSObject *)obj { if ([obj isKindOfClass:[UIControl class]]) { return nil; @@ -89,9 +93,9 @@ + (nullable NSArray*)getChildren:(NSObject*)obj } } } else if ([obj isKindOfClass:[UINavigationController class]]) { - UIViewController *vc = ((UINavigationController*)obj).visibleViewController; - UIViewController *tc = ((UINavigationController*)obj).topViewController; - NSArray *nextChildren = [FBSDKViewHierarchy getChildren:((UIViewController*)obj).view]; + UIViewController *vc = ((UINavigationController *)obj).visibleViewController; + UIViewController *tc = ((UINavigationController *)obj).topViewController; + NSArray *nextChildren = [FBSDKViewHierarchy getChildren:((UIViewController *)obj).view]; for (NSObject *child in nextChildren) { if (tc && [self isView:child superViewOfView:tc.view]) { [FBSDKTypeUtility array:children addObject:tc]; @@ -115,7 +119,7 @@ + (nullable NSArray*)getChildren:(NSObject*)obj } } else if ([obj isKindOfClass:[UITabBarController class]]) { UIViewController *vc = ((UITabBarController *)obj).selectedViewController; - NSArray *nextChildren = [FBSDKViewHierarchy getChildren:((UIViewController*)obj).view]; + NSArray *nextChildren = [FBSDKViewHierarchy getChildren:((UIViewController *)obj).view]; for (NSObject *child in nextChildren) { if (vc && [self isView:child superViewOfView:vc.view]) { [FBSDKTypeUtility array:children addObject:vc]; @@ -162,8 +166,7 @@ + (nullable NSObject *)getParent:(nullable NSObject *)obj if (superview && superview != obj) { return superview; } - } - else if ([obj isKindOfClass:[UIViewController class]]) { + } else if ([obj isKindOfClass:[UIViewController class]]) { UIViewController *vc = (UIViewController *)obj; UIViewController *parentVC = vc.parentViewController; UIViewController *presentingVC = vc.presentingViewController; @@ -219,13 +222,13 @@ + (nullable NSArray *)getPath:(NSObject *)obj limit:(int)limit NSDictionary *componentInfo = [FBSDKViewHierarchy getAttributesOf:obj parent:parent]; FBSDKCodelessPathComponent *pathComponent = [[FBSDKCodelessPathComponent alloc] - initWithJSON:componentInfo]; + initWithJSON:componentInfo]; [FBSDKTypeUtility array:path addObject:pathComponent]; return [NSArray arrayWithArray:path]; } -+ (NSDictionary *)getAttributesOf:(NSObject *)obj parent:(NSObject * _Nullable)parent ++ (NSDictionary *)getAttributesOf:(NSObject *)obj parent:(NSObject *_Nullable)parent { NSMutableDictionary *componentInfo = [NSMutableDictionary dictionary]; [FBSDKTypeUtility dictionary:componentInfo setObject:NSStringFromClass([obj class]) forKey:CODELESS_MAPPING_CLASS_NAME_KEY]; @@ -336,15 +339,33 @@ + (nullable NSIndexPath *)getIndexPath:(NSObject *)obj return indexPath; } +// This method only works for ObjC objects (whether statically typed or id) +id getVariableFromInstance(NSObject *instance, NSString *variableName) +{ + if (instance == nil || variableName.length == 0) { + return nil; + } + + Ivar ivar = class_getInstanceVariable([instance class], variableName.UTF8String); + if (ivar != NULL) { + const char *encoding = ivar_getTypeEncoding(ivar); + if (encoding != NULL && encoding[0] == '@') { + return object_getIvar(instance, ivar); + } + } + + return nil; +} + + (NSString *)getText:(nullable NSObject *)obj { NSString *text = nil; if ([obj isKindOfClass:[UIButton class]]) { text = ((UIButton *)obj).currentTitle; - } else if ([obj isKindOfClass:[UITextView class]] || - [obj isKindOfClass:[UITextField class]] || - [obj isKindOfClass:[UILabel class]]) { + } else if ([obj isKindOfClass:[UITextView class]] + || [obj isKindOfClass:[UITextField class]] + || [obj isKindOfClass:[UILabel class]]) { text = ((UILabel *)obj).text; } else if ([obj isKindOfClass:[UIPickerView class]]) { UIPickerView *picker = (UIPickerView *)obj; @@ -377,19 +398,19 @@ + (NSString *)getText:(nullable NSObject *)obj } } else if ([obj isKindOfClass:[UIDatePicker class]]) { UIDatePicker *picker = (UIDatePicker *)obj; - NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + NSDateFormatter *const formatter = [NSDateFormatter new]; formatter.dateFormat = @"yyyy-MM-dd HH:mm:ssZ"; text = [formatter stringFromDate:picker.date]; } else if ([obj isKindOfClass:objc_lookUpClass("RCTTextView")]) { - NSTextStorage *textStorage = [FBSDKAppEventsUtility getVariable:@"_textStorage" - fromInstance:obj]; + NSTextStorage *const textStorage = FBSDK_CAST_TO_CLASS_OR_NIL(getVariableFromInstance(obj, @"_textStorage"), NSTextStorage); if (textStorage) { - text = textStorage.string; + text = [textStorage string]; } } else if ([obj isKindOfClass:objc_lookUpClass("RCTBaseTextInputView")]) { - NSAttributedString *attributedText = [FBSDKAppEventsUtility getVariable:@"attributedText" - fromInstance:obj]; - text = attributedText.string; + NSAttributedString *const attributedText = FBSDK_CAST_TO_CLASS_OR_NIL(getVariableFromInstance(obj, @"attributedText"), NSAttributedString); + if (attributedText) { + text = [attributedText string]; + } } return text ?: @""; @@ -415,10 +436,10 @@ + (NSString *)getText:(nullable NSObject *)obj CGFloat fontSize = font.pointSize; return @{ - CODELESS_VIEW_TREE_TEXT_IS_BOLD_KEY: @(isBold), - CODELESS_VIEW_TREE_TEXT_IS_ITALIC_KEY: @(isItalic), - CODELESS_VIEW_TREE_TEXT_SIZE_KEY: @(fontSize) - }; + CODELESS_VIEW_TREE_TEXT_IS_BOLD_KEY : @(isBold), + CODELESS_VIEW_TREE_TEXT_IS_ITALIC_KEY : @(isItalic), + CODELESS_VIEW_TREE_TEXT_SIZE_KEY : @(fontSize) + }; } return nil; @@ -453,7 +474,7 @@ + (NSUInteger)getClassBitmask:(NSObject *)obj bitmask |= FBCodelessClassBitmaskUIButton; } else if ([obj isKindOfClass:[UISwitch class]]) { bitmask |= FBCodelessClassBitmaskSwitch; - }else if ([obj isKindOfClass:[UIDatePicker class]]) { + } else if ([obj isKindOfClass:[UIDatePicker class]]) { bitmask |= FBCodelessClassBitmaskPicker; } } else if ([obj isKindOfClass:[UITableViewCell class]]) { @@ -514,7 +535,7 @@ + (BOOL)isUserInputView:(NSObject *)obj } if (objAddressSet) { - if ([objAddressSet containsObject: currentNode]) { + if ([objAddressSet containsObject:currentNode]) { return nil; } [objAddressSet addObject:currentNode]; @@ -544,8 +565,8 @@ + (BOOL)isUserInputView:(NSObject *)obj return [result copy]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundeclared-selector" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wundeclared-selector" + (BOOL)isRCTButton:(UIView *)view { if (view == nil) { @@ -553,10 +574,10 @@ + (BOOL)isRCTButton:(UIView *)view } Class classRCTView = objc_lookUpClass(ReactNativeClassRCTView); - if (classRCTView && [view isKindOfClass:classRCTView] && - [view respondsToSelector:@selector(reactTagAtPoint:)] && - [view respondsToSelector:@selector(reactTag)] && - view.userInteractionEnabled) { + if (classRCTView && [view isKindOfClass:classRCTView] + && [view respondsToSelector:@selector(reactTagAtPoint:)] + && [view respondsToSelector:@selector(reactTag)] + && view.userInteractionEnabled) { // We check all its subviews locations and the view is clickable if there exists one that mathces reactTagAtPoint for (UIView *subview in view.subviews) { if (subview && ![subview isKindOfClass:classRCTView]) { @@ -584,7 +605,8 @@ + (nullable NSNumber *)getViewReactTag:(UIView *)view return nil; } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop + (BOOL)isView:(NSObject *)obj1 superViewOfView:(UIView *)obj2 { @@ -670,18 +692,19 @@ + (NSInteger)getTag:(NSObject *)obj CGRect frame = view.frame; CGPoint offset = CGPointZero; - if ([view isKindOfClass:[UIScrollView class]]) + if ([view isKindOfClass:[UIScrollView class]]) { offset = ((UIScrollView *)view).contentOffset; + } return @{ - CODELESS_VIEW_TREE_TOP_KEY: @((int)frame.origin.y), - CODELESS_VIEW_TREE_LEFT_KEY: @((int)frame.origin.x), - CODELESS_VIEW_TREE_WIDTH_KEY: @((int)frame.size.width), - CODELESS_VIEW_TREE_HEIGHT_KEY: @((int)frame.size.height), - CODELESS_VIEW_TREE_OFFSET_X_KEY: @((int)offset.x), - CODELESS_VIEW_TREE_OFFSET_Y_KEY: @((int)offset.y), - CODELESS_VIEW_TREE_VISIBILITY_KEY: view.isHidden ? @4 : @0 - }; + CODELESS_VIEW_TREE_TOP_KEY : @((int)frame.origin.y), + CODELESS_VIEW_TREE_LEFT_KEY : @((int)frame.origin.x), + CODELESS_VIEW_TREE_WIDTH_KEY : @((int)frame.size.width), + CODELESS_VIEW_TREE_HEIGHT_KEY : @((int)frame.size.height), + CODELESS_VIEW_TREE_OFFSET_X_KEY : @((int)offset.x), + CODELESS_VIEW_TREE_OFFSET_Y_KEY : @((int)offset.y), + CODELESS_VIEW_TREE_VISIBILITY_KEY : view.isHidden ? @4 : @0 + }; } + (NSString *)recursiveGetLabelsFromView:(UIView *)view diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchyMacros.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchyMacros.h index 5eedf9f3a0..c7a904814d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchyMacros.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchyMacros.h @@ -18,7 +18,7 @@ #ifndef FBSDKViewHierarchyMacros_h #define FBSDKViewHierarchyMacros_h -// keys for event binding path compoenent +// keys for event binding path compoenent #define CODELESS_MAPPING_METHOD_KEY @"method" #define CODELESS_MAPPING_EVENT_NAME_KEY @"event_name" #define CODELESS_MAPPING_EVENT_TYPE_KEY @"event_type" @@ -65,7 +65,7 @@ #define CODELESS_SETTING_TIMESTAMP_KEY @"codeless_setting_timestamp" #define CODELESS_SETTING_CACHE_TIMEOUT (7 * 24 * 60 * 60) -// keys for view tree +// keys for view tree #define CODELESS_VIEW_TREE_DESC_KEY @"description" #define CODELESS_VIEW_TREE_DIMENSION_KEY @"dimension" #define CODELESS_VIEW_TREE_TAG_KEY @"tag" @@ -84,7 +84,7 @@ #define CODELESS_VIEW_TREE_TEXT_IS_ITALIC_KEY @"is_italic" #define CODELESS_VIEW_TREE_TEXT_SIZE_KEY @"font_size" -// keys for view hierarchy +// keys for view hierarchy #define VIEW_HIERARCHY_CHILD_VIEWS_KEY @"childviews" #define VIEW_HIERARCHY_CLASS_NAME_KEY @"classname" #define VIEW_HIERARCHY_CLASS_TYPE_BITMASK_KEY @"classtypebitmask" diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLink.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLink.m index a1ea9d2dc6..2db4a3031d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLink.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLink.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKAppLink_Internal.h" + #import "FBSDKAppLink_Internal.h" NSString *const FBSDKAppLinkDataParameterName = @"al_applink_data"; NSString *const FBSDKAppLinkTargetKeyName = @"target_url"; @@ -38,7 +38,7 @@ @interface FBSDKAppLink () @property (nonatomic, copy) NSArray *targets; @property (nonatomic, strong) NSURL *webURL; -@property (nonatomic, assign, getter=isBackToReferrer) BOOL backToReferrer; +@property (nonatomic, getter = isBackToReferrer, assign) BOOL backToReferrer; @end @@ -47,28 +47,31 @@ @implementation FBSDKAppLink + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets webURL:(NSURL *)webURL - isBackToReferrer:(BOOL)isBackToReferrer { - FBSDKAppLink *link = [[self alloc] initWithIsBackToReferrer:isBackToReferrer]; - link.sourceURL = sourceURL; - link.targets = [targets copy]; - link.webURL = webURL; - return link; + isBackToReferrer:(BOOL)isBackToReferrer +{ + FBSDKAppLink *link = [[self alloc] initWithIsBackToReferrer:isBackToReferrer]; + link.sourceURL = sourceURL; + link.targets = [targets copy]; + link.webURL = webURL; + return link; } + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets - webURL:(NSURL *)webURL { - return [self appLinkWithSourceURL:sourceURL - targets:targets - webURL:webURL - isBackToReferrer:NO]; + webURL:(NSURL *)webURL +{ + return [self appLinkWithSourceURL:sourceURL + targets:targets + webURL:webURL + isBackToReferrer:NO]; } -- (FBSDKAppLink *)initWithIsBackToReferrer:(BOOL)backToReferrer { - if ((self = [super init])) { - _backToReferrer = backToReferrer; - } - return self; +- (FBSDKAppLink *)initWithIsBackToReferrer:(BOOL)backToReferrer +{ + if ((self = [super init])) { + _backToReferrer = backToReferrer; + } + return self; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkNavigation.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkNavigation.m index 14a3eab489..f5d4afd91b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkNavigation.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkNavigation.m @@ -20,14 +20,14 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkNavigation.h" + #import "FBSDKAppLinkNavigation.h" -#import "FBSDKAppLinkTarget.h" -#import "FBSDKAppLink_Internal.h" -#import "FBSDKMeasurementEvent_Internal.h" -#import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" -#import "FBSDKWebViewAppLinkResolver.h" + #import "FBSDKAppLinkTarget.h" + #import "FBSDKAppLink_Internal.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKMeasurementEvent_Internal.h" + #import "FBSDKSettings.h" + #import "FBSDKWebViewAppLinkResolver.h" FOUNDATION_EXPORT NSString *const FBSDKAppLinkDataParameterName; FOUNDATION_EXPORT NSString *const FBSDKAppLinkTargetKeyName; @@ -52,190 +52,199 @@ @implementation FBSDKAppLinkNavigation + (instancetype)navigationWithAppLink:(FBSDKAppLink *)appLink extras:(NSDictionary *)extras - appLinkData:(NSDictionary *)appLinkData { - FBSDKAppLinkNavigation *navigation = [[self alloc] init]; - navigation.appLink = appLink; - navigation.extras = extras; - navigation.appLinkData = appLinkData; - return navigation; + appLinkData:(NSDictionary *)appLinkData +{ + FBSDKAppLinkNavigation *navigation = [[self alloc] init]; + navigation.appLink = appLink; + navigation.extras = extras; + navigation.appLinkData = appLinkData; + return navigation; } + (NSDictionary *> *)callbackAppLinkDataForAppWithName:(NSString *)appName - url:(NSString *)url { - return @{FBSDKAppLinkRefererAppLink: @{FBSDKAppLinkRefererAppName: appName, FBSDKAppLinkRefererUrl: url}}; + url:(NSString *)url +{ + return @{FBSDKAppLinkRefererAppLink : @{FBSDKAppLinkRefererAppName : appName, FBSDKAppLinkRefererUrl : url}}; } -- (NSString *)stringByEscapingQueryString:(NSString *)string { - return [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; +- (NSString *)stringByEscapingQueryString:(NSString *)string +{ + return [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; } -- (NSURL *)appLinkURLWithTargetURL:(NSURL *)targetUrl error:(NSError **)error { - NSMutableDictionary *appLinkData = - [NSMutableDictionary dictionaryWithDictionary:self.appLinkData ?: @{}]; - - // Add applink protocol data - if (!appLinkData[FBSDKAppLinkUserAgentKeyName]) { - [FBSDKTypeUtility dictionary:appLinkData setObject:[NSString stringWithFormat:@"FBSDK %@", FBSDKSettings.sdkVersion] forKey:FBSDKAppLinkUserAgentKeyName]; - } - if (!appLinkData[FBSDKAppLinkVersionKeyName]) { - [FBSDKTypeUtility dictionary:appLinkData setObject:FBSDKAppLinkVersion forKey:FBSDKAppLinkVersionKeyName]; +- (NSURL *)appLinkURLWithTargetURL:(NSURL *)targetUrl error:(NSError **)error +{ + NSMutableDictionary *appLinkData = + [NSMutableDictionary dictionaryWithDictionary:self.appLinkData ?: @{}]; + + // Add applink protocol data + if (!appLinkData[FBSDKAppLinkUserAgentKeyName]) { + [FBSDKTypeUtility dictionary:appLinkData setObject:[NSString stringWithFormat:@"FBSDK %@", FBSDKSettings.sdkVersion] forKey:FBSDKAppLinkUserAgentKeyName]; + } + if (!appLinkData[FBSDKAppLinkVersionKeyName]) { + [FBSDKTypeUtility dictionary:appLinkData setObject:FBSDKAppLinkVersion forKey:FBSDKAppLinkVersionKeyName]; + } + if (self.appLink.sourceURL.absoluteString) { + [FBSDKTypeUtility dictionary:appLinkData setObject:self.appLink.sourceURL.absoluteString forKey:FBSDKAppLinkTargetKeyName]; + } + [FBSDKTypeUtility dictionary:appLinkData setObject:self.extras ?: @{} forKey:FBSDKAppLinkExtrasKeyName]; + + // JSON-ify the applink data + NSError *jsonError = nil; + NSData *jsonBlob = [FBSDKTypeUtility dataWithJSONObject:appLinkData options:0 error:&jsonError]; + if (!jsonError) { + NSString *jsonString = [[NSString alloc] initWithData:jsonBlob encoding:NSUTF8StringEncoding]; + NSString *encoded = [self stringByEscapingQueryString:jsonString]; + + NSString *endUrlString = [NSString stringWithFormat:@"%@%@%@=%@", + targetUrl.absoluteString, + targetUrl.query ? @"&" : @"?", + FBSDKAppLinkDataParameterName, + encoded]; + + return [NSURL URLWithString:endUrlString]; + } else { + if (error) { + *error = jsonError; } - if (self.appLink.sourceURL.absoluteString) { - [FBSDKTypeUtility dictionary:appLinkData setObject:self.appLink.sourceURL.absoluteString forKey:FBSDKAppLinkTargetKeyName]; - } - [FBSDKTypeUtility dictionary:appLinkData setObject:self.extras ?: @{} forKey:FBSDKAppLinkExtrasKeyName]; - - // JSON-ify the applink data - NSError *jsonError = nil; - NSData *jsonBlob = [FBSDKTypeUtility dataWithJSONObject:appLinkData options:0 error:&jsonError]; - if (!jsonError) { - NSString *jsonString = [[NSString alloc] initWithData:jsonBlob encoding:NSUTF8StringEncoding]; - NSString *encoded = [self stringByEscapingQueryString:jsonString]; - - NSString *endUrlString = [NSString stringWithFormat:@"%@%@%@=%@", - targetUrl.absoluteString, - targetUrl.query ? @"&" : @"?", - FBSDKAppLinkDataParameterName, - encoded]; - - return [NSURL URLWithString:endUrlString]; - } else { - if (error) { - *error = jsonError; - } - // If there was an error encoding the app link data, fail hard. - return nil; - } + // If there was an error encoding the app link data, fail hard. + return nil; + } } -- (FBSDKAppLinkNavigationType)navigate:(NSError **)error { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - NSURL *openedURL = nil; - NSError *encodingError = nil; - FBSDKAppLinkNavigationType retType = FBSDKAppLinkNavigationTypeFailure; - - // Find the first eligible/launchable target in the FBSDKAppLink. - for (FBSDKAppLinkTarget *target in self.appLink.targets) { - NSURL *appLinkAppURL = [self appLinkURLWithTargetURL:target.URL error:&encodingError]; - if (encodingError || !appLinkAppURL) { - if (error) { - *error = encodingError; - } - } else if ([[UIApplication sharedApplication] openURL:appLinkAppURL]) { - retType = FBSDKAppLinkNavigationTypeApp; - openedURL = appLinkAppURL; - break; - } +- (FBSDKAppLinkNavigationType)navigate:(NSError **)error +{ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSURL *openedURL = nil; + NSError *encodingError = nil; + FBSDKAppLinkNavigationType retType = FBSDKAppLinkNavigationTypeFailure; + + // Find the first eligible/launchable target in the FBSDKAppLink. + for (FBSDKAppLinkTarget *target in self.appLink.targets) { + NSURL *appLinkAppURL = [self appLinkURLWithTargetURL:target.URL error:&encodingError]; + if (encodingError || !appLinkAppURL) { + if (error) { + *error = encodingError; + } + } else if ([[UIApplication sharedApplication] openURL:appLinkAppURL]) { + retType = FBSDKAppLinkNavigationTypeApp; + openedURL = appLinkAppURL; + break; } - - if (!openedURL && self.appLink.webURL) { - // Fall back to opening the url in the browser if available. - NSURL *appLinkBrowserURL = [self appLinkURLWithTargetURL:self.appLink.webURL error:&encodingError]; - if (encodingError || !appLinkBrowserURL) { - // If there was an error encoding the app link data, fail hard. - if (error) { - *error = encodingError; - } - } else if ([[UIApplication sharedApplication] openURL:appLinkBrowserURL]) { - // This was a browser navigation. - retType = FBSDKAppLinkNavigationTypeBrowser; - openedURL = appLinkBrowserURL; - } + } + + if (!openedURL && self.appLink.webURL) { + // Fall back to opening the url in the browser if available. + NSURL *appLinkBrowserURL = [self appLinkURLWithTargetURL:self.appLink.webURL error:&encodingError]; + if (encodingError || !appLinkBrowserURL) { + // If there was an error encoding the app link data, fail hard. + if (error) { + *error = encodingError; + } + } else if ([[UIApplication sharedApplication] openURL:appLinkBrowserURL]) { + // This was a browser navigation. + retType = FBSDKAppLinkNavigationTypeBrowser; + openedURL = appLinkBrowserURL; } -#pragma clang diagnostic pop - - [self postAppLinkNavigateEventNotificationWithTargetURL:openedURL - error:error ? *error : nil - type:retType]; - return retType; -} + } + #pragma clang diagnostic pop -- (void)postAppLinkNavigateEventNotificationWithTargetURL:(NSURL *)outputURL error:(NSError *)error type:(FBSDKAppLinkNavigationType)type { - NSString *const EVENT_YES_VAL = @"1"; - NSString *const EVENT_NO_VAL = @"0"; - NSMutableDictionary *logData = - [[NSMutableDictionary alloc] init]; - - NSString *outputURLScheme = outputURL.scheme; - NSString *outputURLString = outputURL.absoluteString; - if (outputURLScheme) { - [FBSDKTypeUtility dictionary:logData setObject:outputURLScheme forKey:@"outputURLScheme"]; - } - if (outputURLString) { - [FBSDKTypeUtility dictionary:logData setObject:outputURLString forKey:@"outputURL"]; - } - - NSString *sourceURLString = self.appLink.sourceURL.absoluteString; - NSString *sourceURLHost = self.appLink.sourceURL.host; - NSString *sourceURLScheme = self.appLink.sourceURL.scheme; - if (sourceURLString) { - [FBSDKTypeUtility dictionary:logData setObject:sourceURLString forKey:@"sourceURL"]; - } - if (sourceURLHost) { - [FBSDKTypeUtility dictionary:logData setObject:sourceURLHost forKey:@"sourceHost"]; - } - if (sourceURLScheme) { - [FBSDKTypeUtility dictionary:logData setObject:sourceURLScheme forKey:@"sourceScheme"]; - } - if (error.localizedDescription) { - [FBSDKTypeUtility dictionary:logData setObject:error.localizedDescription forKey:@"error"]; - } - NSString *success = nil; //no - NSString *linkType = nil; // unknown; - switch (type) { - case FBSDKAppLinkNavigationTypeFailure: - success = EVENT_NO_VAL; - linkType = @"fail"; - break; - case FBSDKAppLinkNavigationTypeBrowser: - success = EVENT_YES_VAL; - linkType = @"web"; - break; - case FBSDKAppLinkNavigationTypeApp: - success = EVENT_YES_VAL; - linkType = @"app"; - break; - default: - break; - } - if (success) { - [FBSDKTypeUtility dictionary:logData setObject:success forKey:@"success"]; - } - if (linkType) { - [FBSDKTypeUtility dictionary:logData setObject:linkType forKey:@"type"]; - } + [self postAppLinkNavigateEventNotificationWithTargetURL:openedURL + error:error ? *error : nil + type:retType]; + return retType; +} - if (self.appLink.backToReferrer) { - [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkNavigateBackToReferrerEventName args:logData]; - } else { - [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkNavigateOutEventName args:logData]; - } +- (void)postAppLinkNavigateEventNotificationWithTargetURL:(NSURL *)outputURL error:(NSError *)error type:(FBSDKAppLinkNavigationType)type +{ + NSString *const EVENT_YES_VAL = @"1"; + NSString *const EVENT_NO_VAL = @"0"; + NSMutableDictionary *logData = + [[NSMutableDictionary alloc] init]; + + NSString *outputURLScheme = outputURL.scheme; + NSString *outputURLString = outputURL.absoluteString; + if (outputURLScheme) { + [FBSDKTypeUtility dictionary:logData setObject:outputURLScheme forKey:@"outputURLScheme"]; + } + if (outputURLString) { + [FBSDKTypeUtility dictionary:logData setObject:outputURLString forKey:@"outputURL"]; + } + + NSString *sourceURLString = self.appLink.sourceURL.absoluteString; + NSString *sourceURLHost = self.appLink.sourceURL.host; + NSString *sourceURLScheme = self.appLink.sourceURL.scheme; + if (sourceURLString) { + [FBSDKTypeUtility dictionary:logData setObject:sourceURLString forKey:@"sourceURL"]; + } + if (sourceURLHost) { + [FBSDKTypeUtility dictionary:logData setObject:sourceURLHost forKey:@"sourceHost"]; + } + if (sourceURLScheme) { + [FBSDKTypeUtility dictionary:logData setObject:sourceURLScheme forKey:@"sourceScheme"]; + } + if (error.localizedDescription) { + [FBSDKTypeUtility dictionary:logData setObject:error.localizedDescription forKey:@"error"]; + } + NSString *success = nil; // no + NSString *linkType = nil; // unknown; + switch (type) { + case FBSDKAppLinkNavigationTypeFailure: + success = EVENT_NO_VAL; + linkType = @"fail"; + break; + case FBSDKAppLinkNavigationTypeBrowser: + success = EVENT_YES_VAL; + linkType = @"web"; + break; + case FBSDKAppLinkNavigationTypeApp: + success = EVENT_YES_VAL; + linkType = @"app"; + break; + default: + break; + } + if (success) { + [FBSDKTypeUtility dictionary:logData setObject:success forKey:@"success"]; + } + if (linkType) { + [FBSDKTypeUtility dictionary:logData setObject:linkType forKey:@"type"]; + } + + if (self.appLink.backToReferrer) { + [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkNavigateBackToReferrerEventName args:logData]; + } else { + [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkNavigateOutEventName args:logData]; + } } + (void)resolveAppLink:(NSURL *)destination resolver:(id)resolver - handler:(FBSDKAppLinkBlock)handler { + handler:(FBSDKAppLinkBlock)handler +{ [resolver appLinkFromURL:destination handler:handler]; } -+ (void)resolveAppLink:(NSURL *)destination handler:(FBSDKAppLinkBlock)handler { ++ (void)resolveAppLink:(NSURL *)destination handler:(FBSDKAppLinkBlock)handler +{ [self resolveAppLink:destination resolver:[self defaultResolver] handler:handler]; } -+ (void)navigateToURL:(NSURL *)destination handler:(FBSDKAppLinkNavigationBlock)handler { ++ (void)navigateToURL:(NSURL *)destination handler:(FBSDKAppLinkNavigationBlock)handler +{ [self navigateToURL:destination resolver:[self defaultResolver] handler:handler]; } + (void)navigateToURL:(NSURL *)destination resolver:(id)resolver - handler:(FBSDKAppLinkNavigationBlock)handler { - + handler:(FBSDKAppLinkNavigationBlock)handler +{ dispatch_async(dispatch_get_main_queue(), ^{ [self resolveAppLink:destination resolver:resolver - handler:^(FBSDKAppLink * _Nullable appLink, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable appLink, NSError *_Nullable error) { if (error) { handler(FBSDKAppLinkNavigationTypeFailure, error); return; @@ -248,55 +257,60 @@ + (void)navigateToURL:(NSURL *)destination }); } -+ (FBSDKAppLinkNavigationType)navigateToAppLink:(FBSDKAppLink *)link error:(NSError **)error { - return [[FBSDKAppLinkNavigation navigationWithAppLink:link - extras:@{} - appLinkData:@{}] navigate:error]; ++ (FBSDKAppLinkNavigationType)navigateToAppLink:(FBSDKAppLink *)link error:(NSError **)error +{ + return [[FBSDKAppLinkNavigation navigationWithAppLink:link + extras:@{} + appLinkData:@{}] navigate:error]; } -+ (FBSDKAppLinkNavigationType)navigationTypeForLink:(FBSDKAppLink *)link { - return [[self navigationWithAppLink:link extras:@{} appLinkData:@{}] navigationType]; ++ (FBSDKAppLinkNavigationType)navigationTypeForLink:(FBSDKAppLink *)link +{ + return [[self navigationWithAppLink:link extras:@{} appLinkData:@{}] navigationType]; } -- (FBSDKAppLinkNavigationType)navigationType { - FBSDKAppLinkTarget *eligibleTarget = nil; - for (FBSDKAppLinkTarget *target in self.appLink.targets) { - if ([[UIApplication sharedApplication] canOpenURL:target.URL]) { - eligibleTarget = target; - break; - } +- (FBSDKAppLinkNavigationType)navigationType +{ + FBSDKAppLinkTarget *eligibleTarget = nil; + for (FBSDKAppLinkTarget *target in self.appLink.targets) { + if ([[UIApplication sharedApplication] canOpenURL:target.URL]) { + eligibleTarget = target; + break; } + } - if (eligibleTarget != nil) { - NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil]; - if (appLinkURL != nil) { - return FBSDKAppLinkNavigationTypeApp; - } else { - return FBSDKAppLinkNavigationTypeFailure; - } + if (eligibleTarget != nil) { + NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil]; + if (appLinkURL != nil) { + return FBSDKAppLinkNavigationTypeApp; + } else { + return FBSDKAppLinkNavigationTypeFailure; } + } - if (self.appLink.webURL != nil) { - NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil]; - if (appLinkURL != nil) { - return FBSDKAppLinkNavigationTypeBrowser; - } else { - return FBSDKAppLinkNavigationTypeFailure; - } + if (self.appLink.webURL != nil) { + NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil]; + if (appLinkURL != nil) { + return FBSDKAppLinkNavigationTypeBrowser; + } else { + return FBSDKAppLinkNavigationTypeFailure; } + } - return FBSDKAppLinkNavigationTypeFailure; + return FBSDKAppLinkNavigationTypeFailure; } -+ (id)defaultResolver { - if (defaultResolver) { - return defaultResolver; - } - return [FBSDKWebViewAppLinkResolver sharedInstance]; ++ (id)defaultResolver +{ + if (defaultResolver) { + return defaultResolver; + } + return [FBSDKWebViewAppLinkResolver sharedInstance]; } -+ (void)setDefaultResolver:(id)resolver { - defaultResolver = resolver; ++ (void)setDefaultResolver:(id)resolver +{ + defaultResolver = resolver; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.m index 97dd764af4..9e9cade28e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.m @@ -20,19 +20,19 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkResolver.h" + #import "FBSDKAppLinkResolver.h" -#import + #import -#import "FBSDKAccessToken.h" -#import "FBSDKAppLink.h" -#import "FBSDKAppLinkTarget.h" -#import "FBSDKGraphRequest+Internal.h" -#import "FBSDKGraphRequestConnection.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKLogger.h" -#import "FBSDKSettings+Internal.h" -#import "FBSDKUtility.h" + #import "FBSDKAccessToken.h" + #import "FBSDKAppLink.h" + #import "FBSDKAppLinkTarget.h" + #import "FBSDKGraphRequest+Internal.h" + #import "FBSDKGraphRequestConnection.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKLogger.h" + #import "FBSDKSettings+Internal.h" + #import "FBSDKUtility.h" static NSString *const kURLKey = @"url"; static NSString *const kIOSAppStoreIdKey = @"app_store_id"; @@ -54,8 +54,7 @@ @implementation FBSDKAppLinkResolver + (void)initialize { - if (self == [FBSDKAppLinkResolver class]) { - } + if (self == [FBSDKAppLinkResolver class]) {} } - (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom @@ -69,7 +68,7 @@ - (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceId - (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkBlock)handler { - [self appLinksFromURLs:@[url] handler:^(NSDictionary *urls, NSError * _Nullable error) { + [self appLinksFromURLs:@[url] handler:^(NSDictionary *urls, NSError *_Nullable error) { handler(urls[url], error); }]; } @@ -84,16 +83,16 @@ - (void)appLinksFromURLs:(NSArray *)urls handler:(FBSDKAppLinksBlock)ha NSMutableArray *toFind = [NSMutableArray array]; NSMutableArray *toFindStrings = [NSMutableArray array]; - @synchronized (self.cachedFBSDKAppLinks) { + @synchronized(self.cachedFBSDKAppLinks) { for (NSURL *url in urls) { if (self.cachedFBSDKAppLinks[url]) { [FBSDKTypeUtility dictionary:appLinks setObject:self.cachedFBSDKAppLinks[url] forKey:url]; } else { [FBSDKTypeUtility array:toFind addObject:url]; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSString *toFindString = [url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -#pragma clang diagnostic pop + #pragma clang diagnostic pop if (toFindString) { [FBSDKTypeUtility array:toFindStrings addObject:toFindString]; } @@ -145,8 +144,8 @@ - (void)appLinksFromURLs:(NSArray *)urls handler:(FBSDKAppLinksBlock)ha NSMutableArray *targets = [NSMutableArray arrayWithCapacity:rawTargets.count]; for (id rawTarget in rawTargets) { [FBSDKTypeUtility array:targets addObject:[FBSDKAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:rawTarget[kURLKey]] - appStoreId:rawTarget[kIOSAppStoreIdKey] - appName:rawTarget[kIOSAppNameKey]]]; + appStoreId:rawTarget[kIOSAppStoreIdKey] + appName:rawTarget[kIOSAppNameKey]]]; } id webTarget = nestedObject[kWebKey]; @@ -161,7 +160,7 @@ - (void)appLinksFromURLs:(NSArray *)urls handler:(FBSDKAppLinksBlock)ha FBSDKAppLink *link = [FBSDKAppLink appLinkWithSourceURL:url targets:targets webURL:fallbackUrl]; - @synchronized (self.cachedFBSDKAppLinks) { + @synchronized(self.cachedFBSDKAppLinks) { [FBSDKTypeUtility dictionary:self.cachedFBSDKAppLinks setObject:link forKey:url]; } [FBSDKTypeUtility dictionary:appLinks setObject:link forKey:url]; @@ -170,13 +169,14 @@ - (void)appLinksFromURLs:(NSArray *)urls handler:(FBSDKAppLinksBlock)ha }]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (instancetype)resolver { return [[self alloc] initWithUserInterfaceIdiom:UI_USER_INTERFACE_IDIOM()]; } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererController.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererController.m index 39ceae629c..ab6f4b3f0f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererController.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererController.m @@ -20,227 +20,246 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkReturnToRefererController.h" + #import "FBSDKAppLinkReturnToRefererController.h" -#import "FBSDKAppLink.h" -#import "FBSDKAppLinkReturnToRefererView_Internal.h" -#import "FBSDKURL_Internal.h" + #import "FBSDKAppLink.h" + #import "FBSDKAppLinkReturnToRefererView_Internal.h" + #import "FBSDKURL_Internal.h" static const CFTimeInterval kFBSDKViewAnimationDuration = 0.25f; -@implementation FBSDKAppLinkReturnToRefererController { - UINavigationController *_navigationController; - FBSDKAppLinkReturnToRefererView *_view; +@implementation FBSDKAppLinkReturnToRefererController +{ + UINavigationController *_navigationController; + FBSDKAppLinkReturnToRefererView *_view; } -#pragma mark - Object lifecycle + #pragma mark - Object lifecycle -- (instancetype)init { +- (instancetype)init +{ return [super init]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -- (instancetype)initForDisplayAboveNavController:(UINavigationController *)navController { - self = [self init]; - if (self) { - _navigationController = navController; - - if (_navigationController != nil) { - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self - selector:@selector(statusBarFrameWillChange:) - name:UIApplicationWillChangeStatusBarFrameNotification - object:nil]; - [nc addObserver:self - selector:@selector(statusBarFrameDidChange:) - name:UIApplicationDidChangeStatusBarFrameNotification - object:nil]; - [nc addObserver:self - selector:@selector(orientationDidChange:) - name:UIDeviceOrientationDidChangeNotification - object:nil]; - } + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (instancetype)initForDisplayAboveNavController:(UINavigationController *)navController +{ + self = [self init]; + if (self) { + _navigationController = navController; + + if (_navigationController != nil) { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self + selector:@selector(statusBarFrameWillChange:) + name:UIApplicationWillChangeStatusBarFrameNotification + object:nil]; + [nc addObserver:self + selector:@selector(statusBarFrameDidChange:) + name:UIApplicationDidChangeStatusBarFrameNotification + object:nil]; + [nc addObserver:self + selector:@selector(orientationDidChange:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; } - return self; + } + return self; } -- (void)dealloc { - _view.delegate = nil; - [[NSNotificationCenter defaultCenter] removeObserver:self]; +- (void)dealloc +{ + _view.delegate = nil; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } -#pragma mark - Public API + #pragma mark - Public API -- (FBSDKAppLinkReturnToRefererView *)view { - if (!_view) { - self.view = [[FBSDKAppLinkReturnToRefererView alloc] initWithFrame:CGRectZero]; - if (_navigationController) { - [_navigationController.view addSubview:_view]; - } +- (FBSDKAppLinkReturnToRefererView *)view +{ + if (!_view) { + self.view = [[FBSDKAppLinkReturnToRefererView alloc] initWithFrame:CGRectZero]; + if (_navigationController) { + [_navigationController.view addSubview:_view]; } - return _view; + } + return _view; } -- (void)setView:(FBSDKAppLinkReturnToRefererView *)view { - if (_view != view) { - _view.delegate = nil; - } +- (void)setView:(FBSDKAppLinkReturnToRefererView *)view +{ + if (_view != view) { + _view.delegate = nil; + } - _view = view; - _view.delegate = self; + _view = view; + _view.delegate = self; - if (_navigationController) { - _view.includeStatusBarInSize = FBSDKIncludeStatusBarInSizeAlways; - } + if (_navigationController) { + _view.includeStatusBarInSize = FBSDKIncludeStatusBarInSizeAlways; + } } -- (void)showViewForRefererAppLink:(FBSDKAppLink *)refererAppLink { - self.view.refererAppLink = refererAppLink; +- (void)showViewForRefererAppLink:(FBSDKAppLink *)refererAppLink +{ + self.view.refererAppLink = refererAppLink; - [_view sizeToFit]; + [_view sizeToFit]; - if (_navigationController) { - if (!_view.closed) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self moveNavigationBar]; - }); - } + if (_navigationController) { + if (!_view.closed) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self moveNavigationBar]; + }); } + } } -- (void)showViewForRefererURL:(NSURL *)url { - FBSDKAppLink *appLink = [FBSDKURL URLForRenderBackToReferrerBarURL:url].appLinkReferer; - [self showViewForRefererAppLink:appLink]; +- (void)showViewForRefererURL:(NSURL *)url +{ + FBSDKAppLink *appLink = [FBSDKURL URLForRenderBackToReferrerBarURL:url].appLinkReferer; + [self showViewForRefererAppLink:appLink]; } -- (void)removeFromNavController { - if (_navigationController) { - [_view removeFromSuperview]; - _navigationController = nil; - } +- (void)removeFromNavController +{ + if (_navigationController) { + [_view removeFromSuperview]; + _navigationController = nil; + } } -#pragma mark - FBSDKAppLinkReturnToRefererViewDelegate + #pragma mark - FBSDKAppLinkReturnToRefererViewDelegate -- (void)returnToRefererViewDidTapInsideCloseButton:(FBSDKAppLinkReturnToRefererView *)view { - [self closeViewAnimated:YES explicitlyClosed:YES]; +- (void)returnToRefererViewDidTapInsideCloseButton:(FBSDKAppLinkReturnToRefererView *)view +{ + [self closeViewAnimated:YES explicitlyClosed:YES]; } - (void)returnToRefererViewDidTapInsideLink:(FBSDKAppLinkReturnToRefererView *)view - link:(FBSDKAppLink *)link { - [self openRefererAppLink:link]; - [self closeViewAnimated:NO explicitlyClosed:NO]; + link:(FBSDKAppLink *)link +{ + [self openRefererAppLink:link]; + [self closeViewAnimated:NO explicitlyClosed:NO]; } -#pragma mark - Private + #pragma mark - Private -- (void)statusBarFrameWillChange:(NSNotification *)notification { - NSValue *rectValue = [notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey]; - CGRect newFrame; - [rectValue getValue:&newFrame]; +- (void)statusBarFrameWillChange:(NSNotification *)notification +{ + NSValue *rectValue = [notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey]; + CGRect newFrame; + [rectValue getValue:&newFrame]; - if (_navigationController && !_view.closed) { - if (CGRectGetHeight(newFrame) == 40) { - UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; - [UIView animateWithDuration:kFBSDKViewAnimationDuration delay:0.0 options:options animations:^{ - self->_view.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self->_view.bounds), 0.0); - } completion:nil]; - } + if (_navigationController && !_view.closed) { + if (CGRectGetHeight(newFrame) == 40) { + UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; + [UIView animateWithDuration:kFBSDKViewAnimationDuration delay:0.0 options:options animations:^{ + self->_view.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(self->_view.bounds), 0.0); + } completion:nil]; } + } } -- (void)statusBarFrameDidChange:(NSNotification *)notification { - NSValue *rectValue = [notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey]; - CGRect newFrame; - [rectValue getValue:&newFrame]; - - if (_navigationController && !_view.closed) { - if (CGRectGetHeight(newFrame) == 40) { - UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; - [UIView animateWithDuration:kFBSDKViewAnimationDuration delay:0.0 options:options animations:^{ - [self->_view sizeToFit]; - [self moveNavigationBar]; - } completion:nil]; - } +- (void)statusBarFrameDidChange:(NSNotification *)notification +{ + NSValue *rectValue = [notification.userInfo valueForKey:UIApplicationStatusBarFrameUserInfoKey]; + CGRect newFrame; + [rectValue getValue:&newFrame]; + + if (_navigationController && !_view.closed) { + if (CGRectGetHeight(newFrame) == 40) { + UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; + [UIView animateWithDuration:kFBSDKViewAnimationDuration delay:0.0 options:options animations:^{ + [self->_view sizeToFit]; + [self moveNavigationBar]; + } completion:nil]; } + } } -- (void)orientationDidChange:(NSNotificationCenter *)notification { - if (_navigationController && !_view.closed && CGRectGetHeight(_view.bounds) > 0) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self moveNavigationBar]; - }); - } +- (void)orientationDidChange:(NSNotificationCenter *)notification +{ + if (_navigationController && !_view.closed && CGRectGetHeight(_view.bounds) > 0) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self moveNavigationBar]; + }); + } } -- (void)moveNavigationBar { - if (_view.closed || !_view.refererAppLink) { - return; +- (void)moveNavigationBar +{ + if (_view.closed || !_view.refererAppLink) { + return; + } + + [self updateNavigationBarY:CGRectGetHeight(_view.bounds)]; +} + +- (void)updateNavigationBarY:(CGFloat)y +{ + UINavigationBar *navigationBar = _navigationController.navigationBar; + CGRect navigationBarFrame = navigationBar.frame; + CGFloat oldContainerViewY = CGRectGetMaxY(navigationBarFrame); + navigationBarFrame.origin.y = y; + navigationBar.frame = navigationBarFrame; + + CGFloat dy = CGRectGetMaxY(navigationBarFrame) - oldContainerViewY; + UIView *containerView = _navigationController.visibleViewController.view.superview; + containerView.frame = UIEdgeInsetsInsetRect(containerView.frame, UIEdgeInsetsMake(dy, 0.0, 0.0, 0.0)); +} + +- (void)closeViewAnimated:(BOOL)animated +{ + [self closeViewAnimated:animated explicitlyClosed:YES]; +} + +- (void)closeViewAnimated:(BOOL)animated explicitlyClosed:(BOOL)explicitlyClosed +{ + void (^closer)(void) = ^{ + if (self->_navigationController) { + [self updateNavigationBarY:self->_view.statusBarHeight]; } - [self updateNavigationBarY:CGRectGetHeight(_view.bounds)]; -} - -- (void)updateNavigationBarY:(CGFloat)y { - UINavigationBar *navigationBar = _navigationController.navigationBar; - CGRect navigationBarFrame = navigationBar.frame; - CGFloat oldContainerViewY = CGRectGetMaxY(navigationBarFrame); - navigationBarFrame.origin.y = y; - navigationBar.frame = navigationBarFrame; - - CGFloat dy = CGRectGetMaxY(navigationBarFrame) - oldContainerViewY; - UIView *containerView = _navigationController.visibleViewController.view.superview; - containerView.frame = UIEdgeInsetsInsetRect(containerView.frame, UIEdgeInsetsMake(dy, 0.0, 0.0, 0.0)); -} - -- (void)closeViewAnimated:(BOOL)animated { - [self closeViewAnimated:animated explicitlyClosed:YES]; -} - -- (void)closeViewAnimated:(BOOL)animated explicitlyClosed:(BOOL)explicitlyClosed { - void (^closer)(void) = ^{ - if (self->_navigationController) { - [self updateNavigationBarY:self->_view.statusBarHeight]; - } - - CGRect frame = self->_view.frame; - frame.size.height = 0.0; - self->_view.frame = frame; - }; - - if (animated) { - [UIView animateWithDuration:kFBSDKViewAnimationDuration animations:^{ - closer(); - } completion:^(BOOL finished) { - if (explicitlyClosed) { - self->_view.closed = YES; - } - }]; - } else { - closer(); - if (explicitlyClosed) { - self->_view.closed = YES; - } + CGRect frame = self->_view.frame; + frame.size.height = 0.0; + self->_view.frame = frame; + }; + + if (animated) { + [UIView animateWithDuration:kFBSDKViewAnimationDuration animations:^{ + closer(); + } completion:^(BOOL finished) { + if (explicitlyClosed) { + self->_view.closed = YES; + } + }]; + } else { + closer(); + if (explicitlyClosed) { + self->_view.closed = YES; } + } } -- (void)openRefererAppLink:(FBSDKAppLink *)refererAppLink { - if (refererAppLink) { - id delegate = _delegate; - if ([delegate respondsToSelector:@selector(returnToRefererController:willNavigateToAppLink:)]) { - [delegate returnToRefererController:self willNavigateToAppLink:refererAppLink]; - } +- (void)openRefererAppLink:(FBSDKAppLink *)refererAppLink +{ + if (refererAppLink) { + id delegate = _delegate; + if ([delegate respondsToSelector:@selector(returnToRefererController:willNavigateToAppLink:)]) { + [delegate returnToRefererController:self willNavigateToAppLink:refererAppLink]; + } - NSError *error = nil; - FBSDKAppLinkNavigationType type = [FBSDKAppLinkNavigation navigateToAppLink:refererAppLink error:&error]; + NSError *error = nil; + FBSDKAppLinkNavigationType type = [FBSDKAppLinkNavigation navigateToAppLink:refererAppLink error:&error]; - if ([delegate respondsToSelector:@selector(returnToRefererController:didNavigateToAppLink:type:)]) { - [delegate returnToRefererController:self didNavigateToAppLink:refererAppLink type:type]; - } + if ([delegate respondsToSelector:@selector(returnToRefererController:didNavigateToAppLink:type:)]) { + [delegate returnToRefererController:self didNavigateToAppLink:refererAppLink type:type]; } + } } @end -#pragma clang diagnostic pop + #pragma clang diagnostic pop #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererView.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererView.m index 98fe95e1ba..ca55cf18ee 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkReturnToRefererView.m @@ -20,11 +20,11 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkReturnToRefererView.h" + #import "FBSDKAppLinkReturnToRefererView.h" -#import "FBSDKAppLink.h" -#import "FBSDKAppLinkTarget.h" -#import "FBSDKInternalUtility.h" + #import "FBSDKAppLink.h" + #import "FBSDKAppLinkTarget.h" + #import "FBSDKInternalUtility.h" static const CGFloat FBSDKMarginX = 8.5f; static const CGFloat FBSDKMarginY = 8.5f; @@ -43,232 +43,258 @@ @interface FBSDKAppLinkReturnToRefererView () @end -@implementation FBSDKAppLinkReturnToRefererView { - BOOL _explicitlyHidden; +@implementation FBSDKAppLinkReturnToRefererView +{ + BOOL _explicitlyHidden; } -#pragma mark - Initialization + #pragma mark - Initialization -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - [self commonInit]; - [self sizeToFit]; - } - return self; +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInit]; + [self sizeToFit]; + } + return self; } -- (instancetype)initWithCoder:(NSCoder *)aDecoder { - self = [super initWithCoder:aDecoder]; - if (self) { - [self commonInit]; - } - return self; +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInit]; + } + return self; } -- (void)commonInit { - // Initialization code - _includeStatusBarInSize = FBSDKIncludeStatusBarInSizeAlways; +- (void)commonInit +{ + // Initialization code + _includeStatusBarInSize = FBSDKIncludeStatusBarInSizeAlways; - // iOS 7 system blue color - self.backgroundColor = [UIColor colorWithRed:0.0f green:122.0f / 255.0f blue:1.0f alpha:1.0f]; - self.textColor = [UIColor whiteColor]; - self.clipsToBounds = YES; + // iOS 7 system blue color + self.backgroundColor = [UIColor colorWithRed:0.0f green:122.0f / 255.0f blue:1.0f alpha:1.0f]; + self.textColor = [UIColor whiteColor]; + self.clipsToBounds = YES; - [self initViews]; + [self initViews]; } -- (void)initViews { - if (!_labelView && !_closeButton) { - _closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; - _closeButton.backgroundColor = [UIColor clearColor]; - _closeButton.userInteractionEnabled = YES; - _closeButton.clipsToBounds = YES; - _closeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; - _closeButton.contentMode = UIViewContentModeCenter; - [_closeButton addTarget:self action:@selector(closeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; - - [self addSubview:_closeButton]; - - _labelView = [[UILabel alloc] initWithFrame:CGRectZero]; - _labelView.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]]; - _labelView.textColor = [UIColor whiteColor]; - _labelView.backgroundColor = [UIColor clearColor]; - _labelView.textAlignment = NSTextAlignmentCenter; - _labelView.clipsToBounds = YES; - [self updateLabelText]; - [self addSubview:_labelView]; - - _insideTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapInside:)]; - _labelView.userInteractionEnabled = YES; - [_labelView addGestureRecognizer:_insideTapGestureRecognizer]; - - [self updateColors]; - } -} - -#pragma mark - Layout - -- (CGSize)intrinsicContentSize { - CGSize size = self.bounds.size; - if (_closed || !self.hasRefererData) { - size.height = 0.0; - } else { - CGSize labelSize = [_labelView sizeThatFits:size]; - size = CGSizeMake(size.width, labelSize.height + 2 * FBSDKMarginY + self.statusBarHeight); - } - return size; -} +- (void)initViews +{ + if (!_labelView && !_closeButton) { + _closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; + _closeButton.backgroundColor = [UIColor clearColor]; + _closeButton.userInteractionEnabled = YES; + _closeButton.clipsToBounds = YES; + _closeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; + _closeButton.contentMode = UIViewContentModeCenter; + [_closeButton addTarget:self action:@selector(closeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; + + [self addSubview:_closeButton]; + + _labelView = [[UILabel alloc] initWithFrame:CGRectZero]; + _labelView.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]]; + _labelView.textColor = [UIColor whiteColor]; + _labelView.backgroundColor = [UIColor clearColor]; + _labelView.textAlignment = NSTextAlignmentCenter; + _labelView.clipsToBounds = YES; + [self updateLabelText]; + [self addSubview:_labelView]; -- (void)layoutSubviews { - [super layoutSubviews]; + _insideTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapInside:)]; + _labelView.userInteractionEnabled = YES; + [_labelView addGestureRecognizer:_insideTapGestureRecognizer]; - CGRect bounds = self.bounds; + [self updateColors]; + } +} - _labelView.preferredMaxLayoutWidth = _labelView.bounds.size.width; - CGSize labelSize = [_labelView sizeThatFits:bounds.size]; - _labelView.frame = CGRectMake(FBSDKMarginX, - CGRectGetMaxY(bounds) - labelSize.height - 1.5f * FBSDKMarginY, - CGRectGetMaxX(bounds) - FBSDKCloseButtonWidth - 3 * FBSDKMarginX, - labelSize.height + FBSDKMarginY); + #pragma mark - Layout + +- (CGSize)intrinsicContentSize +{ + CGSize size = self.bounds.size; + if (_closed || !self.hasRefererData) { + size.height = 0.0; + } else { + CGSize labelSize = [_labelView sizeThatFits:size]; + size = CGSizeMake(size.width, labelSize.height + 2 * FBSDKMarginY + self.statusBarHeight); + } + return size; +} - _closeButton.frame = CGRectMake(CGRectGetMaxX(bounds) - FBSDKCloseButtonWidth - 2 * FBSDKMarginX, - _labelView.center.y - FBSDKCloseButtonHeight / 2.0f - FBSDKMarginY, - FBSDKCloseButtonWidth + 2 * FBSDKMarginX, - FBSDKCloseButtonHeight + 2 * FBSDKMarginY); +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGRect bounds = self.bounds; + + _labelView.preferredMaxLayoutWidth = _labelView.bounds.size.width; + CGSize labelSize = [_labelView sizeThatFits:bounds.size]; + _labelView.frame = CGRectMake( + FBSDKMarginX, + CGRectGetMaxY(bounds) - labelSize.height - 1.5f * FBSDKMarginY, + CGRectGetMaxX(bounds) - FBSDKCloseButtonWidth - 3 * FBSDKMarginX, + labelSize.height + FBSDKMarginY + ); + + _closeButton.frame = CGRectMake( + CGRectGetMaxX(bounds) - FBSDKCloseButtonWidth - 2 * FBSDKMarginX, + _labelView.center.y - FBSDKCloseButtonHeight / 2.0f - FBSDKMarginY, + FBSDKCloseButtonWidth + 2 * FBSDKMarginX, + FBSDKCloseButtonHeight + 2 * FBSDKMarginY + ); } -- (CGSize)sizeThatFits:(CGSize)size { - if (_closed || !self.hasRefererData) { - size = CGSizeMake(size.width, 0.0); - } else { - CGSize labelSize = [_labelView sizeThatFits:size]; - size = CGSizeMake(size.width, labelSize.height + 2 * FBSDKMarginY + self.statusBarHeight); - } - return size; +- (CGSize)sizeThatFits:(CGSize)size +{ + if (_closed || !self.hasRefererData) { + size = CGSizeMake(size.width, 0.0); + } else { + CGSize labelSize = [_labelView sizeThatFits:size]; + size = CGSizeMake(size.width, labelSize.height + 2 * FBSDKMarginY + self.statusBarHeight); + } + return size; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -- (CGFloat)statusBarHeight { - UIApplication *application = [UIApplication sharedApplication]; - - BOOL include; - switch (_includeStatusBarInSize) { - case FBSDKIncludeStatusBarInSizeAlways: - include = YES; - break; - case FBSDKIncludeStatusBarInSizeNever: - include = NO; - break; - } - if (include && !application.statusBarHidden) { - BOOL landscape = UIInterfaceOrientationIsLandscape(FBSDKInternalUtility.statusBarOrientation); - CGRect statusBarFrame = application.statusBarFrame; - return landscape ? CGRectGetWidth(statusBarFrame) : CGRectGetHeight(statusBarFrame); - } - - return 0; + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (CGFloat)statusBarHeight +{ + UIApplication *application = [UIApplication sharedApplication]; + + BOOL include; + switch (_includeStatusBarInSize) { + case FBSDKIncludeStatusBarInSizeAlways: + include = YES; + break; + case FBSDKIncludeStatusBarInSizeNever: + include = NO; + break; + } + if (include && !application.statusBarHidden) { + BOOL landscape = UIInterfaceOrientationIsLandscape(FBSDKInternalUtility.statusBarOrientation); + CGRect statusBarFrame = application.statusBarFrame; + return landscape ? CGRectGetWidth(statusBarFrame) : CGRectGetHeight(statusBarFrame); + } + + return 0; } -#pragma clang diagnostic pop -#pragma mark - Public API + #pragma clang diagnostic pop -- (void)setIncludeStatusBarInSize:(FBSDKIncludeStatusBarInSize)includeStatusBarInSize { - _includeStatusBarInSize = includeStatusBarInSize; - [self setNeedsLayout]; - [self invalidateIntrinsicContentSize]; -} + #pragma mark - Public API -- (void)setTextColor:(UIColor *)textColor { - _textColor = textColor; - [self updateColors]; +- (void)setIncludeStatusBarInSize:(FBSDKIncludeStatusBarInSize)includeStatusBarInSize +{ + _includeStatusBarInSize = includeStatusBarInSize; + [self setNeedsLayout]; + [self invalidateIntrinsicContentSize]; } -- (void)setRefererAppLink:(FBSDKAppLink *)refererAppLink { - _refererAppLink = refererAppLink; - [self updateLabelText]; - [self updateHidden]; - [self invalidateIntrinsicContentSize]; +- (void)setTextColor:(UIColor *)textColor +{ + _textColor = textColor; + [self updateColors]; } -- (void)setClosed:(BOOL)closed { - if (_closed != closed) { - _closed = closed; - [self updateHidden]; - [self invalidateIntrinsicContentSize]; - } +- (void)setRefererAppLink:(FBSDKAppLink *)refererAppLink +{ + _refererAppLink = refererAppLink; + [self updateLabelText]; + [self updateHidden]; + [self invalidateIntrinsicContentSize]; } -- (void)setHidden:(BOOL)hidden { - _explicitlyHidden = hidden; +- (void)setClosed:(BOOL)closed +{ + if (_closed != closed) { + _closed = closed; [self updateHidden]; + [self invalidateIntrinsicContentSize]; + } } -#pragma mark - Private - -- (void)updateLabelText { - NSString *appName = (_refererAppLink && [FBSDKTypeUtility array:_refererAppLink.targets objectAtIndex:0]) ? [[FBSDKTypeUtility array:_refererAppLink.targets objectAtIndex:0] appName] : nil; - _labelView.text = [self localizedLabelForReferer:appName]; +- (void)setHidden:(BOOL)hidden +{ + _explicitlyHidden = hidden; + [self updateHidden]; } -- (void)updateColors { - UIImage *closeButtonImage = [self drawCloseButtonImageWithColor:_textColor]; + #pragma mark - Private - _labelView.textColor = _textColor; - [_closeButton setImage:closeButtonImage forState:UIControlStateNormal]; +- (void)updateLabelText +{ + NSString *appName = (_refererAppLink && [FBSDKTypeUtility array:_refererAppLink.targets objectAtIndex:0]) ? [[FBSDKTypeUtility array:_refererAppLink.targets objectAtIndex:0] appName] : nil; + _labelView.text = [self localizedLabelForReferer:appName]; } -- (UIImage *)drawCloseButtonImageWithColor:(UIColor *)color { +- (void)updateColors +{ + UIImage *closeButtonImage = [self drawCloseButtonImageWithColor:_textColor]; + + _labelView.textColor = _textColor; + [_closeButton setImage:closeButtonImage forState:UIControlStateNormal]; +} - UIGraphicsBeginImageContextWithOptions(CGSizeMake(FBSDKCloseButtonWidth, FBSDKCloseButtonHeight), NO, 0.0f); +- (UIImage *)drawCloseButtonImageWithColor:(UIColor *)color +{ + UIGraphicsBeginImageContextWithOptions(CGSizeMake(FBSDKCloseButtonWidth, FBSDKCloseButtonHeight), NO, 0.0f); - CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetStrokeColorWithColor(context, color.CGColor); - CGContextSetFillColorWithColor(context, color.CGColor); + CGContextSetStrokeColorWithColor(context, color.CGColor); + CGContextSetFillColorWithColor(context, color.CGColor); - CGContextSetLineWidth(context, 1.25f); + CGContextSetLineWidth(context, 1.25f); - CGFloat inset = 0.5f; + CGFloat inset = 0.5f; - CGContextMoveToPoint(context, inset, inset); - CGContextAddLineToPoint(context, FBSDKCloseButtonWidth - inset, FBSDKCloseButtonHeight - inset); - CGContextStrokePath(context); + CGContextMoveToPoint(context, inset, inset); + CGContextAddLineToPoint(context, FBSDKCloseButtonWidth - inset, FBSDKCloseButtonHeight - inset); + CGContextStrokePath(context); - CGContextMoveToPoint(context, FBSDKCloseButtonWidth - inset, inset); - CGContextAddLineToPoint(context, inset, FBSDKCloseButtonHeight - inset); - CGContextStrokePath(context); + CGContextMoveToPoint(context, FBSDKCloseButtonWidth - inset, inset); + CGContextAddLineToPoint(context, inset, FBSDKCloseButtonHeight - inset); + CGContextStrokePath(context); - UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); + UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); - return result; + return result; } -- (NSString *)localizedLabelForReferer:(NSString *)refererName { - if (!refererName) { - return nil; - } +- (NSString *)localizedLabelForReferer:(NSString *)refererName +{ + if (!refererName) { + return nil; + } - NSString *format = NSLocalizedString(@"Touch to return to %1$@", @"Format for the string to return to a calling app."); - return [NSString stringWithFormat:format, refererName]; + NSString *format = NSLocalizedString(@"Touch to return to %1$@", @"Format for the string to return to a calling app."); + return [NSString stringWithFormat:format, refererName]; } -- (BOOL)hasRefererData { - return _refererAppLink && [FBSDKTypeUtility array:_refererAppLink.targets objectAtIndex:0]; +- (BOOL)hasRefererData +{ + return _refererAppLink && [FBSDKTypeUtility array:_refererAppLink.targets objectAtIndex:0]; } -- (void)closeButtonTapped:(id)sender { - [_delegate returnToRefererViewDidTapInsideCloseButton:self]; +- (void)closeButtonTapped:(id)sender +{ + [_delegate returnToRefererViewDidTapInsideCloseButton:self]; } -- (void)onTapInside:(UIGestureRecognizer *)sender { - [_delegate returnToRefererViewDidTapInsideLink:self link:_refererAppLink]; +- (void)onTapInside:(UIGestureRecognizer *)sender +{ + [_delegate returnToRefererViewDidTapInsideLink:self link:_refererAppLink]; } -- (void)updateHidden { - super.hidden = _explicitlyHidden || _closed || !self.hasRefererData; +- (void)updateHidden +{ + super.hidden = _explicitlyHidden || _closed || !self.hasRefererData; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkTarget.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkTarget.m index 0a98717c1e..7bc14d59dd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkTarget.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkTarget.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkTarget.h" + #import "FBSDKAppLinkTarget.h" @interface FBSDKAppLinkTarget () @@ -34,12 +34,13 @@ @implementation FBSDKAppLinkTarget + (instancetype)appLinkTargetWithURL:(NSURL *)url appStoreId:(NSString *)appStoreId - appName:(NSString *)appName { - FBSDKAppLinkTarget *target = [[self alloc] init]; - target.URL = url; - target.appStoreId = appStoreId; - target.appName = appName; - return target; + appName:(NSString *)appName +{ + FBSDKAppLinkTarget *target = [[self alloc] init]; + target.URL = url; + target.appStoreId = appStoreId; + target.appName = appName; + return target; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkUtility.m index 5944c567ff..9aabfbc338 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkUtility.m @@ -20,24 +20,33 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkUtility.h" + #import "FBSDKAppLinkUtility.h" -#import "FBSDKAppEventsUtility.h" -#import "FBSDKGraphRequest.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKSettings.h" -#import "FBSDKURL.h" -#import "FBSDKUtility.h" + #import "FBSDKAppEventsUtility.h" + #import "FBSDKGraphRequest.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKSettings.h" + #import "FBSDKURL.h" + #import "FBSDKUtility.h" static NSString *const FBSDKLastDeferredAppLink = @"com.facebook.sdk:lastDeferredAppLink%@"; static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK"; -@implementation FBSDKAppLinkUtility {} +@implementation FBSDKAppLinkUtility +{} + (void)fetchDeferredAppLink:(FBSDKURLBlock)handler { NSAssert([NSThread isMainThread], @"FBSDKAppLink fetchDeferredAppLink: must be invoked from main thread."); + if ([FBSDKAppEventsUtility shouldDropAppEvent]) { + if (handler) { + NSError *error = [[NSError alloc] initWithDomain:@"AdvertiserTrackingEnabled must be enabled" code:-1 userInfo:nil]; + handler(nil, error); + } + return; + } + NSString *appID = [FBSDKSettings appID]; // Deferred app links are only currently used for engagement ads, thus we consider the app to be an advertising one. @@ -56,30 +65,30 @@ + (void)fetchDeferredAppLink:(FBSDKURLBlock)handler [deferredAppLinkRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - NSURL *applinkURL = nil; - if (!error) { - NSString *appLinkString = result[@"applink_url"]; - if (appLinkString) { - applinkURL = [NSURL URLWithString:appLinkString]; - - NSString *createTimeUtc = result[@"click_time"]; - if (createTimeUtc) { - // append/translate the create_time_utc so it can be used by clients - NSString *modifiedURLString = [applinkURL.absoluteString - stringByAppendingFormat:@"%@fb_click_time_utc=%@", - (applinkURL.query) ? @"&" : @"?" , - createTimeUtc]; - applinkURL = [NSURL URLWithString:modifiedURLString]; - } - } - } - - if (handler) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(applinkURL, error); - }); - } - }]; + NSURL *applinkURL = nil; + if (!error) { + NSString *appLinkString = result[@"applink_url"]; + if (appLinkString) { + applinkURL = [NSURL URLWithString:appLinkString]; + + NSString *createTimeUtc = result[@"click_time"]; + if (createTimeUtc) { + // append/translate the create_time_utc so it can be used by clients + NSString *modifiedURLString = [applinkURL.absoluteString + stringByAppendingFormat:@"%@fb_click_time_utc=%@", + (applinkURL.query) ? @"&" : @"?", + createTimeUtc]; + applinkURL = [NSURL URLWithString:modifiedURLString]; + } + } + } + + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(applinkURL, error); + }); + } + }]; } + (NSString *)appInvitePromotionCodeFromURL:(NSURL *)url @@ -100,7 +109,6 @@ + (NSString *)appInvitePromotionCodeFromURL:(NSURL *)url } return nil; - } + (BOOL)isMatchURLScheme:(NSString *)scheme @@ -108,10 +116,9 @@ + (BOOL)isMatchURLScheme:(NSString *)scheme if (!scheme) { return NO; } - for(NSDictionary *urlType in [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"]) - { - for(NSString *urlScheme in urlType[@"CFBundleURLSchemes"]) { - if([urlScheme caseInsensitiveCompare:scheme] == NSOrderedSame) { + for (NSDictionary *urlType in [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"]) { + for (NSString *urlScheme in urlType[@"CFBundleURLSchemes"]) { + if ([urlScheme caseInsensitiveCompare:scheme] == NSOrderedSame) { return YES; } } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m index 18a60f9bec..1d02acf27e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m @@ -27,7 +27,7 @@ #import "FBSDKAppLink.h" #import "FBSDKAppLinkTarget.h" -#import "FBSDKTypeUtility.h" +#import "FBSDKInternalUtility.h" /** Describes the callback for appLinkFromURLInBackground. diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Internal/FBSDKMeasurementEventListener.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Internal/FBSDKMeasurementEventListener.m index 42f1fa9420..885947cbb9 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Internal/FBSDKMeasurementEventListener.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Internal/FBSDKMeasurementEventListener.m @@ -20,21 +20,11 @@ #if !TARGET_OS_TV -#import "FBSDKMeasurementEventListener.h" + #import "FBSDKMeasurementEventListener.h" -#import "FBSDKAppEvents+Internal.h" -#import "FBSDKTimeSpentData.h" -#import "FBSDKTypeUtility.h" - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -static NSNotificationName const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event"; - -#else - -static NSString *const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event"; - -#endif + #import "FBSDKAppEvents+Internal.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKTimeSpentData.h" static NSString *const FBSDKMeasurementEventName = @"event_name"; static NSString *const FBSDKMeasurementEventArgs = @"event_args"; @@ -44,48 +34,48 @@ @implementation FBSDKMeasurementEventListener + (instancetype)defaultListener { - static dispatch_once_t dispatchOnceLocker = 0; - static FBSDKMeasurementEventListener *defaultListener = nil; - dispatch_once(&dispatchOnceLocker, ^{ - defaultListener = [[self alloc] init]; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - [center addObserver:defaultListener - selector:@selector(logFBAppEventForNotification:) - name:FBSDKMeasurementEventNotification - object:nil]; - }); - return defaultListener; + static dispatch_once_t dispatchOnceLocker = 0; + static FBSDKMeasurementEventListener *defaultListener = nil; + dispatch_once(&dispatchOnceLocker, ^{ + defaultListener = [[self alloc] init]; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver:defaultListener + selector:@selector(logFBAppEventForNotification:) + name:FBSDKMeasurementEventNotification + object:nil]; + }); + return defaultListener; } - (void)logFBAppEventForNotification:(NSNotification *)note { - // when catch al_nav_in event, we set source application for FBAppEvents. - if ([note.userInfo[FBSDKMeasurementEventName] isEqualToString:@"al_nav_in"]) { - NSString *sourceApplication = note.userInfo[FBSDKMeasurementEventArgs][@"sourceApplication"]; - if (sourceApplication) { - [FBSDKTimeSpentData setSourceApplication:sourceApplication isFromAppLink:YES]; - } - } - NSDictionary *eventArgs = note.userInfo[FBSDKMeasurementEventArgs]; - NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; - for (NSString *key in eventArgs.allKeys) { - NSError *error = nil; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9a-zA-Z _-]" options:0 error:&error]; - NSString *safeKey = [regex stringByReplacingMatchesInString:key - options:0 - range:NSMakeRange(0, key.length) - withTemplate:@"-"]; - safeKey = [safeKey stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -"]]; - [FBSDKTypeUtility dictionary:logData setObject:eventArgs[key] forKey:safeKey]; + // when catch al_nav_in event, we set source application for FBAppEvents. + if ([note.userInfo[FBSDKMeasurementEventName] isEqualToString:@"al_nav_in"]) { + NSString *sourceApplication = note.userInfo[FBSDKMeasurementEventArgs][@"sourceApplication"]; + if (sourceApplication) { + [FBSDKTimeSpentData setSourceApplication:sourceApplication isFromAppLink:YES]; } - [FBSDKAppEvents logInternalEvent:[FBSDKMeasurementEventPrefix stringByAppendingString:note.userInfo[FBSDKMeasurementEventName]] - parameters:logData - isImplicitlyLogged:YES]; + } + NSDictionary *eventArgs = note.userInfo[FBSDKMeasurementEventArgs]; + NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; + for (NSString *key in eventArgs.allKeys) { + NSError *error = nil; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9a-zA-Z _-]" options:0 error:&error]; + NSString *safeKey = [regex stringByReplacingMatchesInString:key + options:0 + range:NSMakeRange(0, key.length) + withTemplate:@"-"]; + safeKey = [safeKey stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -"]]; + [FBSDKTypeUtility dictionary:logData setObject:eventArgs[key] forKey:safeKey]; + } + [FBSDKAppEvents logInternalEvent:[FBSDKMeasurementEventPrefix stringByAppendingString:note.userInfo[FBSDKMeasurementEventName]] + parameters:logData + isImplicitlyLogged:YES]; } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap b/FBSDKCoreKit/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap deleted file mode 100644 index dfbaae6eb1..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/FBSDKCoreKit.modulemap +++ /dev/null @@ -1,6 +0,0 @@ -framework module FBSDKCoreKit { - umbrella header "FBSDKBasicUtility.h" - - export * - module * { export * } -} diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m index 8055aec42a..969e5d598c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessToken.h" +#import "FBSDKAccessToken+Internal.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKInternalUtility.h" @@ -56,25 +57,25 @@ @implementation FBSDKAccessToken - (instancetype)initWithTokenString:(NSString *)tokenString permissions:(NSArray *)permissions declinedPermissions:(NSArray *)declinedPermissions - expiredPermissions:(NSArray *)expiredPermissions + expiredPermissions:(NSArray *)expiredPermissions appID:(NSString *)appID userID:(NSString *)userID expirationDate:(NSDate *)expirationDate refreshDate:(NSDate *)refreshDate dataAccessExpirationDate:(NSDate *)dataAccessExpirationDate { - if ((self = [super init])) { - _tokenString = [tokenString copy]; - _permissions = [NSSet setWithArray:permissions]; - _declinedPermissions = [NSSet setWithArray:declinedPermissions]; - _expiredPermissions = [NSSet setWithArray:expiredPermissions]; - _appID = [appID copy]; - _userID = [userID copy]; - _expirationDate = [expirationDate copy] ?: [NSDate distantFuture]; - _refreshDate = [refreshDate copy] ?: [NSDate date]; - _dataAccessExpirationDate = [dataAccessExpirationDate copy] ?: [NSDate distantFuture]; - } - return self; + if ((self = [super init])) { + _tokenString = [tokenString copy]; + _permissions = [NSSet setWithArray:permissions]; + _declinedPermissions = [NSSet setWithArray:declinedPermissions]; + _expiredPermissions = [NSSet setWithArray:expiredPermissions]; + _appID = [appID copy]; + _userID = [userID copy]; + _expirationDate = [expirationDate copy] ?: [NSDate distantFuture]; + _refreshDate = [refreshDate copy] ?: [NSDate date]; + _dataAccessExpirationDate = [dataAccessExpirationDate copy] ?: [NSDate distantFuture]; + } + return self; } - (instancetype)initWithTokenString:(NSString *)tokenString @@ -110,12 +111,11 @@ - (instancetype)initWithTokenString:(NSString *)tokenString - (BOOL)hasGranted:(NSString *)permission { return [self.permissions containsObject:permission]; - } - (BOOL)isDataAccessExpired { - return [self.dataAccessExpirationDate compare:NSDate.date] == NSOrderedAscending; + return [self.dataAccessExpirationDate compare:NSDate.date] == NSOrderedAscending; } - (BOOL)isExpired @@ -129,6 +129,12 @@ + (FBSDKAccessToken *)currentAccessToken } + (void)setCurrentAccessToken:(FBSDKAccessToken *)token +{ + [FBSDKAccessToken setCurrentAccessToken:token shouldDispatchNotif:YES]; +} + ++ (void)setCurrentAccessToken:(FBSDKAccessToken *)token + shouldDispatchNotif:(BOOL)shouldDispatchNotif { if (token != g_currentAccessToken) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; @@ -148,9 +154,11 @@ + (void)setCurrentAccessToken:(FBSDKAccessToken *)token } [FBSDKSettings accessTokenCache].accessToken = token; - [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAccessTokenDidChangeNotification - object:[self class] - userInfo:userInfo]; + if (shouldDispatchNotif) { + [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAccessTokenDidChangeNotification + object:[self class] + userInfo:userInfo]; + } } } @@ -167,9 +175,13 @@ + (void)refreshCurrentAccessToken:(FBSDKGraphRequestBlock)completionHandler [FBSDKGraphRequestPiggybackManager addRefreshPiggyback:connection permissionHandler:completionHandler]; [connection start]; } else if (completionHandler) { - completionHandler(nil, nil, [FBSDKError - errorWithCode:FBSDKErrorAccessTokenRequired - message:@"No current access token to refresh"]); + completionHandler( + nil, + nil, + [FBSDKError + errorWithCode:FBSDKErrorAccessTokenRequired + message:@"No current access token to refresh"] + ); } } @@ -205,17 +217,17 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToAccessToken:(FBSDKAccessToken *)token { - return (token && - [FBSDKInternalUtility object:self.tokenString isEqualToObject:token.tokenString] && - [FBSDKInternalUtility object:self.permissions isEqualToObject:token.permissions] && - [FBSDKInternalUtility object:self.declinedPermissions isEqualToObject:token.declinedPermissions] && - [FBSDKInternalUtility object:self.expiredPermissions isEqualToObject:token.expiredPermissions] && - [FBSDKInternalUtility object:self.appID isEqualToObject:token.appID] && - [FBSDKInternalUtility object:self.userID isEqualToObject:token.userID] && - [FBSDKInternalUtility object:self.refreshDate isEqualToObject:token.refreshDate] && - [FBSDKInternalUtility object:self.expirationDate isEqualToObject:token.expirationDate] && - [FBSDKInternalUtility object:self.dataAccessExpirationDate isEqualToObject:token.dataAccessExpirationDate] && - [FBSDKInternalUtility object:self.graphDomain isEqualToObject:token.graphDomain]); + return (token + && [FBSDKInternalUtility object:self.tokenString isEqualToObject:token.tokenString] + && [FBSDKInternalUtility object:self.permissions isEqualToObject:token.permissions] + && [FBSDKInternalUtility object:self.declinedPermissions isEqualToObject:token.declinedPermissions] + && [FBSDKInternalUtility object:self.expiredPermissions isEqualToObject:token.expiredPermissions] + && [FBSDKInternalUtility object:self.appID isEqualToObject:token.appID] + && [FBSDKInternalUtility object:self.userID isEqualToObject:token.userID] + && [FBSDKInternalUtility object:self.refreshDate isEqualToObject:token.refreshDate] + && [FBSDKInternalUtility object:self.expirationDate isEqualToObject:token.expirationDate] + && [FBSDKInternalUtility object:self.dataAccessExpirationDate isEqualToObject:token.dataAccessExpirationDate] + && [FBSDKInternalUtility object:self.graphDomain isEqualToObject:token.graphDomain]); } #pragma mark - NSCopying diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m index 3d62cddd3e..29d2afa94c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m @@ -37,9 +37,9 @@ #import "FBSDKTimeSpentData.h" #if !TARGET_OS_TV -#import "FBSDKMeasurementEventListener.h" -#import "FBSDKContainerViewController.h" -#import "FBSDKProfile+Internal.h" + #import "FBSDKContainerViewController.h" + #import "FBSDKMeasurementEventListener.h" + #import "FBSDKProfile+Internal.h" #endif #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 @@ -53,7 +53,8 @@ #endif static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound"; -static NSString *const FBSDKKitsBitmaskKey = @"com.facebook.sdk.kits.bitmask"; +static NSString *const FBSDKKitsBitmaskKey = @"com.facebook.sdk.kits.bitmask"; +static NSString *const FBSDKAutoInitLaunchArgument = @"_calledFromAutoInitSDK"; static BOOL g_isSDKInitialized = NO; static UIApplicationState _applicationState; @@ -67,7 +68,10 @@ @implementation FBSDKApplicationDelegate + (void)load { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" if ([FBSDKSettings isAutoInitEnabled]) { + #pragma clang diagnostic pop // when the app becomes active by any means, kick off the initialization. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initializeWithLaunchData:) @@ -87,24 +91,35 @@ + (void)initializeWithLaunchData:(NSNotification *)note object:nil]; } -+ (void)initializeSDK:(NSDictionary *)launchOptions ++ (void)initializeSDK:(NSDictionary *)launchOptions { if (g_isSDKInitialized) { - // Do nothing if initialized already + // Do nothing if initialized already return; } g_isSDKInitialized = YES; FBSDKApplicationDelegate *delegate = [self sharedInstance]; + [FBSDKSettings recordInstall]; NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter addObserver:delegate selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [defaultCenter addObserver:delegate selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; + [defaultCenter addObserver:delegate selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil]; [[FBSDKAppEvents singleton] registerNotifications]; - [delegate application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchOptions]; + NSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions]; + [FBSDKTypeUtility dictionary:modifiedLaunchOptions setObject:@YES forKey:FBSDKAutoInitLaunchArgument]; + [delegate application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:modifiedLaunchOptions]; + + // In case of sdk autoInit enabled sdk expects one appDidBecomeActive notification after app launch and has some logic to ignore it. + // if sdk autoInit disabled app won't receive appDidBecomeActive on app launch and will ignore the first one it gets instead of handling it. + // Send first applicationDidBecomeActive notification manually + if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { + [delegate applicationDidBecomeActive:nil]; + } [FBSDKFeatureManager checkFeature:FBSDKFeatureInstrument completionBlock:^(BOOL enabled) { if (enabled) { @@ -114,9 +129,9 @@ + (void)initializeSDK:(NSDictionary *)launchOp [FBSDKFeatureManager checkFeature:FBSDKFeatureMonitoring completionBlock:^(BOOL enabled) { if (enabled && FBSDKSettings.isAutoLogAppEventsEnabled) { -#ifndef DEBUG + #ifndef DEBUG [FBSDKMonitor enable]; -#endif + #endif } }]; @@ -156,25 +171,26 @@ - (instancetype)init - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - UIApplicationDelegate -#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_9_0 +#if __IPHONE_OS_VERSION_MAX_ALLOWED> __IPHONE_9_0 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url - options:(NSDictionary *)options + options:(NSDictionary *)options { - if (@available(iOS 9.0, *)) { - return [self application:application - openURL:url - sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] - annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; - } + if (@available(iOS 9.0, *)) { + return [self application:application + openURL:url + sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] + annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; + } - return NO; + return NO; } + #endif - (BOOL)application:(UIApplication *)application @@ -213,22 +229,37 @@ - (BOOL)application:(UIApplication *)application - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - if ([self isAppLaunched]) { - return NO; - } + if ([[FBSDKTypeUtility dictionary:launchOptions objectForKey:FBSDKAutoInitLaunchArgument ofType:NSNumber.class] boolValue]) { + // Clean the flag out of launch options + NSMutableDictionary *originalLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions]; + [originalLaunchOptions removeObjectForKey:FBSDKAutoInitLaunchArgument]; + launchOptions = [originalLaunchOptions copy]; + } else { + // Log because it was not called by autoInit + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameImplementsApplicationDidFinishLaunching + parameters:@{} + isImplicitlyLogged:YES]; + #pragma clang diagnostic pop + } - _isAppLaunched = YES; - FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken; - [FBSDKAccessToken setCurrentAccessToken:cachedToken]; - // fetch app settings - [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; + if (_isAppLaunched) { + return NO; + } - if (FBSDKSettings.isAutoLogAppEventsEnabled) { - [self _logSDKInitialize]; - } + _isAppLaunched = YES; + FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken; + [FBSDKAccessToken setCurrentAccessToken:cachedToken]; + // fetch app settings + [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; + + if (FBSDKSettings.isAutoLogAppEventsEnabled) { + [self _logSDKInitialize]; + } #if !TARGET_OS_TV - FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile]; - [FBSDKProfile setCurrentProfile:cachedProfile]; + FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile]; + [FBSDKProfile setCurrentProfile:cachedProfile]; #endif NSArray> *observers = [_applicationObservers allObjects]; BOOL handled = NO; @@ -261,6 +292,9 @@ - (void)applicationDidBecomeActive:(NSNotification *)notification if (FBSDKSettings.isAutoLogAppEventsEnabled) { [FBSDKAppEvents activateApp]; } +#if !TARGET_OS_TV + [FBSDKSKAdNetworkReporter checkAndRevokeTimer]; +#endif NSArray> *observers = [_applicationObservers copy]; for (id observer in observers) { @@ -270,6 +304,17 @@ - (void)applicationDidBecomeActive:(NSNotification *)notification } } +- (void)applicationWillResignActive:(NSNotification *)notification +{ + _applicationState = UIApplicationStateInactive; + NSArray> *const observers = [_applicationObservers copy]; + for (id observer in observers) { + if ([observer respondsToSelector:@selector(applicationWillResignActive:)]) { + [observer applicationWillResignActive:notification.object]; + } + } +} + #pragma mark - Internal Methods #pragma mark - FBSDKApplicationObserving @@ -306,7 +351,7 @@ - (void)_logIfAppLinkEvent:(NSURL *)url return; } - NSDictionary *applinkData = [FBSDKBasicUtility objectForJSONString:applinkDataString error:NULL]; + NSDictionary *applinkData = [FBSDKTypeUtility dictionaryValue:[FBSDKBasicUtility objectForJSONString:applinkDataString error:NULL]]; if (!applinkData) { return; } @@ -355,7 +400,7 @@ - (void)_logSDKInitialize NSString *keyName = [FBSDKTypeUtility dictionary:metaInfo objectForKey:className ofType:NSObject.class]; if (objc_lookUpClass([className UTF8String])) { [FBSDKTypeUtility dictionary:params setObject:@1 forKey:keyName]; - bitmask |= 1 << bit; + bitmask |= 1 << bit; } bit++; } @@ -405,27 +450,53 @@ - (void)_logSwiftRuntimeAvailability if (!params[swiftUsageKey].boolValue) { double delayInSeconds = 1.0; dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(delay, dispatch_get_main_queue(), ^{ - UIViewController *topMostViewController = [FBSDKInternalUtility topMostViewController]; - NSString const *vcClassName = NSStringFromClass([topMostViewController class]); - if ([vcClassName componentsSeparatedByString:@"."].count > 1) { - params[swiftUsageKey] = @YES; - [FBSDKAppEvents logInternalEvent:eventName - parameters:params - isImplicitlyLogged:NO]; - } - }); - }; + dispatch_after(delay, + dispatch_get_main_queue(), ^{ + UIViewController *topMostViewController = [FBSDKInternalUtility topMostViewController]; + NSString const *vcClassName = NSStringFromClass([topMostViewController class]); + if ([vcClassName componentsSeparatedByString:@"."].count > 1) { + params[swiftUsageKey] = @YES; + [FBSDKAppEvents logInternalEvent:eventName + parameters:params + isImplicitlyLogged:NO]; + } + }); + } + ; } + (BOOL)isSDKInitialized { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" return [FBSDKSettings isAutoInitEnabled] || g_isSDKInitialized; + #pragma clange diagnostic pop } -// Wrapping this makes it mockable and enables testability -- (BOOL)isAppLaunched { +// MARK: - Testability + +#if DEBUG + +- (BOOL)isAppLaunched +{ return _isAppLaunched; } +- (void)setIsAppLaunched:(BOOL)isLaunched +{ + _isAppLaunched = isLaunched; +} + +- (NSHashTable> *)applicationObservers +{ + return _applicationObservers; +} + +- (void)resetApplicationObserverCache +{ + _applicationObservers = [NSHashTable new]; +} + +#endif + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m index 10b073f60f..699353af81 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m @@ -20,8 +20,8 @@ #import "FBSDKButton+Subclass.h" #import "FBSDKAccessToken.h" -#import "FBSDKAppEvents+Internal.h" #import "FBSDKAppEvents.h" +#import "FBSDKAppEvents+Internal.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKLogo.h" #import "FBSDKUIUtility.h" @@ -147,10 +147,12 @@ - (CGRect)titleRectForContentRect:(CGRect)contentRect // to keep the text centered in the button without adding extra blank space to the right when unnecessary // 1. the text fits centered within the button without colliding with the image (imagePaddingWidth) // 2. the text would run into the image, so adjust the insets to effectively left align it (textPaddingWidth) - CGSize titleSize = FBSDKTextSize(titleLabel.text, - titleLabel.font, - titleRect.size, - titleLabel.lineBreakMode); + CGSize titleSize = FBSDKTextSize( + titleLabel.text, + titleLabel.font, + titleRect.size, + titleLabel.lineBreakMode + ); CGFloat titlePaddingWidth = (CGRectGetWidth(titleRect) - titleSize.width) / 2; CGFloat imagePaddingWidth = titleX / 2; CGFloat inset = MIN(titlePaddingWidth, imagePaddingWidth); @@ -196,42 +198,42 @@ - (void)configureWithIcon:(FBSDKIcon *)icon highlightedColor:(UIColor *)highlightedColor { [self _configureWithIcon:icon - title:title - backgroundColor:backgroundColor - highlightedColor:highlightedColor - selectedTitle:nil - selectedIcon:nil - selectedColor:nil - selectedHighlightedColor:nil]; + title:title + backgroundColor:backgroundColor + highlightedColor:highlightedColor + selectedTitle:nil + selectedIcon:nil + selectedColor:nil + selectedHighlightedColor:nil]; } -- (void)configureWithIcon:(FBSDKIcon *)icon - title:(NSString *)title - backgroundColor:(UIColor *)backgroundColor - highlightedColor:(UIColor *)highlightedColor - selectedTitle:(NSString *)selectedTitle - selectedIcon:(FBSDKIcon *)selectedIcon - selectedColor:(UIColor *)selectedColor - selectedHighlightedColor:(UIColor *)selectedHighlightedColor +- (void) configureWithIcon:(FBSDKIcon *)icon + title:(NSString *)title + backgroundColor:(UIColor *)backgroundColor + highlightedColor:(UIColor *)highlightedColor + selectedTitle:(NSString *)selectedTitle + selectedIcon:(FBSDKIcon *)selectedIcon + selectedColor:(UIColor *)selectedColor + selectedHighlightedColor:(UIColor *)selectedHighlightedColor { [self _configureWithIcon:icon - title:title - backgroundColor:backgroundColor - highlightedColor:highlightedColor - selectedTitle:selectedTitle - selectedIcon:selectedIcon - selectedColor:selectedColor - selectedHighlightedColor:selectedHighlightedColor]; + title:title + backgroundColor:backgroundColor + highlightedColor:highlightedColor + selectedTitle:selectedTitle + selectedIcon:selectedIcon + selectedColor:selectedColor + selectedHighlightedColor:selectedHighlightedColor]; } - (UIColor *)defaultBackgroundColor { - return [UIColor colorWithRed:24.0/255.0 green:119.0/255.0 blue:242.0/255.0 alpha:1.0]; + return [UIColor colorWithRed:24.0 / 255.0 green:119.0 / 255.0 blue:242.0 / 255.0 alpha:1.0]; } - (UIColor *)defaultDisabledColor { - return [UIColor colorWithRed:189.0/255.0 green:193.0/255.0 blue:201.0/255.0 alpha:1.0]; + return [UIColor colorWithRed:189.0 / 255.0 green:193.0 / 255.0 blue:201.0 / 255.0 alpha:1.0]; } - (UIFont *)defaultFont @@ -241,7 +243,7 @@ - (UIFont *)defaultFont - (UIColor *)defaultHighlightedColor { - return [UIColor colorWithRed:21.0/255.0 green:105.0/255.0 blue:214.0/255.0 alpha:1.0]; + return [UIColor colorWithRed:21.0 / 255.0 green:105.0 / 255.0 blue:214.0 / 255.0 alpha:1.0]; } - (FBSDKIcon *)defaultIcon @@ -256,7 +258,7 @@ - (UIColor *)defaultSelectedColor - (UIColor *)highlightedContentColor { - return [UIColor colorWithRed:218.0/255.0 green:221.0/255.0 blue:226.0/255.0 alpha:1.0]; + return [UIColor colorWithRed:218.0 / 255.0 green:221.0 / 255.0 blue:226.0 / 255.0 alpha:1.0]; } - (BOOL)isImplicitlyDisabled @@ -378,13 +380,13 @@ - (void)_configureWithIcon:(FBSDKIcon *)icon if (selectedHighlightedColor) { backgroundImage = [self _backgroundImageWithColor:selectedHighlightedColor cornerRadius:3.0 scale:scale]; [self setBackgroundImage:backgroundImage forState:UIControlStateSelected | UIControlStateHighlighted]; -#if TARGET_OS_TV + #if TARGET_OS_TV [self setBackgroundImage:backgroundImage forState:UIControlStateSelected | UIControlStateFocused]; -#endif + #endif } [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; - [self setTitleColor:[self highlightedContentColor] forState: UIControlStateHighlighted | UIControlStateSelected]; + [self setTitleColor:[self highlightedContentColor] forState:UIControlStateHighlighted | UIControlStateSelected]; [self setTitle:title forState:UIControlStateNormal]; #if TARGET_OS_TV @@ -393,9 +395,9 @@ - (void)_configureWithIcon:(FBSDKIcon *)icon if (selectedTitle) { [self setTitle:selectedTitle forState:UIControlStateSelected]; [self setTitle:selectedTitle forState:UIControlStateSelected | UIControlStateHighlighted]; -#if TARGET_OS_TV + #if TARGET_OS_TV [self setTitle:selectedTitle forState:UIControlStateSelected | UIControlStateFocused]; -#endif + #endif } UILabel *titleLabel = self.titleLabel; @@ -417,9 +419,9 @@ - (void)_configureWithIcon:(FBSDKIcon *)icon resizingMode:UIImageResizingModeStretch]; [self setImage:selectedImage forState:UIControlStateSelected]; [self setImage:selectedImage forState:UIControlStateSelected | UIControlStateHighlighted]; -#if TARGET_OS_TV + #if TARGET_OS_TV [self setImage:selectedImage forState:UIControlStateSelected | UIControlStateFocused]; -#endif + #endif } if (forceSizeToFit) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m index 756a122d7c..b3630268d1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m @@ -28,7 +28,6 @@ #endif - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSErrorUserInfoKey const FBSDKErrorArgumentCollectionKey = @"com.facebook.sdk:FBSDKErrorArgumentCollectionKey"; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 77be032ac2..594774e1fb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -18,77 +18,83 @@ #import +#if TARGET_OS_TV + #ifndef DEVICE_SHARING_DEPRECATED + #define DEVICE_SHARING_DEPRECATED DEPRECATED_MSG_ATTRIBUTE("Sharing from devices will no longer work as of Nov 2nd 2020") + #endif +#endif + #ifdef BUCK -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import -#if !TARGET_OS_TV -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#else -#import -#import -#endif + #if !TARGET_OS_TV + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #else + #import + #import + #endif #else -#import "FBSDKAccessToken.h" -#import "FBSDKAppEvents.h" -#import "FBSDKApplicationDelegate.h" -#import "FBSDKButton.h" -#import "FBSDKConstants.h" -#import "FBSDKCopying.h" -#import "FBSDKGraphRequest.h" -#import "FBSDKGraphRequestConnection.h" -#import "FBSDKGraphRequestDataAttachment.h" -#import "FBSDKSettings.h" -#import "FBSDKTestUsersManager.h" -#import "FBSDKUtility.h" + #import "FBSDKAccessToken.h" + #import "FBSDKAppEvents.h" + #import "FBSDKApplicationDelegate.h" + #import "FBSDKButton.h" + #import "FBSDKConstants.h" + #import "FBSDKCopying.h" + #import "FBSDKGraphRequest.h" + #import "FBSDKGraphRequestConnection.h" + #import "FBSDKGraphRequestDataAttachment.h" + #import "FBSDKSettings.h" + #import "FBSDKTestUsersManager.h" + #import "FBSDKUtility.h" -#if !TARGET_OS_TV -#import "FBSDKAppLink.h" -#import "FBSDKAppLinkNavigation.h" -#import "FBSDKAppLinkResolver.h" -#import "FBSDKAppLinkResolving.h" -#import "FBSDKAppLinkReturnToRefererController.h" -#import "FBSDKAppLinkReturnToRefererView.h" -#import "FBSDKAppLinkTarget.h" -#import "FBSDKAppLinkUtility.h" -#import "FBSDKGraphErrorRecoveryProcessor.h" -#import "FBSDKMeasurementEvent.h" -#import "FBSDKMutableCopying.h" -#import "FBSDKProfile.h" -#import "FBSDKProfilePictureView.h" -#import "FBSDKURL.h" -#import "FBSDKWebViewAppLinkResolver.h" -#else -#import "FBSDKDeviceButton.h" -#import "FBSDKDeviceViewControllerBase.h" -#endif + #if !TARGET_OS_TV + #import "FBSDKAppLink.h" + #import "FBSDKAppLinkNavigation.h" + #import "FBSDKAppLinkResolver.h" + #import "FBSDKAppLinkResolving.h" + #import "FBSDKAppLinkReturnToRefererController.h" + #import "FBSDKAppLinkReturnToRefererView.h" + #import "FBSDKAppLinkTarget.h" + #import "FBSDKAppLinkUtility.h" + #import "FBSDKGraphErrorRecoveryProcessor.h" + #import "FBSDKMeasurementEvent.h" + #import "FBSDKMutableCopying.h" + #import "FBSDKProfile.h" + #import "FBSDKProfilePictureView.h" + #import "FBSDKURL.h" + #import "FBSDKWebViewAppLinkResolver.h" + #else + #import "FBSDKDeviceButton.h" + #import "FBSDKDeviceViewControllerBase.h" + #endif #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceButton.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceButton.m index 383dd42c95..0a888c5d16 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceButton.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceButton.m @@ -20,11 +20,11 @@ #if TARGET_OS_TV -#import "FBSDKDeviceButton.h" + #import "FBSDKDeviceButton.h" -#import + #import -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" static const CGFloat kFBLogoSize = 54.0; static const CGFloat kFBLogoLeftMargin = 36.0; @@ -33,7 +33,7 @@ @implementation FBSDKDeviceButton -#pragma mark - Layout + #pragma mark - Layout - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator { @@ -41,14 +41,14 @@ - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoo if (self == context.nextFocusedView) { [coordinator addCoordinatedAnimations:^{ - self.transform = CGAffineTransformMakeScale(1.05, 1.05); - self.layer.shadowOpacity = 0.5; - } completion:NULL]; + self.transform = CGAffineTransformMakeScale(1.05, 1.05); + self.layer.shadowOpacity = 0.5; + } completion:NULL]; } else if (self == context.previouslyFocusedView) { [coordinator addCoordinatedAnimations:^{ - self.transform = CGAffineTransformMakeScale(1.0, 1.0); - self.layer.shadowOpacity = 0; - } completion:NULL]; + self.transform = CGAffineTransformMakeScale(1.0, 1.0); + self.layer.shadowOpacity = 0; + } completion:NULL]; } } @@ -70,11 +70,11 @@ - (CGRect)titleRectForContentRect:(CGRect)contentRect if (!self.layer.needsLayout) { CGSize titleSize = [FBSDKMath ceilForSize:[self.titleLabel.attributedText boundingRectWithSize:contentRect.size - options:(NSStringDrawingUsesDeviceMetrics | - NSStringDrawingUsesLineFragmentOrigin | - NSStringDrawingUsesFontLeading) + options:(NSStringDrawingUsesDeviceMetrics + | NSStringDrawingUsesLineFragmentOrigin + | NSStringDrawingUsesFontLeading) context:NULL].size]; - CGFloat titlePadding = ( CGRectGetWidth(rect) - titleSize.width ) / 2; + CGFloat titlePadding = (CGRectGetWidth(rect) - titleSize.width) / 2; if (titlePadding > titleX) { // if there's room to re-center the text, do so. rect = CGRectMake(kRightMargin, 0, CGRectGetWidth(contentRect) - kRightMargin - kRightMargin, CGRectGetHeight(contentRect)); @@ -84,7 +84,7 @@ - (CGRect)titleRectForContentRect:(CGRect)contentRect return rect; } -#pragma mark - FBSDKButton + #pragma mark - FBSDKButton - (UIFont *)defaultFont { @@ -94,14 +94,16 @@ - (UIFont *)defaultFont - (CGSize)sizeThatFits:(CGSize)size attributedTitle:(NSAttributedString *)title { CGSize titleSize = [FBSDKMath ceilForSize:[title boundingRectWithSize:size - options:(NSStringDrawingUsesDeviceMetrics | - NSStringDrawingUsesLineFragmentOrigin | - NSStringDrawingUsesFontLeading) + options:(NSStringDrawingUsesDeviceMetrics + | NSStringDrawingUsesLineFragmentOrigin + | NSStringDrawingUsesFontLeading) context:NULL].size]; CGFloat logoAndTitleWidth = kFBLogoSize + kPreferredPaddingBetweenLogoTitle + titleSize.width + kPreferredPaddingBetweenLogoTitle; CGFloat height = 108; - CGSize contentSize = CGSizeMake(kFBLogoLeftMargin + logoAndTitleWidth + kRightMargin, - height); + CGSize contentSize = CGSizeMake( + kFBLogoLeftMargin + logoAndTitleWidth + kRightMargin, + height + ); return contentSize; } @@ -110,7 +112,7 @@ - (CGSize)sizeThatFits:(CGSize)size title:(NSString *)title return [self sizeThatFits:size attributedTitle:[self attributedTitleStringFromString:title]]; } -#pragma mark - Subclasses + #pragma mark - Subclasses - (NSAttributedString *)attributedTitleStringFromString:(NSString *)string { @@ -123,10 +125,10 @@ - (NSAttributedString *)attributedTitleStringFromString:(NSString *)string NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:@{ - NSParagraphStyleAttributeName: style, - NSFontAttributeName: [self defaultFont], - NSForegroundColorAttributeName: [UIColor whiteColor] - }]; + NSParagraphStyleAttributeName : style, + NSFontAttributeName : [self defaultFont], + NSForegroundColorAttributeName : [UIColor whiteColor] + }]; // Now find all the spaces and widen their kerning. NSRange range = NSMakeRange(0, string.length); while (range.location != NSNotFound) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceViewControllerBase.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceViewControllerBase.m index be6ed4906f..0c638201dd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceViewControllerBase.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKDeviceViewControllerBase.m @@ -20,12 +20,11 @@ #if TARGET_OS_TV -#import "FBSDKDeviceViewControllerBase+Internal.h" + #import "FBSDKDeviceViewControllerBase+Internal.h" -#import "FBSDKCoreKit+Internal.h" - -#import "FBSDKSmartDeviceDialogView.h" -#import "FBSDKModalFormPresentationController.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKModalFormPresentationController.h" + #import "FBSDKSmartDeviceDialogView.h" static const NSTimeInterval kAnimationDurationTimeInterval = .5; @@ -50,9 +49,9 @@ - (void)loadView CGRect frame = [UIScreen mainScreen].bounds; BOOL smartLoginEnabled = ([FBSDKServerConfigurationManager cachedServerConfiguration].smartLoginOptions & FBSDKServerConfigurationSmartLoginOptionsEnabled); FBSDKDeviceDialogView *deviceView = - (smartLoginEnabled ? - [[FBSDKSmartDeviceDialogView alloc] initWithFrame:frame] : - [[FBSDKDeviceDialogView alloc] initWithFrame:frame] ); + (smartLoginEnabled + ? [[FBSDKSmartDeviceDialogView alloc] initWithFrame:frame] + : [[FBSDKDeviceDialogView alloc] initWithFrame:frame]); deviceView.delegate = self; self.view = deviceView; } @@ -62,7 +61,7 @@ - (FBSDKDeviceDialogView *)deviceDialogView return (FBSDKDeviceDialogView *)self.view; } -#pragma mark - UIViewControllerAnimatedTransitioning + #pragma mark - UIViewControllerAnimatedTransitioning // Extract this out to another class if we have other similar transitions. - (NSTimeInterval)transitionDuration:(id)transitionContext @@ -104,7 +103,7 @@ - (void)animateTransition:(id)transitionCo } } -#pragma mark - UIViewControllerTransitioningDelegate + #pragma mark - UIViewControllerTransitioningDelegate - (id)animationControllerForDismissedController:(UIViewController *)dismissed { @@ -124,12 +123,13 @@ - (UIPresentationController *)presentationControllerForPresentedViewController:( presentingViewController:presenting]; } -#pragma mark - FBSDKDeviceDialogViewDelegate + #pragma mark - FBSDKDeviceDialogViewDelegate - (void)deviceDialogViewDidCancel:(FBSDKDeviceDialogView *)deviceDialogView { [self dismissViewControllerAnimated:YES completion:NULL]; } + @end #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKMeasurementEvent.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKMeasurementEvent.m index e678777dd6..363813b6a3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKMeasurementEvent.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKMeasurementEvent.m @@ -20,20 +20,19 @@ #if !TARGET_OS_TV -#import "FBSDKMeasurementEvent_Internal.h" + #import "FBSDKLogger.h" + #import "FBSDKMeasurementEvent_Internal.h" + #import "FBSDKSettings.h" -#import "FBSDKLogger.h" -#import "FBSDKSettings.h" - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSNotificationName const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event"; -#else + #else NSString *const FBSDKMeasurementEventNotification = @"com.facebook.facebook-objc-sdk.measurement_event"; -#endif + #endif NSString *const FBSDKMeasurementEventNotificationName = @"com.facebook.facebook-objc-sdk.measurement_event"; @@ -48,39 +47,43 @@ NSString *const FBSDKAppLinkNavigateOutEventName = @"al_nav_out"; NSString *const FBSDKAppLinkNavigateBackToReferrerEventName = @"al_ref_back_out"; -@implementation FBSDKMeasurementEvent { - NSString *_name; - NSDictionary *_args; +@implementation FBSDKMeasurementEvent +{ + NSString *_name; + NSDictionary *_args; } -- (void)postNotification { - if (!_name) { - [FBSDKLogger - singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors - logEntry:@"Warning: Missing event name when logging FBSDK measurement event.\nIgnoring this event in logging."]; - return; - } - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - NSDictionary *userInfo = @{FBSDKMeasurementEventNameKey : _name, - FBSDKMeasurementEventArgsKey : _args}; - - [center postNotificationName:FBSDKMeasurementEventNotification - object:self - userInfo:userInfo]; +- (void)postNotification +{ + if (!_name) { + [FBSDKLogger + singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + logEntry:@"Warning: Missing event name when logging FBSDK measurement event.\nIgnoring this event in logging."]; + return; + } + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + NSDictionary *userInfo = @{FBSDKMeasurementEventNameKey : _name, + FBSDKMeasurementEventArgsKey : _args}; + + [center postNotificationName:FBSDKMeasurementEventNotification + object:self + userInfo:userInfo]; } - (instancetype)initEventWithName:(NSString *)name - args:(NSDictionary *)args { - if ((self = [super init])) { - _name = name; - _args = args ? args : @{}; - } - return self; + args:(NSDictionary *)args +{ + if ((self = [super init])) { + _name = name; + _args = args ? args : @{}; + } + return self; } + (void)postNotificationForEventName:(NSString *)name - args:(NSDictionary *)args { - [[[self alloc] initEventWithName:name args:args] postNotification]; + args:(NSDictionary *)args +{ + [[[self alloc] initEventWithName:name args:args] postNotification]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index a3930e48af..405938ea81 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -20,35 +20,35 @@ #if !TARGET_OS_TV -#import "FBSDKProfile+Internal.h" + #import "FBSDKProfile+Internal.h" -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSNotificationName const FBSDKProfileDidChangeNotification = @"com.facebook.sdk.FBSDKProfile.FBSDKProfileDidChangeNotification";; -#else + #else NSString *const FBSDKProfileDidChangeNotification = @"com.facebook.sdk.FBSDKProfile.FBSDKProfileDidChangeNotification";; -#endif + #endif NSString *const FBSDKProfileChangeOldKey = @"FBSDKProfileOld"; NSString *const FBSDKProfileChangeNewKey = @"FBSDKProfileNew"; static NSString *const FBSDKProfileUserDefaultsKey = @"com.facebook.sdk.FBSDKProfile.currentProfile"; static FBSDKProfile *g_currentProfile; -#define FBSDKPROFILE_USERID_KEY @"userID" -#define FBSDKPROFILE_FIRSTNAME_KEY @"firstName" -#define FBSDKPROFILE_MIDDLENAME_KEY @"middleName" -#define FBSDKPROFILE_LASTNAME_KEY @"lastName" -#define FBSDKPROFILE_NAME_KEY @"name" -#define FBSDKPROFILE_LINKURL_KEY @"linkURL" -#define FBSDKPROFILE_REFRESHDATE_KEY @"refreshDate" + #define FBSDKPROFILE_USERID_KEY @"userID" + #define FBSDKPROFILE_FIRSTNAME_KEY @"firstName" + #define FBSDKPROFILE_MIDDLENAME_KEY @"middleName" + #define FBSDKPROFILE_LASTNAME_KEY @"lastName" + #define FBSDKPROFILE_NAME_KEY @"name" + #define FBSDKPROFILE_LINKURL_KEY @"linkURL" + #define FBSDKPROFILE_REFRESHDATE_KEY @"refreshDate" // Once a day -#define FBSDKPROFILE_STALE_IN_SECONDS (60 * 60 * 24) + #define FBSDKPROFILE_STALE_IN_SECONDS (60 * 60 * 24) @implementation FBSDKProfile @@ -94,21 +94,39 @@ + (void)setCurrentProfile:(FBSDKProfile *)profile - (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size { + NSString *const accessTokenKey = @"access_token"; + NSString *const pictureModeKey = @"type"; + NSString *const widthKey = @"width"; + NSString *const heightKey = @"height"; + NSString *type; switch (mode) { case FBSDKProfilePictureModeNormal: type = @"normal"; break; case FBSDKProfilePictureModeSquare: type = @"square"; break; + case FBSDKProfilePictureModeSmall: type = @"small"; break; + case FBSDKProfilePictureModeAlbum: type = @"album"; break; + case FBSDKProfilePictureModeLarge: type = @"large"; break; + default: type = @"normal"; } - NSString *path = [NSString stringWithFormat:@"%@/picture?type=%@&width=%d&height=%d", - _userID, - type, - (int) roundf(size.width), - (int) roundf(size.height)]; + NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary]; + [FBSDKTypeUtility dictionary:queryParameters setObject:type forKey:pictureModeKey]; + [FBSDKTypeUtility dictionary:queryParameters setObject:@(roundf(size.width)) forKey:widthKey]; + [FBSDKTypeUtility dictionary:queryParameters setObject:@(roundf(size.height)) forKey:heightKey]; + + if (FBSDKAccessToken.currentAccessToken) { + [FBSDKTypeUtility dictionary:queryParameters setObject:FBSDKAccessToken.currentAccessToken.tokenString forKey:accessTokenKey]; + } else if (FBSDKSettings.clientToken) { + [FBSDKTypeUtility dictionary:queryParameters setObject:FBSDKSettings.clientToken forKey:accessTokenKey]; + } else { + NSLog(@"As of Graph API v8.0, profile images may not be retrieved without an access token. This can be the current access token from logging in with Facebook or it can be set via the plist or in code. Providing neither will cause this call to return a silhouette image."); + } + + NSString *path = [NSString stringWithFormat:@"%@/picture", _userID]; return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" path:path - queryParameters:@{} + queryParameters:queryParameters error:NULL]; } @@ -129,15 +147,15 @@ + (void)loadCurrentProfileWithCompletion:(FBSDKProfileBlock)completion [self loadProfileWithToken:[FBSDKAccessToken currentAccessToken] completion:completion]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { - //immutable + // immutable return self; } -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -158,7 +176,7 @@ - (BOOL)isEqual:(id)object if (self == object) { return YES; } - if (![object isKindOfClass:[FBSDKProfile class]]){ + if (![object isKindOfClass:[FBSDKProfile class]]) { return NO; } return [self isEqualToProfile:object]; @@ -166,15 +184,16 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToProfile:(FBSDKProfile *)profile { - return ([_userID isEqualToString:profile.userID] && - [_firstName isEqualToString:profile.firstName] && - [_middleName isEqualToString:profile.middleName] && - [_lastName isEqualToString:profile.lastName] && - [_name isEqualToString:profile.name] && - [_linkURL isEqual:profile.linkURL] && - [_refreshDate isEqualToDate:profile.refreshDate]); + return ([_userID isEqualToString:profile.userID] + && [_firstName isEqualToString:profile.firstName] + && [_middleName isEqualToString:profile.middleName] + && [_lastName isEqualToString:profile.lastName] + && [_name isEqualToString:profile.name] + && [_linkURL isEqual:profile.linkURL] + && [_refreshDate isEqualToDate:profile.refreshDate]); } -#pragma mark NSCoding + + #pragma mark NSCoding + (BOOL)supportsSecureCoding { @@ -210,15 +229,15 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:self.refreshDate forKey:FBSDKPROFILE_REFRESHDATE_KEY]; } -#pragma mark - Private + #pragma mark - Private + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion { static FBSDKGraphRequestConnection *executingRequestConnection = nil; BOOL isStale = [[NSDate date] timeIntervalSinceDate:g_currentProfile.refreshDate] > FBSDKPROFILE_STALE_IN_SECONDS; - if (token && - (isStale || ![g_currentProfile.userID isEqualToString:token.userID])) { + if (token + && (isStale || ![g_currentProfile.userID isEqualToString:token.userID])) { FBSDKProfile *expectedCurrentProfile = g_currentProfile; NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; @@ -262,10 +281,10 @@ + (void)observeChangeAccessTokenChange:(NSNotification *)notification @end -@implementation FBSDKProfile(Internal) +@implementation FBSDKProfile (Internal) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (void)cacheProfile:(FBSDKProfile *)profile { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; @@ -291,7 +310,17 @@ + (FBSDKProfile *)fetchCachedProfile } return nil; } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop + +@end + +@implementation FBSDKProfile (Testing) + ++ (void)resetCurrentProfileCache +{ + g_currentProfile = nil; +} @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.h index c5a1672b0e..cbef2ce9fe 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.h @@ -40,6 +40,18 @@ typedef NS_ENUM(NSUInteger, FBSDKProfilePictureMode) The original picture's aspect ratio will be used for the source image in the view. */ FBSDKProfilePictureModeNormal, + /** + The original picture's aspect ratio will be used for the source image in the view. + */ + FBSDKProfilePictureModeAlbum, + /** + The original picture's aspect ratio will be used for the source image in the view. + */ + FBSDKProfilePictureModeSmall, + /** + The original picture's aspect ratio will be used for the source image in the view. + */ + FBSDKProfilePictureModeLarge, } NS_SWIFT_NAME(Profile.PictureMode); /** diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m index f203586f73..f657ce3101 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m @@ -20,13 +20,13 @@ #if !TARGET_OS_TV -#import "FBSDKProfilePictureView.h" + #import "FBSDKProfilePictureView.h" -#import "FBSDKAccessToken.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKMaleSilhouetteIcon.h" -#import "FBSDKMath.h" -#import "FBSDKUtility.h" + #import "FBSDKAccessToken.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKMaleSilhouetteIcon.h" + #import "FBSDKMath.h" + #import "FBSDKUtility.h" @interface FBSDKProfilePictureViewState : NSObject @@ -36,11 +36,11 @@ - (instancetype)initWithProfileID:(NSString *)profileID pictureMode:(FBSDKProfilePictureMode)pictureMode imageShouldFit:(BOOL)imageShouldFit; -@property (nonatomic, assign, readonly) BOOL imageShouldFit; -@property (nonatomic, assign, readonly) FBSDKProfilePictureMode pictureMode; -@property (nonatomic, copy, readonly) NSString *profileID; -@property (nonatomic, assign, readonly) CGFloat scale; -@property (nonatomic, assign, readonly) CGSize size; +@property (nonatomic, readonly, assign) BOOL imageShouldFit; +@property (nonatomic, readonly, assign) FBSDKProfilePictureMode pictureMode; +@property (nonatomic, readonly, copy) NSString *profileID; +@property (nonatomic, readonly, assign) CGFloat scale; +@property (nonatomic, readonly, assign) CGSize size; - (BOOL)isEqualToState:(FBSDKProfilePictureViewState *)other; - (BOOL)isValidForState:(FBSDKProfilePictureViewState *)other; @@ -89,17 +89,17 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToState:(FBSDKProfilePictureViewState *)other { - return ([self isValidForState:other] && - CGSizeEqualToSize(_size, other->_size) && - (_scale == other->_scale)); + return ([self isValidForState:other] + && CGSizeEqualToSize(_size, other->_size) + && (_scale == other->_scale)); } - (BOOL)isValidForState:(FBSDKProfilePictureViewState *)other { - return (other != nil && - (_imageShouldFit == other->_imageShouldFit) && - (_pictureMode == other->_pictureMode) && - [FBSDKInternalUtility object:_profileID isEqualToObject:other->_profileID]); + return (other != nil + && (_imageShouldFit == other->_imageShouldFit) + && (_pictureMode == other->_pictureMode) + && [FBSDKInternalUtility object:_profileID isEqualToObject:other->_profileID]); } @end @@ -113,7 +113,7 @@ @implementation FBSDKProfilePictureView BOOL _placeholderImageIsValid; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { @@ -152,7 +152,7 @@ - (void)dealloc [[NSNotificationCenter defaultCenter] removeObserver:self]; } -#pragma mark - Properties + #pragma mark - Properties - (void)setBounds:(CGRect)bounds { @@ -199,7 +199,7 @@ - (void)setProfileID:(NSString *)profileID } } -#pragma mark - Public Methods + #pragma mark - Public Methods - (void)setNeedsImageUpdate { @@ -223,7 +223,7 @@ - (void)setNeedsImageUpdate }); } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { @@ -278,7 +278,7 @@ - (CGSize)_imageSize:(BOOL)imageShouldFit scale:(CGFloat)scale // get the image size based on the contentMode and pictureMode CGSize size = self.bounds.size; switch (_pictureMode) { - case FBSDKProfilePictureModeSquare:{ + case FBSDKProfilePictureModeSquare: { CGFloat imageSize; if (imageShouldFit) { imageSize = MIN(size.width, size.height); @@ -289,6 +289,9 @@ - (CGSize)_imageSize:(BOOL)imageShouldFit scale:(CGFloat)scale break; } case FBSDKProfilePictureModeNormal: + case FBSDKProfilePictureModeAlbum: + case FBSDKProfilePictureModeSmall: + case FBSDKProfilePictureModeLarge: // use the bounds size break; } @@ -354,7 +357,7 @@ - (void)_needsImageUpdate - (void)_setPlaceholderImage { - UIColor *fillColor = [UIColor colorWithRed:157.0/255.0 green:177.0/255.0 blue:204.0/255.0 alpha:1.0]; + UIColor *fillColor = [UIColor colorWithRed:157.0 / 255.0 green:177.0 / 255.0 blue:204.0 / 255.0 alpha:1.0]; _placeholderImageIsValid = YES; _hasProfileImage = NO; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h index 2aa81e263f..86ee277aea 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h @@ -89,7 +89,8 @@ NS_SWIFT_NAME(jpegCompressionQuality); Controls sdk auto initailization. If not explicitly set, the default is true */ -@property (class, nonatomic, assign, getter=isAutoInitEnabled) BOOL autoInitEnabled; +@property (class, nonatomic, assign, getter=isAutoInitEnabled) BOOL autoInitEnabled +DEPRECATED_MSG_ATTRIBUTE("Auto-initialization will be removed in the next major version release."); /** Controls the auto logging of basic app events, such as activateApp and deactivateApp. @@ -104,7 +105,7 @@ NS_SWIFT_NAME(jpegCompressionQuality); @property (class, nonatomic, assign, getter=isCodelessDebugLogEnabled) BOOL codelessDebugLogEnabled; /** - Controls the fb_codeless_debug logging event + Controls the access to IDFA If not explicitly set, the default is true */ @property (class, nonatomic, assign, getter=isAdvertiserIDCollectionEnabled) BOOL advertiserIDCollectionEnabled; @@ -187,6 +188,20 @@ NS_REFINED_FOR_SWIFT; */ @property (class, nonatomic, copy, null_resettable) NSString *graphAPIVersion; +/** + The value of the flag advertiser_tracking_enabled that controls the advertiser tracking status of the data sent to Facebook + If not explicitly set in iOS14 or above, the default is false in iOS14 or above. + */ ++ (BOOL)isAdvertiserTrackingEnabled; + +/** +Set the advertiser_tracking_enabled flag. It only works in iOS14 and above. + +@param advertiserTrackingEnabled the value of the flag +@return Whether the the value is set successfully. It will always return NO in iOS 13 and below. + */ ++ (BOOL)setAdvertiserTrackingEnabled:(BOOL)advertiserTrackingEnabled; + /** Set the data processing options. diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m index b9a8a27e67..7f0ac6dfb6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m @@ -21,32 +21,34 @@ #import "FBSDKAccessTokenCache.h" #import "FBSDKAccessTokenExpirer.h" #import "FBSDKAppEvents+Internal.h" +#import "FBSDKAppEventsConfiguration.h" +#import "FBSDKAppEventsConfigurationManager.h" #import "FBSDKCoreKit.h" -#import "FBSDKTypeUtility.h" +#import "FBSDKInternalUtility.h" #define FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE, ENABLE_CACHE) \ -static TYPE *g_##PLIST_KEY = nil; \ -+ (TYPE *)GETTER \ -{ \ - if ((g_##PLIST_KEY == nil) && ENABLE_CACHE) { \ - g_##PLIST_KEY = [[[NSUserDefaults standardUserDefaults] objectForKey:@#PLIST_KEY] copy]; \ - } \ - if (g_##PLIST_KEY == nil) { \ - g_##PLIST_KEY = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@#PLIST_KEY] copy] ?: DEFAULT_VALUE; \ - } \ - return g_##PLIST_KEY; \ -} \ -+ (void)SETTER:(TYPE *)value { \ - g_##PLIST_KEY = [value copy]; \ - if (ENABLE_CACHE) { \ - if (value != nil) { \ - [[NSUserDefaults standardUserDefaults] setObject:value forKey:@#PLIST_KEY]; \ - } else { \ - [[NSUserDefaults standardUserDefaults] removeObjectForKey:@#PLIST_KEY]; \ + static TYPE *g_ ## PLIST_KEY = nil; \ + + (TYPE *)GETTER \ + { \ + if ((g_ ## PLIST_KEY == nil) && ENABLE_CACHE) { \ + g_ ## PLIST_KEY = [[[NSUserDefaults standardUserDefaults] objectForKey:@#PLIST_KEY] copy]; \ } \ + if (g_ ## PLIST_KEY == nil) { \ + g_ ## PLIST_KEY = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@#PLIST_KEY] copy] ?: DEFAULT_VALUE; \ + } \ + return g_ ## PLIST_KEY; \ } \ - [FBSDKSettings _logIfSDKSettingsChanged]; \ -} + + (void)SETTER:(TYPE *)value { \ + g_ ## PLIST_KEY = [value copy]; \ + if (ENABLE_CACHE) { \ + if (value != nil) { \ + [[NSUserDefaults standardUserDefaults] setObject:value forKey:@#PLIST_KEY]; \ + } else { \ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@#PLIST_KEY]; \ + } \ + } \ + [FBSDKSettings _logIfSDKSettingsChanged]; \ + } FBSDKLoggingBehavior FBSDKLoggingBehaviorAccessTokens = @"include_access_tokens"; FBSDKLoggingBehavior FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics"; @@ -64,27 +66,31 @@ + (void)SETTER:(TYPE *)value { \ static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage"; static NSString *const FBSDKSettingsBitmask = @"com.facebook.sdk:FBSDKSettingsBitmask"; static NSString *const FBSDKSettingsDataProcessingOptions = @"com.facebook.sdk:FBSDKSettingsDataProcessingOptions"; +static NSString *const FBSDKSettingsAdvertisingTrackingStatus = @"com.facebook.sdk:FBSDKSettingsAdvertisingTrackingStatus"; +static NSString *const FBSDKSettingsInstallTimestamp = @"com.facebook.sdk:FBSDKSettingsInstallTimestamp"; +static NSString *const FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp = @"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"; static BOOL g_disableErrorRecovery; static NSString *g_userAgentSuffix; static NSString *g_defaultGraphAPIVersion; static FBSDKAccessTokenExpirer *g_accessTokenExpirer; static NSDictionary *g_dataProcessingOptions = nil; +static NSNumber *g_advertiserTrackingStatus = nil; // -// Warning messages for App Event Flags +// Warning messages for App Event Flags // static NSString *const autoLogAppEventsEnabledNotSetWarning = - @": Please set a value for FacebookAutoLogAppEventsEnabled. Set the flag to TRUE if you want " - "to collect app install, app launch and in-app purchase events automatically. To request user consent " - "before collecting data, set the flag value to FALSE, then change to TRUE once user consent is received. " - "Learn more: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios#disable-auto-events."; +@": Please set a value for FacebookAutoLogAppEventsEnabled. Set the flag to TRUE if you want " +"to collect app install, app launch and in-app purchase events automatically. To request user consent " +"before collecting data, set the flag value to FALSE, then change to TRUE once user consent is received. " +"Learn more: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios#disable-auto-events."; static NSString *const advertiserIDCollectionEnabledNotSetWarning = - @": You haven't set a value for FacebookAdvertiserIDCollectionEnabled. Set the flag to TRUE if " - "you want to collect Advertiser ID for better advertising and analytics results."; +@": You haven't set a value for FacebookAdvertiserIDCollectionEnabled. Set the flag to TRUE if " +"you want to collect Advertiser ID for better advertising and analytics results."; static NSString *const advertiserIDCollectionEnabledFalseWarning = - @": The value for FacebookAdvertiserIDCollectionEnabled is currently set to FALSE so you're sending app " - "events without collecting Advertiser ID. This can affect the quality of your advertising and analytics results."; +@": The value for FacebookAdvertiserIDCollectionEnabled is currently set to FALSE so you're sending app " +"events without collecting Advertiser ID. This can affect the quality of your advertising and analytics results."; @implementation FBSDKSettings @@ -111,8 +117,14 @@ + (void)initialize FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookInstrumentEnabled, _instrumentEnabled, _setInstrumentEnabled, @1, YES); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoLogAppEventsEnabled, _autoLogAppEventsEnabled, _setAutoLogAppEventsEnabled, @1, YES); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCollectionEnabled, _advertiserIDCollectionEnabled, _setAdvertiserIDCollectionEnabled, @1, YES); -FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookCodelessDebugLogEnabled, _codelessDebugLogEnabled, - _setCodelessDebugLogEnabled, @0, YES); +FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL( + NSNumber, + FacebookCodelessDebugLogEnabled, + _codelessDebugLogEnabled, + _setCodelessDebugLogEnabled, + @0, + YES +); + (BOOL)isGraphErrorRecoveryEnabled { @@ -187,6 +199,40 @@ + (void)setAdvertiserIDCollectionEnabled:(BOOL)advertiserIDCollectionEnabled [self _setAdvertiserIDCollectionEnabled:@(advertiserIDCollectionEnabled)]; } ++ (BOOL)isAdvertiserTrackingEnabled +{ + return [FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingAllowed; +} + ++ (BOOL)setAdvertiserTrackingEnabled:(BOOL)enabled; +{ + if (@available(iOS 14.0, *)) { + [FBSDKSettings setAdvertiserTrackingStatus:enabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed]; + [self recordSetAdvertiserTrackingEnabled]; + return YES; + } else { + return NO; + } +} + ++ (FBSDKAdvertisingTrackingStatus)getAdvertisingTrackingStatus +{ + if (@available(iOS 14.0, *)) { + if (g_advertiserTrackingStatus == nil) { + g_advertiserTrackingStatus = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsAdvertisingTrackingStatus] ?: @([FBSDKAppEventsConfigurationManager cachedAppEventsConfiguration].defaultATEStatus); + } + return g_advertiserTrackingStatus.unsignedIntegerValue; + } else { + return [FBSDKAppEventsUtility advertisingTrackingStatus]; + } +} + ++ (void)setAdvertiserTrackingStatus:(FBSDKAdvertisingTrackingStatus)status +{ + g_advertiserTrackingStatus = @(status); + [[NSUserDefaults standardUserDefaults] setObject:g_advertiserTrackingStatus forKey:FBSDKSettingsAdvertisingTrackingStatus]; +} + + (BOOL)shouldLimitEventAndDataUsage { NSNumber *storedValue = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsLimitEventAndDataUsage]; @@ -230,9 +276,9 @@ + (void)setDataProcessingOptions:(nullable NSArray *)options state:(int)state { NSDictionary *json = @{ - DATA_PROCESSING_OPTIONS: options ?: @[], - DATA_PROCESSING_OPTIONS_COUNTRY: @(country), - DATA_PROCESSING_OPTIONS_STATE: @(state), + DATA_PROCESSING_OPTIONS : options ?: @[], + DATA_PROCESSING_OPTIONS_COUNTRY : @(country), + DATA_PROCESSING_OPTIONS_STATE : @(state), }; g_dataProcessingOptions = json; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:g_dataProcessingOptions]; @@ -241,6 +287,7 @@ + (void)setDataProcessingOptions:(nullable NSArray *)options forKey:FBSDKSettingsDataProcessingOptions]; } } + #pragma clang diagnostic pop + (void)setLoggingBehaviors:(NSSet *)loggingBehaviors @@ -305,8 +352,7 @@ + (void)setUserAgentSuffix:(NSString *)suffix + (void)setGraphAPIVersion:(NSString *)version { - if (![g_defaultGraphAPIVersion isEqualToString:version]) - { + if (![g_defaultGraphAPIVersion isEqualToString:version]) { g_defaultGraphAPIVersion = version; } } @@ -352,6 +398,7 @@ + (NSNumber *)appEventSettingsForUserDefaultsKey:(NSString *)userDefaultsKey } return g_dataProcessingOptions; } + #pragma clang diagnostic pop + (BOOL)isDataProcessingRestricted @@ -386,7 +433,10 @@ + (void)_logIfSDKSettingsChanged { NSInteger bitmask = 0; NSInteger bit = 0; + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" bitmask |= ([FBSDKSettings isAutoInitEnabled] ? 1 : 0) << bit++; + #pragma clang diagnostic pop bitmask |= ([FBSDKSettings isAutoLogAppEventsEnabled] ? 1 : 0) << bit++; bitmask |= ([FBSDKSettings isAdvertiserIDCollectionEnabled] ? 1 : 0) << bit++; @@ -407,14 +457,56 @@ + (void)_logIfSDKSettingsChanged usageBitmask |= (plistValue != nil ? 1 : 0) << i; } [FBSDKAppEvents logInternalEvent:@"fb_sdk_settings_changed" - parameters:@{@"usage": @(usageBitmask), - @"initial": @(initialBitmask), - @"previous":@(previousBitmask), - @"current": @(bitmask)} + parameters:@{@"usage" : @(usageBitmask), + @"initial" : @(initialBitmask), + @"previous" : @(previousBitmask), + @"current" : @(bitmask)} isImplicitlyLogged:YES]; } } ++ (void)recordInstall +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + if (![defaults objectForKey:FBSDKSettingsInstallTimestamp]) { + [defaults setObject:[NSDate date] forKey:FBSDKSettingsInstallTimestamp]; + } +} + ++ (void)recordSetAdvertiserTrackingEnabled +{ + [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp]; +} + ++ (BOOL)isEventDelayTimerExpired +{ + NSDate *timestamp = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsInstallTimestamp]; + if (timestamp) { + return [[NSDate date] timeIntervalSinceDate:timestamp] > 86400; + } + return NO; +} + ++ (BOOL)isSetATETimeExceedsInstallTime +{ + NSDate *installTimestamp = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsInstallTimestamp]; + NSDate *setATETimestamp = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp]; + if (installTimestamp && setATETimestamp) { + return [setATETimestamp timeIntervalSinceDate:installTimestamp] > 86400; + } + return NO; +} + ++ (NSDate *_Nullable)getInstallTimestamp +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsInstallTimestamp]; +} + ++ (NSDate *_Nullable)getSetAdvertiserTrackingEnabledTimestamp +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp]; +} + #pragma mark - Internal - Graph API Debug + (void)updateGraphAPIDebugBehavior @@ -437,4 +529,90 @@ + (NSString *)graphAPIDebugParamValue return nil; } +#pragma mark - Testability + +#if DEBUG + ++ (void)resetLoggingBehaviorsCache +{ + g_loggingBehaviors = nil; +} + ++ (void)resetTokenCache +{ + g_tokenCache = nil; +} + ++ (void)resetFacebookAppIDCache +{ + g_FacebookAppID = nil; +} + ++ (void)resetFacebookUrlSchemeSuffixCache +{ + g_FacebookUrlSchemeSuffix = nil; +} + ++ (void)resetFacebookClientTokenCache +{ + g_FacebookClientToken = nil; +} + ++ (void)resetFacebookDisplayNameCache +{ + g_FacebookDisplayName = nil; +} + ++ (void)resetFacebookDomainPartCache +{ + g_FacebookDomainPart = nil; +} + ++ (void)resetFacebookJpegCompressionQualityCache +{ + g_FacebookJpegCompressionQuality = nil; +} + ++ (void)resetFacebookAutoInitEnabledCache +{ + g_FacebookAutoInitEnabled = nil; +} + ++ (void)resetFacebookInstrumentEnabledCache +{ + g_FacebookInstrumentEnabled = nil; +} + ++ (void)resetFacebookAutoLogAppEventsEnabledCache +{ + g_FacebookAutoLogAppEventsEnabled = nil; +} + ++ (void)resetFacebookAdvertiserIDCollectionEnabledCache +{ + g_FacebookAdvertiserIDCollectionEnabled = nil; +} + ++ (void)resetAdvertiserTrackingStatusCache +{ + g_advertiserTrackingStatus = nil; +} + ++ (void)resetUserAgentSuffixCache +{ + g_userAgentSuffix = nil; +} + ++ (void)resetFacebookCodelessDebugLogEnabledCache +{ + g_FacebookCodelessDebugLogEnabled = nil; +} + ++ (void)resetDataProcessingOptionsCache +{ + g_dataProcessingOptions = nil; +} + +#endif + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m index ee36c081e8..955ba74dcb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m @@ -25,7 +25,7 @@ static NSString *const kAccountsDictionaryPermissionsKey = @"permissions"; static NSMutableDictionary *gInstancesDictionary; -@interface FBSDKTestUsersManager() +@interface FBSDKTestUsersManager () - (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret NS_DESIGNATED_INITIALIZER; @end @@ -35,11 +35,12 @@ @implementation FBSDKTestUsersManager NSString *_appSecret; // dictionary with format like: // { user_id : { kAccountsDictionaryTokenKey : "token", - // kAccountsDictionaryPermissionsKey : [ permissions ] } + // kAccountsDictionaryPermissionsKey : [ permissions ] } NSMutableDictionary *_accounts; } -- (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret { +- (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret +{ if ((self = [super init])) { _appID = [appID copy]; _appSecret = [appSecret copy]; @@ -48,7 +49,8 @@ - (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret return self; } -+ (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret { ++ (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret +{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ gInstancesDictionary = [NSMutableDictionary dictionary]; @@ -63,11 +65,12 @@ + (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)a - (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *> *)arraysOfPermissions createIfNotFound:(BOOL)createIfNotFound - completionHandler:(FBSDKAccessTokensBlock)handler { + completionHandler:(FBSDKAccessTokensBlock)handler +{ arraysOfPermissions = arraysOfPermissions ?: @[[NSSet set]]; // wrap work in a block so that we can chain it to after a fetch of existing accounts if we need to. - void (^helper)(NSError *) = ^(NSError *error){ + void (^helper)(NSError *) = ^(NSError *error) { if (error) { if (handler) { handler(@[], error); @@ -79,7 +82,7 @@ - (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *baseQuery = [FBSDKURL queryParametersForURL:url]; - _inputQueryParameters = baseQuery; - _targetQueryParameters = baseQuery; - - // Check for applink_data - NSString *appLinkDataString = baseQuery[FBSDKAppLinkDataParameterName]; - if (appLinkDataString) { - // Try to parse the JSON - NSError *error = nil; - NSDictionary *applinkData = - [FBSDKTypeUtility JSONObjectWithData:[appLinkDataString dataUsingEncoding:NSUTF8StringEncoding] - options:0 - error:&error]; - if (!error && [applinkData isKindOfClass:[NSDictionary class]]) { - // If the version is not specified, assume it is 1. - NSString *version = applinkData[FBSDKAppLinkVersionKeyName] ?: @"1.0"; - NSString *target = applinkData[FBSDKAppLinkTargetKeyName]; - if ([version isKindOfClass:[NSString class]] && - [version isEqual:FBSDKAppLinkVersion]) { - // There's applink data! The target should actually be the applink target. - _appLinkData = applinkData; - id applinkExtras = applinkData[FBSDKAppLinkExtrasKeyName]; - if (applinkExtras && [applinkExtras isKindOfClass:[NSDictionary class]]) { - _appLinkExtras = applinkExtras; - } - _targetURL = ([target isKindOfClass:[NSString class]] ? [NSURL URLWithString:target] : url); - _targetQueryParameters = [FBSDKURL queryParametersForURL:_targetURL]; - - NSDictionary *refererAppLink = _appLinkData[FBSDKAppLinkRefererAppLink]; - NSString *refererURLString = refererAppLink[FBSDKAppLinkRefererUrl]; - NSString *refererAppName = refererAppLink[FBSDKAppLinkRefererAppName]; - - if (refererURLString && refererAppName) { - FBSDKAppLinkTarget *appLinkTarget = [FBSDKAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:refererURLString] - appStoreId:nil - appName:refererAppName]; - _appLinkReferer = [FBSDKAppLink appLinkWithSourceURL:[NSURL URLWithString:refererURLString] - targets:@[ appLinkTarget ] - webURL:nil - isBackToReferrer:YES]; - } - - // Raise Measurement Event - NSString *const EVENT_YES_VAL = @"1"; - NSString *const EVENT_NO_VAL = @"0"; - NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:logData setObject:version forKey:@"version"]; - if (refererURLString) { - [FBSDKTypeUtility dictionary:logData setObject:refererURLString forKey:@"refererURL"]; - } - if (refererAppName) { - [FBSDKTypeUtility dictionary:logData setObject:refererAppName forKey:@"refererAppName"]; - } - if (sourceApplication) { - [FBSDKTypeUtility dictionary:logData setObject:sourceApplication forKey:@"sourceApplication"]; - } - if (_targetURL.absoluteString) { - [FBSDKTypeUtility dictionary:logData setObject:_targetURL.absoluteString forKey:@"targetURL"]; - } - if (_inputURL.absoluteString) { - [FBSDKTypeUtility dictionary:logData setObject:_inputURL.absoluteString forKey:@"inputURL"]; - } - if (_inputURL.scheme) { - [FBSDKTypeUtility dictionary:logData setObject:_inputURL.scheme forKey:@"inputURLScheme"]; - } - [FBSDKTypeUtility dictionary:logData setObject:forRenderBackToReferrerBar ? EVENT_YES_VAL : EVENT_NO_VAL forKey:@"forRenderBackToReferrerBar"]; - [FBSDKTypeUtility dictionary:logData setObject:forOpenURLEvent ? EVENT_YES_VAL : EVENT_NO_VAL forKey:@"forOpenUrl"]; - [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkParseEventName args:logData]; - if (forOpenURLEvent) { - [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkNavigateInEventName args:logData]; - } - } +- (instancetype)initWithURL:(NSURL *)url forOpenInboundURL:(BOOL)forOpenURLEvent sourceApplication:(NSString *)sourceApplication forRenderBackToReferrerBar:(BOOL)forRenderBackToReferrerBar +{ + self = [super init]; + if (!self) { + return nil; + } + + _inputURL = url; + _targetURL = url; + + // Parse the query string parameters for the base URL + NSDictionary *baseQuery = [FBSDKURL queryParametersForURL:url]; + _inputQueryParameters = baseQuery; + _targetQueryParameters = baseQuery; + + // Check for applink_data + NSString *appLinkDataString = baseQuery[FBSDKAppLinkDataParameterName]; + if (appLinkDataString) { + // Try to parse the JSON + NSError *error = nil; + NSDictionary *applinkData = + [FBSDKTypeUtility JSONObjectWithData:[appLinkDataString dataUsingEncoding:NSUTF8StringEncoding] + options:0 + error:&error]; + if (!error && [applinkData isKindOfClass:[NSDictionary class]]) { + // If the version is not specified, assume it is 1. + NSString *version = applinkData[FBSDKAppLinkVersionKeyName] ?: @"1.0"; + NSString *target = applinkData[FBSDKAppLinkTargetKeyName]; + if ([version isKindOfClass:[NSString class]] + && [version isEqual:FBSDKAppLinkVersion]) { + // There's applink data! The target should actually be the applink target. + _appLinkData = applinkData; + id applinkExtras = applinkData[FBSDKAppLinkExtrasKeyName]; + if (applinkExtras && [applinkExtras isKindOfClass:[NSDictionary class]]) { + _appLinkExtras = applinkExtras; + } + _targetURL = ([target isKindOfClass:[NSString class]] ? [NSURL URLWithString:target] : url); + _targetQueryParameters = [FBSDKURL queryParametersForURL:_targetURL]; + + NSDictionary *refererAppLink = _appLinkData[FBSDKAppLinkRefererAppLink]; + NSString *refererURLString = refererAppLink[FBSDKAppLinkRefererUrl]; + NSString *refererAppName = refererAppLink[FBSDKAppLinkRefererAppName]; + + if (refererURLString && refererAppName) { + FBSDKAppLinkTarget *appLinkTarget = [FBSDKAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:refererURLString] + appStoreId:nil + appName:refererAppName]; + _appLinkReferer = [FBSDKAppLink appLinkWithSourceURL:[NSURL URLWithString:refererURLString] + targets:@[appLinkTarget] + webURL:nil + isBackToReferrer:YES]; + } + + // Raise Measurement Event + NSString *const EVENT_YES_VAL = @"1"; + NSString *const EVENT_NO_VAL = @"0"; + NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; + [FBSDKTypeUtility dictionary:logData setObject:version forKey:@"version"]; + if (refererURLString) { + [FBSDKTypeUtility dictionary:logData setObject:refererURLString forKey:@"refererURL"]; + } + if (refererAppName) { + [FBSDKTypeUtility dictionary:logData setObject:refererAppName forKey:@"refererAppName"]; + } + if (sourceApplication) { + [FBSDKTypeUtility dictionary:logData setObject:sourceApplication forKey:@"sourceApplication"]; } + if (_targetURL.absoluteString) { + [FBSDKTypeUtility dictionary:logData setObject:_targetURL.absoluteString forKey:@"targetURL"]; + } + if (_inputURL.absoluteString) { + [FBSDKTypeUtility dictionary:logData setObject:_inputURL.absoluteString forKey:@"inputURL"]; + } + if (_inputURL.scheme) { + [FBSDKTypeUtility dictionary:logData setObject:_inputURL.scheme forKey:@"inputURLScheme"]; + } + [FBSDKTypeUtility dictionary:logData setObject:forRenderBackToReferrerBar ? EVENT_YES_VAL : EVENT_NO_VAL forKey:@"forRenderBackToReferrerBar"]; + [FBSDKTypeUtility dictionary:logData setObject:forOpenURLEvent ? EVENT_YES_VAL : EVENT_NO_VAL forKey:@"forOpenUrl"]; + [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkParseEventName args:logData]; + if (forOpenURLEvent) { + [FBSDKMeasurementEvent postNotificationForEventName:FBSDKAppLinkNavigateInEventName args:logData]; + } + } } + } - return self; + return self; } -- (BOOL)isAutoAppLink { +- (BOOL)isAutoAppLink +{ NSString *host = self.targetURL.host; NSString *scheme = self.targetURL.scheme; NSString *expectedHost = @"applinks"; @@ -127,37 +130,41 @@ - (BOOL)isAutoAppLink { return autoFlag && [expectedHost isEqual:host] && [expectedScheme isEqual:scheme]; } -+ (instancetype)URLWithURL:(NSURL *)url { - return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:NO]; ++ (instancetype)URLWithURL:(NSURL *)url +{ + return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:NO]; } -+ (instancetype)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { - return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:YES sourceApplication:sourceApplication forRenderBackToReferrerBar:NO]; ++ (instancetype)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication +{ + return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:YES sourceApplication:sourceApplication forRenderBackToReferrerBar:NO]; } -+ (instancetype)URLForRenderBackToReferrerBarURL:(NSURL *)url { - return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:YES]; ++ (instancetype)URLForRenderBackToReferrerBarURL:(NSURL *)url +{ + return [[FBSDKURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:YES]; } -+ (NSDictionary *)queryParametersForURL:(NSURL *)url { - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - NSString *query = url.query; - if ([query isEqualToString:@""]) { - return @{}; - } - NSArray *queryComponents = [query componentsSeparatedByString:@"&"]; - for (NSString *component in queryComponents) { - NSRange equalsLocation = [component rangeOfString:@"="]; - if (equalsLocation.location == NSNotFound) { - // There's no equals, so associate the key with NSNull - [FBSDKTypeUtility dictionary:parameters setObject:[NSNull null] forKey:[FBSDKBasicUtility URLDecode:component]]; - } else { - NSString *key = [FBSDKBasicUtility URLDecode:[component substringToIndex:equalsLocation.location]]; - NSString *value = [FBSDKBasicUtility URLDecode:[component substringFromIndex:equalsLocation.location + 1]]; - [FBSDKTypeUtility dictionary:parameters setObject:value forKey:key]; - } ++ (NSDictionary *)queryParametersForURL:(NSURL *)url +{ + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + NSString *query = url.query; + if ([query isEqualToString:@""]) { + return @{}; + } + NSArray *queryComponents = [query componentsSeparatedByString:@"&"]; + for (NSString *component in queryComponents) { + NSRange equalsLocation = [component rangeOfString:@"="]; + if (equalsLocation.location == NSNotFound) { + // There's no equals, so associate the key with NSNull + [FBSDKTypeUtility dictionary:parameters setObject:[NSNull null] forKey:[FBSDKBasicUtility URLDecode:component]]; + } else { + NSString *key = [FBSDKBasicUtility URLDecode:[component substringToIndex:equalsLocation.location]]; + NSString *value = [FBSDKBasicUtility URLDecode:[component substringFromIndex:equalsLocation.location + 1]]; + [FBSDKTypeUtility dictionary:parameters setObject:value forKey:key]; } - return [NSDictionary dictionaryWithDictionary:parameters]; + } + return [NSDictionary dictionaryWithDictionary:parameters]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m index 8a32c665e0..84e88eb853 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m @@ -46,15 +46,19 @@ + (NSString *)URLEncode:(NSString *)value + (dispatch_source_t)startGCDTimerWithInterval:(double)interval block:(dispatch_block_t)block { - dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, // source type - 0, // handle - 0, // mask - dispatch_get_main_queue()); // queue - - dispatch_source_set_timer(timer, // dispatch source - dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), // start - interval * NSEC_PER_SEC, // interval - 0 * NSEC_PER_SEC); // leeway + dispatch_source_t timer = dispatch_source_create( + DISPATCH_SOURCE_TYPE_TIMER, // source type + 0, // handle + 0, // mask + dispatch_get_main_queue() + ); // queue + + dispatch_source_set_timer( + timer, // dispatch source + dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), // start + interval * NSEC_PER_SEC, // interval + 0 * NSEC_PER_SEC + ); // leeway dispatch_source_set_event_handler(timer, block); @@ -72,26 +76,7 @@ + (void)stopGCDTimer:(dispatch_source_t)timer + (NSString *)SHA256Hash:(NSObject *)input { - NSData *data = nil; - - if ([input isKindOfClass:[NSData class]]) { - data = (NSData *)input; - } else if ([input isKindOfClass:[NSString class]]) { - data = [(NSString *)input dataUsingEncoding:NSUTF8StringEncoding]; - } - - if (!data) { - return nil; - } - - uint8_t digest[CC_SHA256_DIGEST_LENGTH]; - CC_SHA256(data.bytes, (CC_LONG)data.length, digest); - NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; - for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { - [hashed appendFormat:@"%02x", digest[i]]; - } - - return [hashed copy]; + return [FBSDKBasicUtility SHA256Hash:input]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m index b3b37e9682..3ebc35b7b7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m @@ -20,18 +20,18 @@ #if !TARGET_OS_TV -#import "FBSDKGraphErrorRecoveryProcessor.h" + #import "FBSDKGraphErrorRecoveryProcessor.h" -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKErrorRecoveryAttempter.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKErrorRecoveryAttempter.h" -@interface FBSDKGraphErrorRecoveryProcessor() +@interface FBSDKGraphErrorRecoveryProcessor () { FBSDKErrorRecoveryAttempter *_recoveryAttempter; NSError *_error; } -@property (nonatomic, strong, nullable) iddelegate; +@property (nullable, nonatomic, strong) id delegate; @end @@ -48,17 +48,17 @@ - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request deleg FBSDKGraphRequestError errorCategory = [error.userInfo[FBSDKGraphRequestErrorKey] unsignedIntegerValue]; switch (errorCategory) { - case FBSDKGraphRequestErrorTransient : + case FBSDKGraphRequestErrorTransient: [self.delegate processorDidAttemptRecovery:self didRecover:YES error:nil]; self.delegate = nil; return YES; - case FBSDKGraphRequestErrorRecoverable : + case FBSDKGraphRequestErrorRecoverable: if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { _recoveryAttempter = error.recoveryAttempter; // Set up a block to do the typical recovery work so that we can chain it for ios auth special cases. // the block returns YES if recovery UI is started (meaning we wait for the alertviewdelegate to resume control flow). - BOOL (^standardRecoveryWork)(void) = ^BOOL{ + BOOL (^standardRecoveryWork)(void) = ^BOOL { NSArray *recoveryOptionsTitles = error.userInfo[NSLocalizedRecoveryOptionsErrorKey]; if (recoveryOptionsTitles.count > 0 && self->_recoveryAttempter) { NSString *recoverySuggestion = error.userInfo[NSLocalizedRecoverySuggestionErrorKey]; @@ -74,16 +74,20 @@ - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request deleg return standardRecoveryWork(); } return NO; - case FBSDKGraphRequestErrorOther : + case FBSDKGraphRequestErrorOther: if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { NSString *message = error.userInfo[FBSDKErrorLocalizedDescriptionKey]; NSString *title = error.userInfo[FBSDKErrorLocalizedTitleKey]; if (message) { dispatch_async(dispatch_get_main_queue(), ^{ NSString *localizedOK = - NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Alert.OK", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"OK", - @"The title of the label to dismiss the alert when presenting user facing error messages"); + NSLocalizedStringWithDefaultValue( + @"ErrorRecovery.Alert.OK", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"OK", + @"The title of the label to dismiss the alert when presenting user facing error messages" + ); [self displayAlertWithTitle:title message:message cancelButtonTitle:localizedOK]; }); } @@ -93,7 +97,7 @@ - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request deleg return NO; } -#pragma mark - UIAlertController support + #pragma mark - UIAlertController support - (void)displayAlertWithRecoverySuggestion:(NSString *)recoverySuggestion recoveryOptionsTitles:(NSArray *)recoveryOptionsTitles { @@ -104,7 +108,7 @@ - (void)displayAlertWithRecoverySuggestion:(NSString *)recoverySuggestion recove NSString *title = [FBSDKTypeUtility array:recoveryOptionsTitles objectAtIndex:i]; UIAlertAction *option = [UIAlertAction actionWithTitle:title style:UIAlertActionStyleDefault - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *_Nonnull action) { [self->_recoveryAttempter attemptRecoveryFromError:self->_error optionIndex:i delegate:self @@ -126,7 +130,7 @@ - (void)displayAlertWithTitle:(NSString *)title message:(NSString *)message canc preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *OKAction = [UIAlertAction actionWithTitle:localizedOK style:UIAlertActionStyleCancel - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *_Nonnull action) { [self->_recoveryAttempter attemptRecoveryFromError:self->_error optionIndex:0 delegate:self @@ -140,7 +144,7 @@ - (void)displayAlertWithTitle:(NSString *)title message:(NSString *)message canc completion:nil]; } -#pragma mark - FBSDKErrorRecoveryAttempting "delegate" + #pragma mark - FBSDKErrorRecoveryAttempting "delegate" - (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo { diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m index 1157fcb3b0..b3b06dd521 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m @@ -33,26 +33,29 @@ FBSDKHTTPMethod FBSDKHTTPMethodPOST = @"POST"; FBSDKHTTPMethod FBSDKHTTPMethodDELETE = @"DELETE"; -@interface FBSDKGraphRequest() +@interface FBSDKGraphRequest () @property (nonatomic, assign) FBSDKGraphRequestFlags flags; -@property (nonatomic, copy, readwrite) FBSDKHTTPMethod HTTPMethod; +@property (nonatomic, readwrite, copy) FBSDKHTTPMethod HTTPMethod; @end @implementation FBSDKGraphRequest @synthesize HTTPMethod; -- (instancetype)initWithGraphPath:(NSString *)graphPath { +- (instancetype)initWithGraphPath:(NSString *)graphPath +{ return [self initWithGraphPath:graphPath parameters:@{}]; } - (instancetype)initWithGraphPath:(NSString *)graphPath - HTTPMethod:(FBSDKHTTPMethod)method { + HTTPMethod:(FBSDKHTTPMethod)method +{ return [self initWithGraphPath:graphPath parameters:@{} HTTPMethod:method]; } - (instancetype)initWithGraphPath:(NSString *)graphPath - parameters:(NSDictionary *)parameters { + parameters:(NSDictionary *)parameters +{ return [self initWithGraphPath:graphPath parameters:parameters flags:FBSDKGraphRequestFlagNone]; @@ -60,7 +63,8 @@ - (instancetype)initWithGraphPath:(NSString *)graphPath - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters - HTTPMethod:(FBSDKHTTPMethod)method { + HTTPMethod:(FBSDKHTTPMethod)method +{ return [self initWithGraphPath:graphPath parameters:parameters tokenString:[FBSDKAccessToken currentAccessToken].tokenString @@ -70,7 +74,8 @@ - (instancetype)initWithGraphPath:(NSString *)graphPath - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters - flags:(FBSDKGraphRequestFlags)flags { + flags:(FBSDKGraphRequestFlags)flags +{ return [self initWithGraphPath:graphPath parameters:parameters tokenString:[FBSDKAccessToken currentAccessToken].tokenString @@ -82,7 +87,8 @@ - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters tokenString:(NSString *)tokenString HTTPMethod:(FBSDKHTTPMethod)method - flags:(FBSDKGraphRequestFlags)flags { + flags:(FBSDKGraphRequestFlags)flags +{ if ((self = [self initWithGraphPath:graphPath parameters:parameters tokenString:tokenString @@ -97,7 +103,8 @@ - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters tokenString:(NSString *)tokenString version:(NSString *)version - HTTPMethod:(FBSDKHTTPMethod)method { + HTTPMethod:(FBSDKHTTPMethod)method +{ if ((self = [super init])) { _tokenString = tokenString ? [tokenString copy] : nil; _version = version ? [version copy] : [FBSDKSettings graphAPIVersion]; @@ -139,33 +146,35 @@ - (BOOL)hasAttachments + (BOOL)isAttachment:(id)item { - return ([item isKindOfClass:[UIImage class]] || - [item isKindOfClass:[NSData class]] || - [item isKindOfClass:[FBSDKGraphRequestDataAttachment class]]); + return ([item isKindOfClass:[UIImage class]] + || [item isKindOfClass:[NSData class]] + || [item isKindOfClass:[FBSDKGraphRequestDataAttachment class]]); } - + (NSString *)serializeURL:(NSString *)baseUrl - params:(NSDictionary *)params { + params:(NSDictionary *)params +{ return [self serializeURL:baseUrl params:params httpMethod:FBSDKHTTPMethodGET]; } + (NSString *)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params - httpMethod:(NSString *)httpMethod { + httpMethod:(NSString *)httpMethod +{ return [self serializeURL:baseUrl params:params httpMethod:httpMethod forBatch:NO]; } + (NSString *)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params httpMethod:(NSString *)httpMethod - forBatch:(BOOL)forBatch { - params = [self preprocessParams: params]; + forBatch:(BOOL)forBatch +{ + params = [self preprocessParams:params]; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSURL *parsedURL = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; -#pragma clang pop + #pragma clang pop if ([httpMethod isEqualToString:FBSDKHTTPMethodPOST] && !forBatch) { return baseUrl; @@ -173,7 +182,7 @@ + (NSString *)serializeURL:(NSString *)baseUrl NSString *queryPrefix = parsedURL.query ? @"&" : @"?"; - NSString *query = [FBSDKBasicUtility queryStringWithDictionary:params error:NULL invalidObjectHandler:^id(id object, BOOL *stop) { + NSString *query = [FBSDKBasicUtility queryStringWithDictionary:params error:NULL invalidObjectHandler:^id (id object, BOOL *stop) { if ([self isAttachment:object]) { if ([httpMethod isEqualToString:FBSDKHTTPMethodGET]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"can not use GET to upload a file"]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m index 1e029a5cba..f95b6a86e3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m @@ -31,7 +31,6 @@ #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings+Internal.h" -#import "FBSDKURLSessionTask.h" NSString *const FBSDKNonJSONResponseProperty = @"FACEBOOK_NON_JSON_RESULT"; @@ -73,21 +72,21 @@ return [[FBSDKAccessToken alloc] initWithTokenString:accessToken.tokenString permissions:accessToken.permissions.allObjects declinedPermissions:accessToken.declinedPermissions.allObjects - expiredPermissions:accessToken.expiredPermissions.allObjects + expiredPermissions:accessToken.expiredPermissions.allObjects appID:accessToken.appID userID:accessToken.userID expirationDate:expirationDate refreshDate:expirationDate - dataAccessExpirationDate:expirationDate + dataAccessExpirationDate:expirationDate graphDomain:accessToken.graphDomain]; } + #endif // ---------------------------------------------------------------------------- // FBSDKGraphRequestConnectionState -typedef NS_ENUM(NSUInteger, FBSDKGraphRequestConnectionState) -{ +typedef NS_ENUM(NSUInteger, FBSDKGraphRequestConnectionState) { kStateCreated, kStateSerialized, kStateStarted, @@ -99,9 +98,9 @@ typedef NS_ENUM(NSUInteger, FBSDKGraphRequestConnectionState) // Private properties and methods @interface FBSDKGraphRequestConnection () < -NSURLSessionDataDelegate + NSURLSessionDataDelegate #if !TARGET_OS_TV -, FBSDKGraphErrorRecoveryProcessorDelegate + , FBSDKGraphErrorRecoveryProcessorDelegate #endif > @@ -153,27 +152,28 @@ + (void)setDefaultConnectionTimeout:(NSTimeInterval)defaultTimeout } } -+ (NSTimeInterval)defaultConnectionTimeout { ++ (NSTimeInterval)defaultConnectionTimeout +{ return g_defaultTimeout; } -- (void)addRequest:(FBSDKGraphRequest *)request - completionHandler:(FBSDKGraphRequestBlock)handler +- (void) addRequest:(FBSDKGraphRequest *)request + completionHandler:(FBSDKGraphRequestBlock)handler { [self addRequest:request batchEntryName:@"" completionHandler:handler]; } -- (void)addRequest:(FBSDKGraphRequest *)request - batchEntryName:(NSString *)name - completionHandler:(FBSDKGraphRequestBlock)handler +- (void) addRequest:(FBSDKGraphRequest *)request + batchEntryName:(NSString *)name + completionHandler:(FBSDKGraphRequestBlock)handler { NSDictionary *batchParams = name.length > 0 ? @{kBatchEntryName : name } : nil; [self addRequest:request batchParameters:batchParams completionHandler:handler]; } -- (void)addRequest:(FBSDKGraphRequest *)request - batchParameters:(NSDictionary *)batchParameters - completionHandler:(FBSDKGraphRequestBlock)handler +- (void) addRequest:(FBSDKGraphRequest *)request + batchParameters:(NSDictionary *)batchParameters + completionHandler:(FBSDKGraphRequestBlock)handler { if (self.state != kStateCreated) { @throw [NSException exceptionWithName:NSInternalInconsistencyException @@ -219,7 +219,7 @@ - (void)start return; } - //optimistically check for updated server configuration; + // optimistically check for updated server configuration; g_errorConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration].errorConfiguration ?: g_errorConfiguration; if (self.state != kStateCreated && self.state != kStateSerialized) { @@ -244,8 +244,8 @@ - (void)start networkError:errorV2]; }; - if(errorV1) { - [self taskDidCompleteWithError:errorV1 handler:handler]; + if (errorV1) { + [self _taskDidCompleteWithError:errorV1 handler:handler]; } else { [self taskDidCompleteWithResponse:responseV1 data:responseDataV1 requestStartTime:self.requestStartTime handler:handler]; } @@ -277,7 +277,7 @@ - (void)setDelegateQueue:(NSOperationQueue *)queue - (FBSDKURLSession *)session { - return _session; + return _session; } #pragma mark - Private methods (request generation) @@ -370,8 +370,8 @@ - (void)appendJSONRequests:(NSArray *)requests for (FBSDKGraphRequestMetadata *metadata in requests) { NSString *individualToken = [self accessTokenWithRequest:metadata.request]; BOOL isClientToken = [FBSDKSettings clientToken] && [individualToken hasSuffix:[FBSDKSettings clientToken]]; - if (!batchToken && - !isClientToken) { + if (!batchToken + && !isClientToken) { batchToken = individualToken; } [self addRequest:metadata @@ -410,10 +410,10 @@ - (void)_validateFieldsParamForGetRequests:(NSArray *)requests { for (FBSDKGraphRequestMetadata *metadata in requests) { FBSDKGraphRequest *request = metadata.request; - if ([request.HTTPMethod.uppercaseString isEqualToString:@"GET"] && - [self _shouldWarnOnMissingFieldsParam:request] && - !request.parameters[@"fields"] && - [request.graphPath rangeOfString:@"fields="].location == NSNotFound) { + if ([request.HTTPMethod.uppercaseString isEqualToString:@"GET"] + && [self _shouldWarnOnMissingFieldsParam:request] + && !request.parameters[@"fields"] + && [request.graphPath rangeOfString:@"fields="].location == NSNotFound) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"starting with Graph API v2.4, GET requests for /%@ should contain an explicit \"fields\" parameter", request.graphPath]; } @@ -439,7 +439,6 @@ - (NSMutableURLRequest *)requestWithBatch:(NSArray *)requests reason:@"FBSDKGraphRequestConnection: Must have at least one request or urlRequest not specified." userInfo:nil] raise]; - } [self _validateFieldsParamForGetRequests:requests]; @@ -548,8 +547,8 @@ - (NSString *)urlStringForSingleRequest:(FBSDKGraphRequest *)request forBatch:(B // We special case a graph post to /videos and send it to graph-video.facebook.com // We only do this for non batch post requests NSString *graphPath = request.graphPath.lowercaseString; - if ([request.HTTPMethod.uppercaseString isEqualToString:@"POST"] && - [graphPath hasSuffix:@"/videos"]) { + if ([request.HTTPMethod.uppercaseString isEqualToString:@"POST"] + && [graphPath hasSuffix:@"/videos"]) { graphPath = [graphPath stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]]; NSArray *components = [graphPath componentsSeparatedByString:@"/"]; if (components.count == 2) { @@ -558,11 +557,11 @@ - (NSString *)urlStringForSingleRequest:(FBSDKGraphRequest *)request forBatch:(B } baseURL = [FBSDKInternalUtility - facebookURLWithHostPrefix:prefix - path:request.graphPath - queryParameters:@{} - defaultVersion:request.version - error:NULL].absoluteString; + facebookURLWithHostPrefix:prefix + path:request.graphPath + queryParameters:@{} + defaultVersion:request.version + error:NULL].absoluteString; } NSString *url = [FBSDKGraphRequest serializeURL:baseURL @@ -579,20 +578,24 @@ - (void)completeFBSDKURLSessionWithResponse:(NSURLResponse *)response networkError:(NSError *)error { if (self.state != kStateCancelled) { - NSAssert(self.state == kStateStarted, - @"Unexpected state %lu in completeWithResponse", - (unsigned long)self.state); + NSAssert( + self.state == kStateStarted, + @"Unexpected state %lu in completeWithResponse", + (unsigned long)self.state + ); self.state = kStateCompleted; } NSArray *results = nil; _urlResponse = (NSHTTPURLResponse *)response; if (response) { - NSAssert([response isKindOfClass:[NSHTTPURLResponse class]], - @"Expected NSHTTPURLResponse, got %@", - response); + NSAssert( + [response isKindOfClass:[NSHTTPURLResponse class]], + @"Expected NSHTTPURLResponse, got %@", + response + ); -NSInteger statusCode = _urlResponse.statusCode; + NSInteger statusCode = _urlResponse.statusCode; if (!error && [response.MIMEType hasPrefix:@"image"]) { error = [FBSDKError errorWithCode:FBSDKErrorGraphRequestNonTextMimeTypeReturned @@ -629,7 +632,7 @@ - (void)completeFBSDKURLSessionWithResponse:(NSURLResponse *)response } [_logger emitToNSLog]; - [self completeWithResults:results networkError:error]; + [self _completeWithResults:results networkError:error]; [self.session invalidateAndCancel]; } @@ -638,10 +641,10 @@ - (void)completeFBSDKURLSessionWithResponse:(NSURLResponse *)response // If there is one request, the JSON is the response. // If there are multiple requests, the JSON has an array of dictionaries whose // body property is the response. -// [{ "code":200, -// "body":"JSON-response-as-a-string" }, -// { "code":200, -// "body":"JSON-response-as-a-string" }] +// [{ "code":200, +// "body":"JSON-response-as-a-string" }, +// { "code":200, +// "body":"JSON-response-as-a-string" }] // // In both cases, this function returns an NSArray containing the results. // The NSArray looks just like the multiple request case except the body @@ -668,19 +671,19 @@ - (NSArray *)parseJSONResponse:(NSData *)data NSDictionary *responseError = nil; if (!response) { if ((error != NULL) && (*error == nil)) { - *error = [self errorWithCode:FBSDKErrorUnknown - statusCode:statusCode - parsedJSONResponse:nil - innerError:nil - message:@"The server returned an unexpected response."]; + *error = [self _errorWithCode:FBSDKErrorUnknown + statusCode:statusCode + parsedJSONResponse:nil + innerError:nil + message:@"The server returned an unexpected response."]; } } else if (self.requests.count == 1) { // response is the entry, so put it in a dictionary under "body" and add // that to array of responses. [FBSDKTypeUtility array:results addObject:@{ - @"code":@(statusCode), - @"body":response - }]; + @"code" : @(statusCode), + @"body" : response + }]; } else if ([response isKindOfClass:[NSArray class]]) { // response is the array of responses, but the body element of each needs // to be decoded from JSON. @@ -701,35 +704,38 @@ - (NSArray *)parseJSONResponse:(NSData *)data *error = batchResultError; } } - } else if ([response isKindOfClass:[NSDictionary class]] && - (responseError = [FBSDKTypeUtility dictionaryValue:response[@"error"]]) != nil && - [responseError[@"type"] isEqualToString:@"OAuthException"]) { + } else if ([response isKindOfClass:[NSDictionary class]] + && (responseError = [FBSDKTypeUtility dictionaryValue:response[@"error"]]) != nil + && [responseError[@"type"] isEqualToString:@"OAuthException"]) { // if there was one request then return the only result. if there were multiple requests // but only one error then the server rejected the batch access token NSDictionary *result = @{ - @"code":@(statusCode), - @"body":response - }; + @"code" : @(statusCode), + @"body" : response + }; for (NSUInteger resultIndex = 0, resultCount = self.requests.count; resultIndex < resultCount; ++resultIndex) { [FBSDKTypeUtility array:results addObject:result]; } } else if (error != NULL) { - *error = [self errorWithCode:FBSDKErrorGraphRequestProtocolMismatch - statusCode:statusCode - parsedJSONResponse:results - innerError:nil - message:nil]; + *error = [self _errorWithCode:FBSDKErrorGraphRequestProtocolMismatch + statusCode:statusCode + parsedJSONResponse:results + innerError:nil + message:nil]; } return results; } -- (id)parseJSONOrOtherwise:(NSString *)utf8 +- (id)parseJSONOrOtherwise:(NSString *)unsafeString error:(NSError **)error { id parsed = nil; - if (!(*error) && [utf8 isKindOfClass:[NSString class]]) { + + // Historically, people have passed-in `id` here. So, gotta double-check. + NSString *const utf8 = FBSDK_CAST_TO_CLASS_OR_NIL(unsafeString, NSString); + if (!(*error) && utf8) { parsed = [FBSDKBasicUtility objectForJSONString:utf8 error:error]; // if we fail parse we attempt a re-parse of a modified input to support results in the form "foo=bar", "true", etc. // which is shouldn't be necessary since Graph API v2.1. @@ -737,10 +743,15 @@ - (id)parseJSONOrOtherwise:(NSString *)utf8 // we round-trip our hand-wired response through the parser in order to remain // consistent with the rest of the output of this function (note, if perf turns out // to be a problem -- unlikely -- we can return the following dictionary outright) - NSDictionary *original = @{ FBSDKNonJSONResponseProperty : utf8 }; - NSString *jsonrep = [FBSDKBasicUtility JSONStringForObject:original error:NULL invalidObjectHandler:NULL]; NSError *reparseError = nil; - parsed = [FBSDKBasicUtility objectForJSONString:jsonrep error:&reparseError]; + parsed = + [FBSDKBasicUtility + objectForJSONString: + [FBSDKBasicUtility JSONStringForObject:@{ FBSDKNonJSONResponseProperty : utf8 } + error:NULL + invalidObjectHandler:NULL] + error:&reparseError]; + if (!reparseError) { *error = nil; } @@ -749,8 +760,8 @@ - (id)parseJSONOrOtherwise:(NSString *)utf8 return parsed; } -- (void)completeWithResults:(NSArray *)results - networkError:(NSError *)networkError +- (void)_completeWithResults:(NSArray *)results + networkError:(NSError *)networkError { NSUInteger count = self.requests.count; _expectingResults = count; @@ -766,7 +777,7 @@ - (void)completeWithResults:(NSArray *)results [self.requests enumerateObjectsUsingBlock:^(FBSDKGraphRequestMetadata *metadata, NSUInteger i, BOOL *stop) { id result = networkError ? nil : [FBSDKTypeUtility array:results objectAtIndex:i]; - NSError *resultError = networkError ?: [self errorFromResult:result request:metadata.request]; + NSError *const resultError = networkError ?: errorFromResult(result, metadata.request); id body = nil; if (!resultError && [result isKindOfClass:[NSDictionary class]]) { @@ -774,7 +785,7 @@ - (void)completeWithResults:(NSArray *)results body = [FBSDKTypeUtility dictionaryValue:resultDictionary[@"body"]]; } -#if !TARGET_OS_TV + #if !TARGET_OS_TV if (resultError && !metadata.request.graphErrorRecoveryDisabled && isSingleRequestToRecover) { self->_recoveringRequestMetadata = metadata; self->_errorRecoveryProcessor = [[FBSDKGraphErrorRecoveryProcessor alloc] init]; @@ -782,7 +793,7 @@ - (void)completeWithResults:(NSArray *)results return; } } -#endif + #endif [self processResultBody:body error:resultError metadata:metadata canNotifyDelegate:networkError == nil]; }]; @@ -799,7 +810,7 @@ - (void)processResultBody:(NSDictionary *)body error:(NSError *)error metadata:( void (^finishAndInvokeCompletionHandler)(void) = ^{ NSDictionary *graphDebugDict = body[@"__debug__"]; if ([graphDebugDict isKindOfClass:[NSDictionary class]]) { - [self processResultDebugDictionary: graphDebugDict]; + [self processResultDebugDictionary:graphDebugDict]; } [metadata invokeCompletionHandlerForConnection:self withResults:body error:error]; @@ -811,7 +822,7 @@ - (void)processResultBody:(NSDictionary *)body error:(NSError *)error metadata:( }; #if !TARGET_OS_TV - void (^clearToken)(NSInteger) = ^(NSInteger errorSubcode){ + void (^clearToken)(NSInteger) = ^(NSInteger errorSubcode) { if (metadata.request.flags & FBSDKGraphRequestFlagDoNotInvalidateTokenOnError) { return; } @@ -820,7 +831,6 @@ - (void)processResultBody:(NSDictionary *)body error:(NSError *)error metadata:( } else { [FBSDKAccessToken setCurrentAccessToken:nil]; } - }; NSString *metadataTokenString = metadata.request.tokenString; @@ -864,58 +874,65 @@ - (void)processResultDebugDictionary:(NSDictionary *)dict [FBSDKLogger singleShotLogEntry:loggingBehavior logEntry:message]; }]; - } -- (NSError *)errorFromResult:(id)result request:(FBSDKGraphRequest *)request +static NSError *_Nullable errorFromResult(id untypedParam, FBSDKGraphRequest *request) { - if ([result isKindOfClass:[NSDictionary class]]) { - NSDictionary *errorDictionary = [FBSDKTypeUtility dictionaryValue:result[@"body"]][@"error"]; - - if ([errorDictionary isKindOfClass:[NSDictionary class]]) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"code"] forKey:FBSDKGraphRequestErrorGraphErrorCodeKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_subcode"] forKey:FBSDKGraphRequestErrorGraphErrorSubcodeKey]; - //"message" is preferred over error_msg or error_reason. - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_msg"] forKey:FBSDKErrorDeveloperMessageKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"message"] forKey:FBSDKErrorDeveloperMessageKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_user_title"] forKey:FBSDKErrorLocalizedTitleKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:FBSDKErrorLocalizedDescriptionKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:NSLocalizedDescriptionKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:result[@"code"] forKey:FBSDKGraphRequestErrorHTTPStatusCodeKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:result forKey:FBSDKGraphRequestErrorParsedJSONResponseKey]; - - FBSDKErrorRecoveryConfiguration *recoveryConfiguration = [g_errorConfiguration - recoveryConfigurationForCode:[userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] stringValue] - subcode:[userInfo[FBSDKGraphRequestErrorGraphErrorSubcodeKey] stringValue] - request:request]; - if ([errorDictionary[@"is_transient"] boolValue]) { - [FBSDKTypeUtility dictionary:userInfo setObject:@(FBSDKGraphRequestErrorTransient) forKey:FBSDKGraphRequestErrorKey]; - } else { - [FBSDKTypeUtility dictionary:userInfo setObject:@(recoveryConfiguration.errorCategory) forKey:FBSDKGraphRequestErrorKey]; - } - [FBSDKTypeUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryDescription forKey:NSLocalizedRecoverySuggestionErrorKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryOptionDescriptions forKey:NSLocalizedRecoveryOptionsErrorKey]; - FBSDKErrorRecoveryAttempter *attempter = [FBSDKErrorRecoveryAttempter recoveryAttempterFromConfiguration:recoveryConfiguration]; - [FBSDKTypeUtility dictionary:userInfo setObject:attempter forKey:NSRecoveryAttempterErrorKey]; - - return [FBSDKError errorWithCode:FBSDKErrorGraphRequestGraphAPI - userInfo:userInfo - message:nil - underlyingError:nil]; - } + NSDictionary *const result = FBSDK_CAST_TO_CLASS_OR_NIL(untypedParam, NSDictionary); + if (!result) { + return nil; + } + + NSDictionary *const body = FBSDK_CAST_TO_CLASS_OR_NIL(result[@"body"], NSDictionary); + if (!body) { + return nil; + } + + NSDictionary *const errorDictionary = FBSDK_CAST_TO_CLASS_OR_NIL(body[@"error"], NSDictionary); + if (!errorDictionary) { + return nil; } - return nil; + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"code"] forKey:FBSDKGraphRequestErrorGraphErrorCodeKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_subcode"] forKey:FBSDKGraphRequestErrorGraphErrorSubcodeKey]; + // "message" is preferred over error_msg or error_reason. + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_msg"] forKey:FBSDKErrorDeveloperMessageKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"message"] forKey:FBSDKErrorDeveloperMessageKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_user_title"] forKey:FBSDKErrorLocalizedTitleKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:FBSDKErrorLocalizedDescriptionKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:NSLocalizedDescriptionKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:result[@"code"] forKey:FBSDKGraphRequestErrorHTTPStatusCodeKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:result forKey:FBSDKGraphRequestErrorParsedJSONResponseKey]; + + FBSDKErrorRecoveryConfiguration *recoveryConfiguration = [g_errorConfiguration + recoveryConfigurationForCode:[userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] stringValue] + subcode:[userInfo[FBSDKGraphRequestErrorGraphErrorSubcodeKey] stringValue] + request:request]; + if ([errorDictionary[@"is_transient"] boolValue]) { + [FBSDKTypeUtility dictionary:userInfo setObject:@(FBSDKGraphRequestErrorTransient) forKey:FBSDKGraphRequestErrorKey]; + } else { + [FBSDKTypeUtility dictionary:userInfo setObject:@(recoveryConfiguration.errorCategory) forKey:FBSDKGraphRequestErrorKey]; + } + [FBSDKTypeUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryDescription forKey:NSLocalizedRecoverySuggestionErrorKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryOptionDescriptions forKey:NSLocalizedRecoveryOptionsErrorKey]; + FBSDKErrorRecoveryAttempter *attempter = [FBSDKErrorRecoveryAttempter recoveryAttempterFromConfiguration:recoveryConfiguration]; + [FBSDKTypeUtility dictionary:userInfo setObject:attempter forKey:NSRecoveryAttempterErrorKey]; + + return [FBSDKError errorWithCode:FBSDKErrorGraphRequestGraphAPI + userInfo:userInfo + message:nil + underlyingError:nil]; } -- (NSError *)errorWithCode:(FBSDKCoreError)code - statusCode:(NSInteger)statusCode - parsedJSONResponse:(id)response - innerError:(NSError *)innerError - message:(NSString *)message { - NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; +- (NSError *)_errorWithCode:(FBSDKCoreError)code + statusCode:(NSInteger)statusCode + parsedJSONResponse:(id)response + innerError:(NSError *)innerError + message:(NSString *)message +{ + NSMutableDictionary *const userInfo = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:userInfo setObject:@(statusCode) forKey:FBSDKGraphRequestErrorHTTPStatusCodeKey]; if (response) { @@ -930,12 +947,11 @@ - (NSError *)errorWithCode:(FBSDKCoreError)code [FBSDKTypeUtility dictionary:userInfo setObject:message forKey:FBSDKErrorDeveloperMessageKey]; } - NSError *error = [[NSError alloc] - initWithDomain:FBSDKErrorDomain - code:code - userInfo:userInfo]; - - return error; + return + [[NSError alloc] + initWithDomain:FBSDKErrorDomain + code:code + userInfo:userInfo]; } #pragma mark - Private methods (logging and completion) @@ -1009,8 +1025,10 @@ - (void)taskDidCompleteWithResponse:(NSURLResponse *)response } @finally {} } -- (void)taskDidCompleteWithError:(NSError *)error - handler:(FBSDKURLSessionTaskBlock)handler +#pragma mark - Private methods (miscellaneous) + +- (void)_taskDidCompleteWithError:(NSError *)error + handler:(FBSDKURLSessionTaskBlock)handler { @try { if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == kCFURLErrorSecureConnectionFailed) { @@ -1025,8 +1043,6 @@ - (void)taskDidCompleteWithError:(NSError *)error } @finally {} } -#pragma mark - Private methods (miscellaneous) - - (void)logRequest:(NSMutableURLRequest *)request bodyLength:(NSUInteger)bodyLength bodyLogger:(FBSDKLogger *)bodyLogger @@ -1096,15 +1112,16 @@ + (NSString *)userAgent return agentWithSuffix ?: agent; } + #pragma clang diagnostic pop #pragma mark - NSURLSessionDataDelegate -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task - didSendBodyData:(int64_t)bytesSent - totalBytesSent:(int64_t)totalBytesSent -totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend +- (void) URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task + didSendBodyData:(int64_t)bytesSent + totalBytesSent:(int64_t)totalBytesSent + totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { id delegate = self.delegate; @@ -1121,27 +1138,30 @@ - (void)URLSession:(NSURLSession *)session #if !TARGET_OS_TV - (void)processorDidAttemptRecovery:(FBSDKGraphErrorRecoveryProcessor *)processor didRecover:(BOOL)didRecover error:(NSError *)error { - if (didRecover) { - FBSDKGraphRequest *originalRequest = _recoveringRequestMetadata.request; - FBSDKGraphRequest *retryRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:originalRequest.graphPath - parameters:originalRequest.parameters - tokenString:[FBSDKAccessToken currentAccessToken].tokenString - version:originalRequest.version - HTTPMethod:originalRequest.HTTPMethod]; - // prevent further attempts at recovery (i.e., additional retries). - [retryRequest setGraphErrorRecoveryDisabled:YES]; - FBSDKGraphRequestMetadata *retryMetadata = [[FBSDKGraphRequestMetadata alloc] initWithRequest:retryRequest completionHandler:_recoveringRequestMetadata.completionHandler batchParameters:_recoveringRequestMetadata.batchParameters]; - [retryRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *retriedError) { - [self processResultBody:result error:retriedError metadata:retryMetadata canNotifyDelegate:YES]; - self->_errorRecoveryProcessor = nil; - self->_recoveringRequestMetadata = nil; - }]; - } else { - [self processResultBody:nil error:error metadata:_recoveringRequestMetadata canNotifyDelegate:YES]; - _errorRecoveryProcessor = nil; - _recoveringRequestMetadata = nil; - } + @try { + if (didRecover) { + FBSDKGraphRequest *originalRequest = _recoveringRequestMetadata.request; + FBSDKGraphRequest *retryRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:originalRequest.graphPath + parameters:originalRequest.parameters + tokenString:[FBSDKAccessToken currentAccessToken].tokenString + version:originalRequest.version + HTTPMethod:originalRequest.HTTPMethod]; + // prevent further attempts at recovery (i.e., additional retries). + [retryRequest setGraphErrorRecoveryDisabled:YES]; + FBSDKGraphRequestMetadata *retryMetadata = [[FBSDKGraphRequestMetadata alloc] initWithRequest:retryRequest completionHandler:_recoveringRequestMetadata.completionHandler batchParameters:_recoveringRequestMetadata.batchParameters]; + [retryRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *retriedError) { + [self processResultBody:result error:retriedError metadata:retryMetadata canNotifyDelegate:YES]; + self->_errorRecoveryProcessor = nil; + self->_recoveringRequestMetadata = nil; + }]; + } else { + [self processResultBody:nil error:error metadata:_recoveringRequestMetadata canNotifyDelegate:YES]; + _errorRecoveryProcessor = nil; + _recoveringRequestMetadata = nil; + } + } @catch (NSException *exception) {} } + #endif #pragma mark - Debugging helpers @@ -1163,7 +1183,6 @@ - (NSString *)description } [result appendString:@"\n)>"]; return result; - } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m index dd81d5a3a1..c4c27c46d6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m @@ -67,7 +67,7 @@ - (NSData *)decodeAsData:(NSString *)string int needPadding = string.length % 4; if (needPadding > 0) { needPadding = 4 - needPadding; - string = [string stringByPaddingToLength:string.length+needPadding withString:@"=" startingAtIndex:0]; + string = [string stringByPaddingToLength:string.length + needPadding withString:@"=" startingAtIndex:0]; } return [[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI+Internal.h new file mode 100644 index 0000000000..23bcc0e471 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI+Internal.h @@ -0,0 +1,31 @@ +// 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 "FBSDKBridgeAPI.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKBridgeAPI (Internal) + +- (void)openURLWithAuthenticationSession:(NSURL *)url; +- (void)setSessionCompletionHandlerFromHandler:(void (^)(BOOL, NSError *))handler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 9a4c9529f1..0cc83ae657 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -20,9 +20,25 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPI.h" - -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKBridgeAPI.h" + + #import "FBSDKCoreKit+Internal.h" + +/** + Specifies state of FBSDKAuthenticationSession (SFAuthenticationSession (iOS 11) and ASWebAuthenticationSession (iOS 12+)) + */ +typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { + /** There is no active authentication session*/ + FBSDKAuthenticationSessionNone, + /** The authentication session has started*/ + FBSDKAuthenticationSessionStarted, + /** System dialog ("app wants to use facebook.com to sign in") to access facebook.com was presented to the user*/ + FBSDKAuthenticationSessionShowAlert, + /** Web browser with log in to authentication was presented to the user*/ + FBSDKAuthenticationSessionShowWebBrowser, + /** Authentication session was canceled by system. It happens when app goes to background while alert requesting access to facebook.com is presented*/ + FBSDKAuthenticationSessionCanceledBySystem, +}; typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); @@ -36,16 +52,17 @@ - (void)setPresentationContextProvider:(id)presentationContextProvider; @end -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 -#import -@interface FBSDKBridgeAPI() -#else -@interface FBSDKBridgeAPI() -#endif + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 + #import +@interface FBSDKBridgeAPI () + #else +@interface FBSDKBridgeAPI () + #endif @end -@implementation FBSDKBridgeAPI { +@implementation FBSDKBridgeAPI +{ FBSDKBridgeAPIRequest *_pendingRequest; FBSDKBridgeAPIResponseBlock _pendingRequestCompletionBlock; id _pendingURLOpen; @@ -53,10 +70,10 @@ @implementation FBSDKBridgeAPI { FBSDKAuthenticationCompletionHandler _authenticationSessionCompletionHandler NS_AVAILABLE_IOS(11_0); BOOL _expectingBackground; - BOOL _isRequestingSFAuthenticationSession; UIViewController *_safariViewController; BOOL _isDismissingSafariViewController; BOOL _isAppLaunched; + FBSDKAuthenticationSession _authenticationSessionState; } + (void)load @@ -74,19 +91,18 @@ + (FBSDKBridgeAPI *)sharedInstance return _sharedInstance; } +- (void)applicationWillResignActive:(UIApplication *)application +{ + [self _updateAuthStateIfSystemAlertToUseWebAuthFlowPresented]; +} + - (void)applicationDidBecomeActive:(UIApplication *)application { + BOOL isRequestingWebAuthenticationSession = NO; if (@available(iOS 11.0, *)) { - if (_active && _authenticationSession) { - // applicationDidBecomeActive: is called after tapping Continue or Cancel in the "{app name} wants to use facebook.com to Sign In" alert. - // authenticationSession will be nil when it's Cancel. - _isRequestingSFAuthenticationSession = YES; - } else if (_active && !_authenticationSession) { - // In theory, this should be done whenever authenticationSession is set to nil, but just in case. - _isRequestingSFAuthenticationSession = NO; - } else if (!_active && !_isRequestingSFAuthenticationSession && _authenticationSession) { - // Handle the case where the app is backgrounded while the "ExampleApp wants to use facebook.com to Sign In" alert is still open - // Call the completion handler with a Cancel + if (_authenticationSession && _authenticationSessionState == FBSDKAuthenticationSessionShowAlert) { + _authenticationSessionState = FBSDKAuthenticationSessionShowWebBrowser; + } else if (_authenticationSession && _authenticationSessionState == FBSDKAuthenticationSessionCanceledBySystem) { [_authenticationSession cancel]; _authenticationSession = nil; NSString *errorDomain; @@ -97,12 +113,13 @@ - (void)applicationDidBecomeActive:(UIApplication *)application } NSError *error = [FBSDKError errorWithDomain:errorDomain code:1 message:nil]; _authenticationSessionCompletionHandler(nil, error); + isRequestingWebAuthenticationSession = [self _isRequestingWebAuthenticationSession]; } } - // _expectingBackground can be YES if the caller started doing work (like login) + // _expectingBackground can be YES if the caller started doing work (like login) // within the app delegate's lifecycle like openURL, in which case there // might have been a "didBecomeActive" event pending that we want to ignore. - BOOL notExpectingBackground = !_expectingBackground && !_safariViewController && !_isDismissingSafariViewController && !_isRequestingSFAuthenticationSession; + BOOL notExpectingBackground = !_expectingBackground && !_safariViewController && !_isDismissingSafariViewController && !isRequestingWebAuthenticationSession; if (notExpectingBackground) { _active = YES; @@ -117,6 +134,7 @@ - (void)applicationDidEnterBackground:(UIApplication *)application { _active = NO; _expectingBackground = NO; + [self _updateAuthStateIfSystemCancelAuthSession]; } - (BOOL)application:(UIApplication *)application @@ -167,7 +185,7 @@ - (BOOL)application:(UIApplication *)application NSError *loginError = [[NSError alloc] initWithDomain:FBSDKErrorDomain code:FBSDKErrorBridgeAPIInterruption - userInfo:@{FBSDKErrorLocalizedDescriptionKey: errorMessage}]; + userInfo:@{FBSDKErrorLocalizedDescriptionKey : errorMessage}]; _authenticationSessionCompletionHandler(url, loginError); _authenticationSessionCompletionHandler = nil; } @@ -187,14 +205,14 @@ - (BOOL)application:(UIApplication *)application return NO; } -- (BOOL)application:(UIApplication *)application -didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +- (BOOL) application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSURL *launchedURL = launchOptions[UIApplicationLaunchOptionsURLKey]; NSString *sourceApplication = launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]; - if (launchedURL && - sourceApplication) { + if (launchedURL + && sourceApplication) { Class loginManagerClass = NSClassFromString(@"FBSDKLoginManager"); if (loginManagerClass) { id annotation = launchOptions[UIApplicationLaunchOptionsAnnotationKey]; @@ -209,10 +227,32 @@ - (BOOL)application:(UIApplication *)application return NO; } -#pragma mark - Internal Methods +- (void)_updateAuthStateIfSystemAlertToUseWebAuthFlowPresented +{ + if (@available(iOS 11.0, *)) { + if (_authenticationSession && _authenticationSessionState == FBSDKAuthenticationSessionStarted) { + _authenticationSessionState = FBSDKAuthenticationSessionShowAlert; + } + } +} -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void)_updateAuthStateIfSystemCancelAuthSession +{ + if (@available(iOS 11.0, *)) { + if (_authenticationSession && _authenticationSessionState == FBSDKAuthenticationSessionShowAlert) { + _authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; + } + } +} + +- (BOOL)_isRequestingWebAuthenticationSession +{ + return !(_authenticationSessionState == FBSDKAuthenticationSessionNone + || _authenticationSessionState == FBSDKAuthenticationSessionCanceledBySystem); +} + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (void)openURL:(NSURL *)url sender:(id)sender handler:(FBSDKSuccessBlock)handler { _expectingBackground = YES; @@ -243,7 +283,8 @@ - (void)openURL:(NSURL *)url sender:(id)sender handler:(FBSDKSu } }); } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop - (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request useSafariViewController:(BOOL)useSafariViewController @@ -302,8 +343,8 @@ - (void)openURLWithSafariViewController:(NSURL *)url if (@available(iOS 11.0, *)) { if ([sender isAuthenticationURL:url]) { - [self _setSessionCompletionHandlerFromHandler:handler]; - [self _openURLWithAuthenticationSession:url]; + [self setSessionCompletionHandlerFromHandler:handler]; + [self openURLWithAuthenticationSession:url]; return; } } @@ -356,7 +397,7 @@ - (void)openURLWithSafariViewController:(NSURL *)url } } -- (void)_openURLWithAuthenticationSession:(NSURL *)url +- (void)openURLWithAuthenticationSession:(NSURL *)url { Class AuthenticationSessionClass = fbsdkdfl_ASWebAuthenticationSessionClass(); @@ -378,16 +419,16 @@ - (void)_openURLWithAuthenticationSession:(NSURL *)url [_authenticationSession setPresentationContextProvider:self]; } } + _authenticationSessionState = FBSDKAuthenticationSessionStarted; [_authenticationSession start]; } } -- (void)_setSessionCompletionHandlerFromHandler:(void(^)(BOOL, NSError *))handler +- (void)setSessionCompletionHandlerFromHandler:(void (^)(BOOL, NSError *))handler { __weak FBSDKBridgeAPI *weakSelf = self; - _authenticationSessionCompletionHandler = ^ (NSURL *aURL, NSError *error) { + _authenticationSessionCompletionHandler = ^(NSURL *aURL, NSError *error) { FBSDKBridgeAPI *strongSelf = weakSelf; - strongSelf->_isRequestingSFAuthenticationSession = NO; BOOL didSucceed = (error == nil && aURL != nil); handler(didSucceed, error); if (didSucceed) { @@ -395,10 +436,11 @@ - (void)_setSessionCompletionHandlerFromHandler:(void(^)(BOOL, NSError *))handle } strongSelf->_authenticationSession = nil; strongSelf->_authenticationSessionCompletionHandler = nil; + strongSelf->_authenticationSessionState = FBSDKAuthenticationSessionNone; }; } -#pragma mark -- SFSafariViewControllerDelegate + #pragma mark -- SFSafariViewControllerDelegate // This means the user tapped "Done" which we should treat as a cancellation. - (void)safariViewControllerDidFinish:(UIViewController *)safariViewController @@ -417,7 +459,7 @@ - (void)safariViewControllerDidFinish:(UIViewController *)safariViewController _safariViewController = nil; } -#pragma mark -- FBSDKContainerViewControllerDelegate + #pragma mark -- FBSDKContainerViewControllerDelegate - (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated { @@ -430,7 +472,7 @@ - (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewControlle } } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication { @@ -475,17 +517,18 @@ - (void)_cancelBridgeRequest _pendingRequestCompletionBlock = NULL; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#pragma mark - ASWebAuthenticationPresentationContextProviding -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 -- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)){ -#else + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma mark - ASWebAuthenticationPresentationContextProviding + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 +- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)) +{ + #else - (UIWindow *)presentationAnchorForWebAuthenticationSession:(id)session API_AVAILABLE(ios(11.0)) { #endif return UIApplication.sharedApplication.keyWindow; } -#pragma clang diagnostic pop + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h index 74c7809af1..8f39a7a672 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h @@ -20,8 +20,8 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPIProtocol.h" -#import "FBSDKBridgeAPIRequest.h" + #import "FBSDKBridgeAPIProtocol.h" + #import "FBSDKBridgeAPIRequest.h" @interface FBSDKBridgeAPIRequest () @@ -32,9 +32,9 @@ methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters userInfo:(NSDictionary *)userInfo -NS_DESIGNATED_INITIALIZER; + NS_DESIGNATED_INITIALIZER; -@property (nonatomic, strong, readonly) id protocol; +@property (nonatomic, readonly, strong) id protocol; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.m index cbff6f8f83..b051ea46d3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.m @@ -20,14 +20,14 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPIRequest.h" -#import "FBSDKBridgeAPIRequest+Private.h" + #import "FBSDKBridgeAPIRequest.h" + #import "FBSDKBridgeAPIRequest+Private.h" -#import "FBSDKBridgeAPIProtocolNativeV1.h" -#import "FBSDKBridgeAPIProtocolWebV1.h" -#import "FBSDKBridgeAPIProtocolWebV2.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKSettings.h" + #import "FBSDKBridgeAPIProtocolNativeV1.h" + #import "FBSDKBridgeAPIProtocolWebV1.h" + #import "FBSDKBridgeAPIProtocolWebV2.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKSettings.h" NSString *const FBSDKBridgeAPIAppIDKey = @"app_id"; NSString *const FBSDKBridgeAPISchemeSuffixKey = @"scheme_suffix"; @@ -35,7 +35,7 @@ @implementation FBSDKBridgeAPIRequest -#pragma mark - Class Methods + #pragma mark - Class Methods + (instancetype)bridgeAPIRequestWithProtocolType:(FBSDKBridgeAPIProtocolType)protocolType scheme:(NSString *)scheme @@ -59,21 +59,21 @@ + (NSDictionary *)protocolMap static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _protocolMap = @{ - @(FBSDKBridgeAPIProtocolTypeNative): @{ - FBSDK_CANOPENURL_FACEBOOK:[[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"fbapi20130214"], - FBSDK_CANOPENURL_MESSENGER:[[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"fb-messenger-share-api"], - FBSDK_CANOPENURL_MSQRD_PLAYER:[[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"msqrdplayer-api20170208"] - }, - @(FBSDKBridgeAPIProtocolTypeWeb): @{ - @"https": [[FBSDKBridgeAPIProtocolWebV1 alloc] init], - @"web": [[FBSDKBridgeAPIProtocolWebV2 alloc] init] - }, - }; + @(FBSDKBridgeAPIProtocolTypeNative) : @{ + FBSDK_CANOPENURL_FACEBOOK : [[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"fbapi20130214"], + FBSDK_CANOPENURL_MESSENGER : [[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"fb-messenger-share-api"], + FBSDK_CANOPENURL_MSQRD_PLAYER : [[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"msqrdplayer-api20170208"] + }, + @(FBSDKBridgeAPIProtocolTypeWeb) : @{ + @"https" : [[FBSDKBridgeAPIProtocolWebV1 alloc] init], + @"web" : [[FBSDKBridgeAPIProtocolWebV2 alloc] init] + }, + }; }); return _protocolMap; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithProtocol:(id)protocol protocolType:(FBSDKBridgeAPIProtocolType)protocolType @@ -100,7 +100,7 @@ - (instancetype)initWithProtocol:(id)protocol return self; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (NSURL *)requestURL:(NSError *__autoreleasing *)errorRef { @@ -120,8 +120,8 @@ - (NSURL *)requestURL:(NSError *__autoreleasing *)errorRef NSMutableDictionary *queryParameters = [[NSMutableDictionary alloc] initWithDictionary:requestQueryParameters]; [FBSDKTypeUtility dictionary:queryParameters setObject:[FBSDKSettings appID] forKey:FBSDKBridgeAPIAppIDKey]; [FBSDKTypeUtility dictionary:queryParameters - setObject:[FBSDKSettings appURLSchemeSuffix] - forKey:FBSDKBridgeAPISchemeSuffixKey]; + setObject:[FBSDKSettings appURLSchemeSuffix] + forKey:FBSDKBridgeAPISchemeSuffixKey]; requestURL = [FBSDKInternalUtility URLWithScheme:requestURL.scheme host:requestURL.host path:requestURL.path @@ -130,7 +130,7 @@ - (NSURL *)requestURL:(NSError *__autoreleasing *)errorRef return requestURL; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m index 9595195db0..5c5ea7ad1a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m @@ -20,25 +20,24 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPIResponse.h" + #import "FBSDKBridgeAPIResponse.h" -#import "FBSDKBridgeAPIProtocol.h" -#import "FBSDKBridgeAPIProtocolType.h" -#import "FBSDKBridgeAPIRequest+Private.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKBridgeAPIProtocol.h" + #import "FBSDKBridgeAPIProtocolType.h" + #import "FBSDKBridgeAPIRequest+Private.h" + #import "FBSDKInternalUtility.h" @interface FBSDKBridgeAPIResponse () - (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request responseParameters:(NSDictionary *)responseParameters cancelled:(BOOL)cancelled error:(NSError *)error -NS_DESIGNATED_INITIALIZER; + NS_DESIGNATED_INITIALIZER; @end @implementation FBSDKBridgeAPIResponse -#pragma mark - Class Methods + #pragma mark - Class Methods + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request error:(NSError *)error { @@ -59,13 +58,13 @@ + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request // https://forums.developer.apple.com/thread/119118 } else { switch (protocolType) { - case FBSDKBridgeAPIProtocolTypeNative:{ + case FBSDKBridgeAPIProtocolTypeNative: { if (![FBSDKInternalUtility isFacebookBundleIdentifier:sourceApplication]) { return nil; } break; } - case FBSDKBridgeAPIProtocolTypeWeb:{ + case FBSDKBridgeAPIProtocolTypeWeb: { if (![FBSDKInternalUtility isSafariBundleIdentifier:sourceApplication]) { return nil; } @@ -104,7 +103,7 @@ + (instancetype)bridgeAPIResponseCancelledWithRequest:(FBSDKBridgeAPIRequest *)r error:nil]; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request responseParameters:(NSDictionary *)responseParameters @@ -120,7 +119,7 @@ - (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request return self; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.m index b4da96ac83..94d38f9230 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.m @@ -20,20 +20,19 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPIProtocolNativeV1.h" + #import "FBSDKBridgeAPIProtocolNativeV1.h" -#import + #import -#import "FBSDKApplicationDelegate+Internal.h" -#import "FBSDKBase64.h" -#import "FBSDKBridgeAPIRequest.h" -#import "FBSDKConstants.h" -#import "FBSDKError.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKApplicationDelegate+Internal.h" + #import "FBSDKBase64.h" + #import "FBSDKBridgeAPIRequest.h" + #import "FBSDKConstants.h" + #import "FBSDKError.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKSettings.h" -#define FBSDKBridgeAPIProtocolNativeV1BridgeMaxBase64DataLengthThreshold (1024 * 16) + #define FBSDKBridgeAPIProtocolNativeV1BridgeMaxBase64DataLengthThreshold (1024 * 16) const FBSDKBridgeAPIProtocolNativeV1OutputKeysStruct FBSDKBridgeAPIProtocolNativeV1OutputKeys = { @@ -62,8 +61,7 @@ .error = @"error", }; -static const struct -{ +static const struct { __unsafe_unretained NSString *isBase64; __unsafe_unretained NSString *isPasteboard; __unsafe_unretained NSString *tag; @@ -78,8 +76,7 @@ static NSString *const FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey = @"com.facebook.Facebook.FBAppBridgeType"; -static const struct -{ +static const struct { __unsafe_unretained NSString *data; __unsafe_unretained NSString *image; } FBSDKBridgeAPIProtocolNativeV1DataTypeTags = @@ -89,8 +86,7 @@ .image = @"png", }; -static const struct -{ +static const struct { __unsafe_unretained NSString *code; __unsafe_unretained NSString *domain; __unsafe_unretained NSString *userInfo; @@ -103,7 +99,7 @@ @implementation FBSDKBridgeAPIProtocolNativeV1 -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithAppScheme:(NSString *)appScheme { @@ -127,7 +123,7 @@ - (instancetype)initWithAppScheme:(NSString *)appScheme return self; } -#pragma mark - FBSDKBridgeAPIProtocol + #pragma mark - FBSDKBridgeAPIProtocol - (NSURL *)requestURLWithActionID:(NSString *)actionID scheme:(NSString *)scheme @@ -141,7 +137,7 @@ - (NSURL *)requestURLWithActionID:(NSString *)actionID NSMutableDictionary *const queryParameters = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:queryParameters setObject:methodVersion - forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.methodVersion]; + forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.methodVersion]; if (parameters.count) { NSString *const parametersString = [self _JSONStringForObject:parameters enablePasteboard:YES error:errorRef]; @@ -151,11 +147,13 @@ - (NSURL *)requestURLWithActionID:(NSString *)actionID NSString *const escapedParametersString = [parametersString stringByReplacingOccurrencesOfString:@"&" withString:@"%26" options:NSCaseInsensitiveSearch - range:NSMakeRange(0, - parametersString.length)]; + range:NSMakeRange( + 0, + parametersString.length + )]; [FBSDKTypeUtility dictionary:queryParameters - setObject:escapedParametersString - forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.methodArgs]; + setObject:escapedParametersString + forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.methodArgs]; } NSDictionary *const bridgeParameters = [self _bridgeParametersWithActionID:actionID error:errorRef]; @@ -167,9 +165,8 @@ - (NSURL *)requestURLWithActionID:(NSString *)actionID return nil; } [FBSDKTypeUtility dictionary:queryParameters - setObject:bridgeParametersString - forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.bridgeArgs]; - + setObject:bridgeParametersString + forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.bridgeArgs]; return [FBSDKInternalUtility URLWithScheme:self.appScheme host:host @@ -234,7 +231,7 @@ - (NSDictionary *)responseParametersForActionID:(NSString *)actionID return resultParameters; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (UIImage *)_appIcon { @@ -254,13 +251,13 @@ - (NSDictionary *)_bridgeParametersWithActionID:(NSString *)actionID error:(NSEr { NSMutableDictionary *bridgeParameters = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:bridgeParameters setObject:actionID - forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.actionID]; + forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.actionID]; [FBSDKTypeUtility dictionary:bridgeParameters setObject:[self _appIcon] - forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.appIcon]; + forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.appIcon]; [FBSDKTypeUtility dictionary:bridgeParameters setObject:[FBSDKSettings displayName] - forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.appName]; + forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.appName]; [FBSDKTypeUtility dictionary:bridgeParameters setObject:[FBSDKSettings sdkVersion] - forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.sdkVersion]; + forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.sdkVersion]; return bridgeParameters; } @@ -269,20 +266,20 @@ - (NSError *)_errorWithDictionary:(NSDictionary *)dictionary if (!dictionary) { return nil; } - NSString *domain = [FBSDKTypeUtility stringValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.domain]] ?: - FBSDKErrorDomain; - NSInteger code = [FBSDKTypeUtility integerValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.code]] ?: - FBSDKErrorUnknown; + NSString *domain = [FBSDKTypeUtility stringValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.domain]] + ?: FBSDKErrorDomain; + NSInteger code = [FBSDKTypeUtility integerValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.code]] + ?: FBSDKErrorUnknown; NSDictionary *userInfo = [FBSDKTypeUtility dictionaryValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.userInfo]]; return [NSError errorWithDomain:domain code:code userInfo:userInfo]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (NSString *)_JSONStringForObject:(id)object enablePasteboard:(BOOL)enablePasteboard error:(NSError **)errorRef { __block BOOL didAddToPasteboard = NO; - return [FBSDKBasicUtility JSONStringForObject:object error:errorRef invalidObjectHandler:^id(id invalidObject, BOOL *stop) { + return [FBSDKBasicUtility JSONStringForObject:object error:errorRef invalidObjectHandler:^id (id invalidObject, BOOL *stop) { NSString *dataTag = FBSDKBridgeAPIProtocolNativeV1DataTypeTags.data; if ([invalidObject isKindOfClass:[UIImage class]]) { UIImage *image = (UIImage *)invalidObject; @@ -297,8 +294,8 @@ - (NSString *)_JSONStringForObject:(id)object enablePasteboard:(BOOL)enablePaste dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.isBase64] = @YES; [FBSDKTypeUtility dictionary:dictionary setObject:dataTag forKey:FBSDKBridgeAPIProtocolNativeV1DataKeys.tag]; [FBSDKTypeUtility dictionary:dictionary - setObject:[FBSDKBase64 encodeData:data] - forKey:FBSDKBridgeAPIProtocolNativeV1DataKeys.value]; + setObject:[FBSDKBase64 encodeData:data] + forKey:FBSDKBridgeAPIProtocolNativeV1DataKeys.value]; } else { dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.isPasteboard] = @YES; [FBSDKTypeUtility dictionary:dictionary setObject:dataTag forKey:FBSDKBridgeAPIProtocolNativeV1DataKeys.tag]; @@ -311,8 +308,8 @@ - (NSString *)_JSONStringForObject:(id)object enablePasteboard:(BOOL)enablePaste // the Facebook app will not clear the value with this version of the protocol, so we should do it when the app // becomes active again NSString *pasteboardName = self->_pasteboard.name; - if ([pasteboardName isEqualToString:UIPasteboardNameGeneral] || - [pasteboardName isEqualToString:UIPasteboardNameFind]) { + if ([pasteboardName isEqualToString:UIPasteboardNameGeneral] + || [pasteboardName isEqualToString:UIPasteboardNameFind]) { [[self class] clearData:data fromPasteboardOnApplicationDidBecomeActive:self->_pasteboard]; } } @@ -323,18 +320,22 @@ - (NSString *)_JSONStringForObject:(id)object enablePasteboard:(BOOL)enablePaste return invalidObject; }]; } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop + (void)clearData:(NSData *)data fromPasteboardOnApplicationDidBecomeActive:(UIPasteboard *)pasteboard { - void(^notificationBlock)(NSNotification *) = ^(NSNotification *note){ + void (^notificationBlock)(NSNotification *) = ^(NSNotification *note) { + // After testing, it seems that reading the pasteboard will not result in a system dialog since + // the clipboard write originates from the app that loads the SDK NSData *pasteboardData = [pasteboard dataForPasteboardType:FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey]; + // We need to compare the data to make sure we don't clear different apps data in a multi-tasking environment if ([data isEqualToData:pasteboardData]) { [pasteboard setData:[NSData data] forPasteboardType:FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey]; } }; [[NSNotificationCenter defaultCenter] addObserverForName:FBSDKApplicationDidBecomeActiveNotification - object:[FBSDKApplicationDelegate sharedInstance] + object:nil queue:nil usingBlock:notificationBlock]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.m index 9747081f71..455c567c9c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.m @@ -20,23 +20,22 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPIProtocolWebV1.h" + #import "FBSDKBridgeAPIProtocolWebV1.h" -#import + #import -#import "FBSDKBase64.h" -#import "FBSDKBridgeAPIRequest.h" -#import "FBSDKError.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKBase64.h" + #import "FBSDKBridgeAPIRequest.h" + #import "FBSDKError.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKSettings.h" -#define FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY @"action_id" -#define FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY @"bridge_args" + #define FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY @"action_id" + #define FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY @"bridge_args" @implementation FBSDKBridgeAPIProtocolWebV1 -#pragma mark - FBSDKBridgeAPIProtocol + #pragma mark - FBSDKBridgeAPIProtocol - (NSURL *)requestURLWithActionID:(NSString *)actionID scheme:(NSString *)scheme @@ -47,10 +46,10 @@ - (NSURL *)requestURLWithActionID:(NSString *)actionID { NSMutableDictionary *queryParameters = [[NSMutableDictionary alloc] initWithDictionary:parameters]; [FBSDKTypeUtility dictionary:queryParameters setObject:@"touch" forKey:@"display"]; - NSString *bridgeArgs = [FBSDKBasicUtility JSONStringForObject:@{ FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY: actionID } + NSString *bridgeArgs = [FBSDKBasicUtility JSONStringForObject:@{ FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY : actionID } error:NULL invalidObjectHandler:NULL]; - NSDictionary *redirectQueryParameters = @{ FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY: bridgeArgs }; + NSDictionary *redirectQueryParameters = @{ FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY : bridgeArgs }; NSURL *redirectURL = [FBSDKInternalUtility appURLWithHost:@"bridge" path:methodName queryParameters:redirectQueryParameters @@ -73,17 +72,17 @@ - (NSDictionary *)responseParametersForActionID:(NSString *)actionID } NSInteger errorCode = [FBSDKTypeUtility integerValue:queryParameters[@"error_code"]]; switch (errorCode) { - case 0:{ + case 0: { // good to go, handle the other codes and bail break; } - case 4201:{ + case 4201: { return @{ - @"completionGesture": @"cancel", - }; + @"completionGesture" : @"cancel", + }; break; } - default:{ + default: { if (errorRef != NULL) { *errorRef = [FBSDKError errorWithCode:errorCode message:[FBSDKTypeUtility stringValue:queryParameters[@"error_message"]]]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.m index 7f5d5d8828..83bf71fba8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.m @@ -20,21 +20,21 @@ #if !TARGET_OS_TV -#import "FBSDKBridgeAPIProtocolWebV2.h" + #import "FBSDKBridgeAPIProtocolWebV2.h" -#import "FBSDKBridgeAPIProtocolNativeV1.h" -#import "FBSDKDialogConfiguration.h" -#import "FBSDKError.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKServerConfiguration.h" -#import "FBSDKServerConfigurationManager.h" + #import "FBSDKBridgeAPIProtocolNativeV1.h" + #import "FBSDKDialogConfiguration.h" + #import "FBSDKError.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKServerConfiguration.h" + #import "FBSDKServerConfigurationManager.h" @implementation FBSDKBridgeAPIProtocolWebV2 { FBSDKBridgeAPIProtocolNativeV1 *_nativeProtocol; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)init { @@ -47,17 +47,17 @@ - (instancetype)init return self; } -#pragma mark - FBSDKBridgeAPIProtocol + #pragma mark - FBSDKBridgeAPIProtocol - (NSURL *)_redirectURLWithActionID:(NSString *)actionID methodName:(NSString *)methodName error:(NSError **)errorRef { NSDictionary *queryParameters = nil; if (actionID) { - NSDictionary *bridgeArgs = @{ FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys.actionID: actionID }; + NSDictionary *bridgeArgs = @{ FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys.actionID : actionID }; NSString *bridgeArgsString = [FBSDKBasicUtility JSONStringForObject:bridgeArgs error:NULL invalidObjectHandler:NULL]; - queryParameters = @{ FBSDKBridgeAPIProtocolNativeV1InputKeys.bridgeArgs: bridgeArgsString }; + queryParameters = @{ FBSDKBridgeAPIProtocolNativeV1InputKeys.bridgeArgs : bridgeArgsString }; } return [FBSDKInternalUtility appURLWithHost:@"bridge" path:methodName queryParameters:queryParameters error:errorRef]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceButton+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceButton+Internal.h index d9c41d450f..0c930865fa 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceButton+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceButton+Internal.h @@ -20,13 +20,13 @@ #if TARGET_OS_TV -#import + #import -#if SWIFT_PACKAGE -#import "FBSDKDeviceButton.h" -#else -#import -#endif + #if SWIFT_PACKAGE + #import "FBSDKDeviceButton.h" + #else + #import + #endif @interface FBSDKDeviceButton () diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m index 6cdce274ec..555716a04a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m @@ -20,10 +20,10 @@ #if TARGET_OS_TV -#import "FBSDKDeviceDialogView.h" + #import "FBSDKDeviceDialogView.h" -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKDeviceUtilities.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKDeviceUtilities.h" @implementation FBSDKDeviceDialogView { @@ -41,7 +41,7 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } -#pragma mark - Properties + #pragma mark - Properties - (void)setConfirmationCode:(NSString *)confirmationCode { @@ -61,7 +61,7 @@ - (void)setConfirmationCode:(NSString *)confirmationCode } } -#pragma mark - Helpers + #pragma mark - Helpers - (void)buildView { @@ -76,7 +76,7 @@ - (void)buildView const CGFloat kLogoMargin = 30; const CGFloat kInstructionTextHorizontalMargin = 151; const CGFloat kConfirmationCodeFontSize = 108; - const CGFloat kFontColorValue = 119.0/255.0; + const CGFloat kFontColorValue = 119.0 / 255.0; const CGFloat kInstructionFontSize = 36; const CGFloat kQRCodeMargin = 50; const CGFloat kQRCodeSize = 200; @@ -96,7 +96,7 @@ - (void)buildView // build the header container view (which will contain the logo and code). UIView *dialogHeaderView = [[UIView alloc] init]; dialogHeaderView.translatesAutoresizingMaskIntoConstraints = NO; - dialogHeaderView.backgroundColor = [UIColor colorWithRed:226.0/255.0 green:231.0/255.0 blue:235.0/255.0 alpha:0.85]; + dialogHeaderView.backgroundColor = [UIColor colorWithRed:226.0 / 255.0 green:231.0 / 255.0 blue:235.0 / 255.0 alpha:0.85]; [dialogView addSubview:dialogHeaderView]; [dialogHeaderView.leadingAnchor constraintEqualToAnchor:dialogView.leadingAnchor].active = YES; [dialogHeaderView.trailingAnchor constraintEqualToAnchor:dialogView.trailingAnchor].active = YES; @@ -105,7 +105,7 @@ - (void)buildView // build the logo. CGSize imageSize = CGSizeMake(kLogoSize, kLogoSize); - FBSDKLogo *logoHelper =[[FBSDKLogo alloc] initWithColor:[UIColor colorWithRed:66.0/255.0 green:103.0/255.0 blue:178.0/255.0 alpha:1]]; + FBSDKLogo *logoHelper = [[FBSDKLogo alloc] initWithColor:[UIColor colorWithRed:66.0 / 255.0 green:103.0 / 255.0 blue:178.0 / 255.0 alpha:1]]; UIImage *image = [logoHelper imageWithSize:imageSize]; image = [image resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; @@ -150,16 +150,18 @@ - (void)buildView [_qrImageView.leadingAnchor constraintEqualToAnchor:dialogView.leadingAnchor constant:kQRCodeMargin].active = YES; [_qrImageView.trailingAnchor constraintEqualToAnchor:_qrImageView.leadingAnchor - constant:kQRCodeSize].active = YES; + constant:kQRCodeSize].active = YES; // build the instructions UILabel UILabel *instructionLabel = [[UILabel alloc] init]; instructionLabel.translatesAutoresizingMaskIntoConstraints = NO; - NSString *localizedFormatString = NSLocalizedStringWithDefaultValue(@"DeviceLogin.LogInPrompt", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"Visit %@ and enter your code.", - @"The format string for device login instructions"); + NSString *localizedFormatString = NSLocalizedStringWithDefaultValue( + @"DeviceLogin.LogInPrompt", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Visit %@ and enter your code.", + @"The format string for device login instructions" + ); NSString *const deviceLoginURLString = @"facebook.com/device"; NSString *instructionString = [NSString localizedStringWithFormat:localizedFormatString, deviceLoginURLString]; NSMutableParagraphStyle *instructionLabelParagraphStyle = [[NSMutableParagraphStyle alloc] init]; @@ -200,11 +202,13 @@ - (void)buildView UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; button.layer.cornerRadius = 4.0; button.translatesAutoresizingMaskIntoConstraints = NO; - [button setTitle:NSLocalizedStringWithDefaultValue(@"LoginButton.CancelLogout", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"Cancel", - @"The label for the FBSDKLoginButton action sheet to cancel logging out") + [button setTitle:NSLocalizedStringWithDefaultValue( + @"LoginButton.CancelLogout", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Cancel", + @"The label for the FBSDKLoginButton action sheet to cancel logging out" + ) forState:UIControlStateNormal]; button.titleLabel.font = instructionLabel.font; [buttonContainerView addSubview:button]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceUtilities.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceUtilities.m index e54e87c8de..9f4c2e1cb3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceUtilities.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceUtilities.m @@ -20,7 +20,7 @@ #if TARGET_OS_TV -#import "FBSDKDeviceUtilities.h" + #import "FBSDKDeviceUtilities.h" @implementation FBSDKDeviceUtilities @@ -41,8 +41,10 @@ + (UIImage *)buildQRCodeWithAuthorizationCode:(NSString *)authorizationCode CGSize qrOutputSize = CGSizeMake(200, 200); CIImage *resizedImage = - [qrCodeImage imageByApplyingTransform: CGAffineTransformMakeScale(qrOutputSize.width / CGRectGetWidth(qrImageSize), - qrOutputSize.height / CGRectGetHeight(qrImageSize))]; + [qrCodeImage imageByApplyingTransform:CGAffineTransformMakeScale( + qrOutputSize.width / CGRectGetWidth(qrImageSize), + qrOutputSize.height / CGRectGetHeight(qrImageSize) + )]; return [UIImage imageWithCIImage:resizedImage]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceViewControllerBase+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceViewControllerBase+Internal.h index 020b4e9d13..3e6628aeac 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceViewControllerBase+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceViewControllerBase+Internal.h @@ -20,14 +20,14 @@ #if TARGET_OS_TV -#if SWIFT_PACKAGE -#import "FBSDKDeviceViewControllerBase.h" -#else -#import -#endif + #if SWIFT_PACKAGE + #import "FBSDKDeviceViewControllerBase.h" + #else + #import + #endif -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKDeviceDialogView.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKDeviceDialogView.h" @class FBSDKDeviceDialogView; @@ -38,13 +38,13 @@ NS_ASSUME_NONNULL_BEGIN This is an internal API that should not be used directly and is subject to change. */ -@interface FBSDKDeviceViewControllerBase()< -UIViewControllerAnimatedTransitioning, -UIViewControllerTransitioningDelegate, -FBSDKDeviceDialogViewDelegate +@interface FBSDKDeviceViewControllerBase () < + UIViewControllerAnimatedTransitioning, + UIViewControllerTransitioningDelegate, + FBSDKDeviceDialogViewDelegate > -@property (nonatomic, strong, readonly) FBSDKDeviceDialogView *deviceDialogView; +@property (nonatomic, readonly, strong) FBSDKDeviceDialogView *deviceDialogView; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKModalFormPresentationController.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKModalFormPresentationController.m index e49e69a5fd..9356ebab32 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKModalFormPresentationController.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKModalFormPresentationController.m @@ -20,9 +20,10 @@ #if TARGET_OS_TV -#import "FBSDKModalFormPresentationController.h" + #import "FBSDKModalFormPresentationController.h" -@implementation FBSDKModalFormPresentationController { +@implementation FBSDKModalFormPresentationController +{ UIView *_dimmedView; } @@ -35,16 +36,16 @@ - (UIView *)dimmedView return _dimmedView; } -#pragma mark - UIPresentationController overrides + #pragma mark - UIPresentationController overrides - (void)presentationTransitionWillBegin { [self.containerView addSubview:[self dimmedView]]; [self.containerView addSubview:[self presentedView]]; [self.presentingViewController.transitionCoordinator - animateAlongsideTransition:^(id _Nonnull context) { - [self dimmedView].alpha = 1.0; - } completion:NULL]; + animateAlongsideTransition:^(id _Nonnull context) { + [self dimmedView].alpha = 1.0; + } completion:NULL]; } - (void)presentationTransitionDidEnd:(BOOL)completed @@ -57,9 +58,9 @@ - (void)presentationTransitionDidEnd:(BOOL)completed - (void)dismissalTransitionWillBegin { [self.presentingViewController.transitionCoordinator - animateAlongsideTransition:^(id _Nonnull context) { - [self dimmedView].alpha = 0; - } completion:NULL]; + animateAlongsideTransition:^(id _Nonnull context) { + [self dimmedView].alpha = 0; + } completion:NULL]; } - (void)dismissalTransitionDidEnd:(BOOL)completed @@ -73,9 +74,9 @@ - (void)dismissalTransitionDidEnd:(BOOL)completed - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - [coordinator animateAlongsideTransition:^(id _Nonnull context) { - [self dimmedView].frame = self.containerView.bounds; - } completion:NULL]; + [coordinator animateAlongsideTransition:^(id _Nonnull context) { + [self dimmedView].frame = self.containerView.bounds; + } completion:NULL]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m index 430801257b..5733514279 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m @@ -20,10 +20,10 @@ #if TARGET_OS_TV -#import "FBSDKSmartDeviceDialogView.h" + #import "FBSDKSmartDeviceDialogView.h" -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKDeviceUtilities.h" + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKDeviceUtilities.h" @implementation FBSDKSmartDeviceDialogView { @@ -40,7 +40,7 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } -#pragma mark - Overrides + #pragma mark - Overrides - (void)setConfirmationCode:(NSString *)confirmationCode { @@ -62,10 +62,10 @@ - (void)setConfirmationCode:(NSString *)confirmationCode - (void)buildView { - //intentionally blank. + // intentionally blank. } -#pragma mark - Helpers + #pragma mark - Helpers - (void)_buildView { @@ -78,7 +78,7 @@ - (void)_buildView const CGFloat kLogoMargin = 30; const CGFloat kInstructionTextHorizontalMargin = 100; const CGFloat kConfirmationCodeFontSize = 108; - const CGFloat kFontColorValue = 119.0/255.0; + const CGFloat kFontColorValue = 119.0 / 255.0; const CGFloat kInstructionFontSize = 32; const CGFloat kVerticalMarginOrLabel = 40; const CGFloat kQRCodeSize = 200; @@ -98,7 +98,7 @@ - (void)_buildView // build the header container view (which will contain the logo and code). UIView *dialogHeaderView = [[UIView alloc] init]; dialogHeaderView.translatesAutoresizingMaskIntoConstraints = NO; - dialogHeaderView.backgroundColor = [UIColor colorWithRed:226.0/255.0 green:231.0/255.0 blue:235.0/255.0 alpha:0.85]; + dialogHeaderView.backgroundColor = [UIColor colorWithRed:226.0 / 255.0 green:231.0 / 255.0 blue:235.0 / 255.0 alpha:0.85]; [dialogView addSubview:dialogHeaderView]; [dialogHeaderView.leadingAnchor constraintEqualToAnchor:dialogView.leadingAnchor].active = YES; [dialogHeaderView.trailingAnchor constraintEqualToAnchor:dialogView.trailingAnchor].active = YES; @@ -107,7 +107,7 @@ - (void)_buildView // build the logo. CGSize imageSize = CGSizeMake(kLogoSize, kLogoSize); - FBSDKLogo *logoHelper =[[FBSDKLogo alloc] initWithColor:[UIColor colorWithRed:66.0/255.0 green:103.0/255.0 blue:178.0/255.0 alpha:1]]; + FBSDKLogo *logoHelper = [[FBSDKLogo alloc] initWithColor:[UIColor colorWithRed:66.0 / 255.0 green:103.0 / 255.0 blue:178.0 / 255.0 alpha:1]]; UIImage *image = [logoHelper imageWithSize:imageSize]; image = [image resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; @@ -143,11 +143,13 @@ - (void)_buildView // build the smartlogin instructions UILabel *smartInstructionLabel = [[UILabel alloc] init]; smartInstructionLabel.translatesAutoresizingMaskIntoConstraints = NO; - NSString *smartInstructionString = NSLocalizedStringWithDefaultValue(@"DeviceLogin.SmartLogInPrompt", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"To connect your account, open the Facebook app on your mobile device and check for notifications.", - @"Instructions telling the user to open their Facebook app on a mobile device and check for a login notification."); + NSString *smartInstructionString = NSLocalizedStringWithDefaultValue( + @"DeviceLogin.SmartLogInPrompt", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"To connect your account, open the Facebook app on your mobile device and check for notifications.", + @"Instructions telling the user to open their Facebook app on a mobile device and check for a login notification." + ); NSMutableParagraphStyle *instructionLabelParagraphStyle = [[NSMutableParagraphStyle alloc] init]; instructionLabelParagraphStyle.lineHeightMultiple = 1.3; @@ -164,7 +166,7 @@ - (void)_buildView smartInstructionLabel.textColor = [UIColor colorWithWhite:kFontColorValue alpha:1.0]; [dialogView addSubview:smartInstructionLabel]; [smartInstructionLabel.topAnchor constraintEqualToAnchor:dialogHeaderView.bottomAnchor - constant:kVerticalSpaceBetweenHeaderViewAndInstructionLabel].active = YES; + constant:kVerticalSpaceBetweenHeaderViewAndInstructionLabel].active = YES; [smartInstructionLabel.leadingAnchor constraintEqualToAnchor:dialogView.leadingAnchor constant:kInstructionTextHorizontalMargin].active = YES; [dialogView.trailingAnchor constraintEqualToAnchor:smartInstructionLabel.trailingAnchor constant:kInstructionTextHorizontalMargin].active = YES; @@ -172,11 +174,13 @@ - (void)_buildView UILabel *orInstructionLabel = [[UILabel alloc] init]; orInstructionLabel.translatesAutoresizingMaskIntoConstraints = NO; orInstructionLabel.font = [UIFont systemFontOfSize:kInstructionFontSize weight:UIFontWeightBold]; - orInstructionLabel.text = NSLocalizedStringWithDefaultValue(@"DeviceLogin.SmartLogInOrLabel", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"-- OR --", - @"The 'or' string for smart login instructions");; + orInstructionLabel.text = NSLocalizedStringWithDefaultValue( + @"DeviceLogin.SmartLogInOrLabel", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"-- OR --", + @"The 'or' string for smart login instructions" + );; orInstructionLabel.numberOfLines = 0; orInstructionLabel.textAlignment = NSTextAlignmentCenter; [orInstructionLabel sizeToFit]; @@ -204,11 +208,13 @@ - (void)_buildView // build the instructions UILabel UILabel *instructionLabel = [[UILabel alloc] init]; instructionLabel.translatesAutoresizingMaskIntoConstraints = NO; - NSString *localizedFormatString = NSLocalizedStringWithDefaultValue(@"DeviceLogin.LogInPrompt", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"Visit %@ and enter the code shown above.", - @"The format string for device login instructions"); + NSString *localizedFormatString = NSLocalizedStringWithDefaultValue( + @"DeviceLogin.LogInPrompt", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Visit %@ and enter the code shown above.", + @"The format string for device login instructions" + ); NSString *const deviceLoginURLString = @"facebook.com/device"; NSString *instructionString = [NSString localizedStringWithFormat:localizedFormatString, deviceLoginURLString]; @@ -249,11 +255,13 @@ - (void)_buildView UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; button.layer.cornerRadius = 4.0; button.translatesAutoresizingMaskIntoConstraints = NO; - [button setTitle:NSLocalizedStringWithDefaultValue(@"LoginButton.CancelLogout", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"Cancel", - @"The label for the FBSDKLoginButton action sheet to cancel logging out") + [button setTitle:NSLocalizedStringWithDefaultValue( + @"LoginButton.CancelLogout", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Cancel", + @"The label for the FBSDKLoginButton action sheet to cancel logging out" + ) forState:UIControlStateNormal]; button.titleLabel.font = instructionLabel.font; [buttonContainerView addSubview:button]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.m index 07aa418dbc..710147b4de 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.m @@ -18,8 +18,8 @@ #import "FBSDKErrorRecoveryAttempter.h" -#import "_FBSDKTemporaryErrorRecoveryAttempter.h" #import "FBSDKErrorRecoveryConfiguration.h" +#import "_FBSDKTemporaryErrorRecoveryAttempter.h" @implementation FBSDKErrorRecoveryAttempter @@ -43,9 +43,10 @@ - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recove { // should be implemented by subclasses. } + @end -@implementation FBSDKErrorRecoveryAttempter(Protected) +@implementation FBSDKErrorRecoveryAttempter (Protected) - (void)completeRecovery:(BOOL)didRecover delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.m index bb555aa7f8..13f5272971 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.m @@ -22,7 +22,11 @@ @implementation _FBSDKTemporaryErrorRecoveryAttempter - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo { - [super completeRecovery:YES delegate:delegate didRecoverSelector:didRecoverSelector contextInfo:contextInfo]; + @try { + [super completeRecovery:YES delegate:delegate didRecoverSelector:didRecoverSelector contextInfo:contextInfo]; + } @catch (NSException *exception) { + NSLog(@"Fail to complete error recovery. Exception reason: %@", exception.reason); + } } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAccessToken+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAccessToken+Internal.h new file mode 100644 index 0000000000..e761e3c801 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAccessToken+Internal.h @@ -0,0 +1,32 @@ +// 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. + +#if SWIFT_PACKAGE + #import "FBSDKAccessToken.h" +#else + #import +#endif + +#import "FBSDKCoreKit+Internal.h" + +@interface FBSDKAccessToken (Internal) + ++ (void)setCurrentAccessToken:(FBSDKAccessToken *)token + shouldDispatchNotif:(BOOL)shouldDispatchNotif; + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLinkReturnToRefererView_Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLinkReturnToRefererView_Internal.h index 6c5d3283e5..8a26b8ebe8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLinkReturnToRefererView_Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLinkReturnToRefererView_Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKAppLinkReturnToRefererView.h" + #import "FBSDKAppLinkReturnToRefererView.h" @interface FBSDKAppLinkReturnToRefererView (Internal) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLink_Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLink_Internal.h index 78cfe3c301..ede28823d6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLink_Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAppLink_Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKAppLink.h" + #import "FBSDKAppLink.h" FOUNDATION_EXPORT NSString *const FBSDKAppLinkDataParameterName; FOUNDATION_EXPORT NSString *const FBSDKAppLinkTargetKeyName; @@ -39,7 +39,7 @@ FOUNDATION_EXPORT NSString *const FBSDKAppLinkRefererUrl; isBackToReferrer:(BOOL)isBackToReferrer; /** return if this AppLink is to go back to referrer. */ -@property (nonatomic, assign, readonly, getter=isBackToReferrer) BOOL backToReferrer; +@property (nonatomic, readonly, getter = isBackToReferrer, assign) BOOL backToReferrer; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationDelegate+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationDelegate+Internal.h index d194a2d058..43154ca6e0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationDelegate+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationDelegate+Internal.h @@ -19,12 +19,12 @@ #import #if SWIFT_PACKAGE -#import "FBSDKApplicationDelegate.h" + #import "FBSDKApplicationDelegate.h" #else -#import + #import #endif -#import "FBSDKCoreKit+Internal.h" +#import "FBSDKApplicationObserving.h" NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationObserving.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationObserving.h index 9eba4ce116..d6695f51bd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationObserving.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationObserving.h @@ -24,9 +24,10 @@ NS_ASSUME_NONNULL_BEGIN @optional - (void)applicationDidBecomeActive:(nullable UIApplication *)application; +- (void)applicationWillResignActive:(nullable UIApplication *)application; - (void)applicationDidEnterBackground:(nullable UIApplication *)application; -- (BOOL)application:(UIApplication *)application -didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions; +- (BOOL) application:(UIApplication *)application + didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions; - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.h index a9875042d3..dc270a4e82 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import NS_ASSUME_NONNULL_BEGIN @@ -35,9 +35,9 @@ NS_ASSUME_NONNULL_BEGIN @interface FBSDKAudioResourceLoader (Subclass) -@property (class, nonatomic, copy, nullable, readonly) NSString *name; -@property (class, nonatomic, copy, nullable, readonly) NSData *data; -@property (class, nonatomic, assign, readonly) NSUInteger version; +@property (class, nullable, nonatomic, readonly, copy) NSString *name; +@property (class, nullable, nonatomic, readonly, copy) NSData *data; +@property (class, nonatomic, readonly, assign) NSUInteger version; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.m index e78bb21ba8..0f96cbd5a3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.m @@ -20,12 +20,12 @@ #if !TARGET_OS_TV -#import "FBSDKAudioResourceLoader.h" + #import "FBSDKAudioResourceLoader.h" -#import "FBSDKDynamicFrameworkLoader.h" -#import "FBSDKLogger.h" -#import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKDynamicFrameworkLoader.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKLogger.h" + #import "FBSDKSettings.h" @implementation FBSDKAudioResourceLoader { @@ -34,7 +34,7 @@ @implementation FBSDKAudioResourceLoader SystemSoundID _systemSoundID; } -#pragma mark - Class Methods + #pragma mark - Class Methods + (instancetype)sharedLoader { @@ -63,7 +63,7 @@ + (instancetype)sharedLoader return loader; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)init { @@ -78,7 +78,7 @@ - (void)dealloc fbsdkdfl_AudioServicesDisposeSystemSoundID(_systemSoundID); } -#pragma mark - Public API + #pragma mark - Public API - (BOOL)loadSound:(NSError **)errorRef { @@ -103,7 +103,7 @@ - (void)playSound fbsdkdfl_AudioServicesPlaySystemSound(_systemSoundID); } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (NSURL *)_fileURL:(NSError **)errorRef { @@ -136,7 +136,7 @@ - (NSURL *)_fileURL:(NSError **)errorRef @implementation FBSDKAudioResourceLoader (Subclass) -#pragma mark - Subclass Methods + #pragma mark - Subclass Methods + (NSString *)name { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.m index b5a62eb062..a4f8267a20 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKContainerViewController.h" + #import "FBSDKContainerViewController.h" @implementation FBSDKContainerViewController diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 48a47df606..dd1195fca8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -19,157 +19,156 @@ #import #if SWIFT_PACKAGE -#import "FBSDKCoreKit.h" + #import "FBSDKCoreKit.h" #else -#import + #import +#endif + +#if defined FBSDKCOCOAPODS + #import +#elif defined BUCK + #import #endif #if defined FBSDKCOCOAPODS || defined BUCK -#if !TARGET_OS_TV -#import "FBSDKViewHierarchy.h" -#import "FBSDKViewHierarchyMacros.h" -#import "FBSDKCodelessIndexer.h" -#import "FBSDKMetadataIndexer.h" -#import "FBSDKSuggestedEventsIndexer.h" -#import "FBSDKCrypto.h" -#import "FBSDKAudioResourceLoader.h" -#import "FBSDKContainerViewController.h" -#import "FBSDKBridgeAPI.h" -#import "FBSDKMonotonicTime.h" -#import "FBSDKTriStateBOOL.h" -#import "FBSDKCloseIcon.h" -#import "FBSDKColor.h" -#import "FBSDKMaleSilhouetteIcon.h" -#import "FBSDKUIUtility.h" -#import "FBSDKViewImpressionTracker.h" -#import "FBSDKWebDialog.h" -#else -#import "FBSDKDeviceButton+Internal.h" -#import "FBSDKDeviceDialogView.h" -#import "FBSDKSmartDeviceDialogView.h" -#import "FBSDKDeviceViewControllerBase+Internal.h" -#import "FBSDKModalFormPresentationController.h" -#endif + #import "FBSDKCoreKit+Internal.h" -#import "FBSDKAppEvents+Internal.h" -#import "FBSDKAppEventsState.h" -#import "FBSDKAppEventsStateManager.h" -#import "FBSDKAppEventsUtility.h" -#import "FBSDKRestrictiveDataFilterManager.h" -#import "FBSDKTimeSpentData.h" -#import "FBSDKUserDataStore.h" -#import "FBSDKBase64.h" -#import "FBSDKErrorRecoveryAttempter.h" -#import "FBSDKDynamicFrameworkLoader.h" -#import "FBSDKApplicationObserving.h" -#import "FBSDKApplicationDelegate+Internal.h" -#import "FBSDKDeviceRequestsHelper.h" -#import "FBSDKError.h" -#import "FBSDKImageDownloader.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKLogger.h" -#import "FBSDKMath.h" -#import "FBSDKMonitorHeaders.h" -#import "FBSDKSettings+Internal.h" -#import "FBSDKSwizzler.h" -#import "FBSDKTypeUtility.h" -#import "FBSDKBasicUtility.h" -#import "FBSDKSafeCast.h" -#import "FBSDKURLSession.h" -#import "FBSDKURLSessionTask.h" -#import "FBSDKCrashHandler.h" -#import "FBSDKLibAnalyzer.h" -#import "FBSDKCrashObserving.h" -#import "FBSDKGraphRequest+Internal.h" -#import "FBSDKGraphRequestConnection+Internal.h" -#import "FBSDKGraphRequestMetadata.h" -#import "FBSDKDialogConfiguration.h" -#import "FBSDKServerConfiguration+Internal.h" -#import "FBSDKServerConfiguration.h" -#import "FBSDKServerConfigurationManager+Internal.h" -#import "FBSDKServerConfigurationManager.h" -#import "FBSDKGateKeeperManager.h" -#import "FBSDKAccessTokenCache.h" -#import "FBSDKAccessTokenCaching.h" -#import "FBSDKKeychainStore.h" -#import "FBSDKKeychainStoreViaBundleID.h" -#import "FBSDKButton+Subclass.h" -#import "FBSDKIcon.h" -#import "FBSDKLogo.h" + #if !TARGET_OS_TV + #import "FBSDKAudioResourceLoader.h" + #import "FBSDKBridgeAPI.h" + #import "FBSDKBridgeAPI+Internal.h" + #import "FBSDKCloseIcon.h" + #import "FBSDKCodelessIndexer.h" + #import "FBSDKColor.h" + #import "FBSDKContainerViewController.h" + #import "FBSDKCrypto.h" + #import "FBSDKMaleSilhouetteIcon.h" + #import "FBSDKMetadataIndexer.h" + #import "FBSDKMonotonicTime.h" + #import "FBSDKSKAdNetworkReporter.h" + #import "FBSDKSuggestedEventsIndexer.h" + #import "FBSDKTriStateBOOL.h" + #import "FBSDKUIUtility.h" + #import "FBSDKViewHierarchy.h" + #import "FBSDKViewHierarchyMacros.h" + #import "FBSDKViewImpressionTracker.h" + #import "FBSDKWebDialog.h" + #else + #import "FBSDKDeviceButton+Internal.h" + #import "FBSDKDeviceDialogView.h" + #import "FBSDKDeviceViewControllerBase+Internal.h" + #import "FBSDKModalFormPresentationController.h" + #import "FBSDKSmartDeviceDialogView.h" + #endif -#else + #import "FBSDKAccessTokenCache.h" + #import "FBSDKAccessTokenCaching.h" + #import "FBSDKAppEvents+Internal.h" + #import "FBSDKAppEventsConfiguration.h" + #import "FBSDKAppEventsConfigurationManager.h" + #import "FBSDKAppEventsState.h" + #import "FBSDKAppEventsStateManager.h" + #import "FBSDKAppEventsUtility.h" + #import "FBSDKApplicationDelegate+Internal.h" + #import "FBSDKApplicationObserving.h" + #import "FBSDKBase64.h" + #import "FBSDKButton+Subclass.h" + #import "FBSDKDeviceRequestsHelper.h" + #import "FBSDKDialogConfiguration.h" + #import "FBSDKDynamicFrameworkLoader.h" + #import "FBSDKError.h" + #import "FBSDKErrorRecoveryAttempter.h" + #import "FBSDKGateKeeperManager.h" + #import "FBSDKGraphRequest+Internal.h" + #import "FBSDKGraphRequestConnection+Internal.h" + #import "FBSDKGraphRequestMetadata.h" + #import "FBSDKIcon.h" + #import "FBSDKImageDownloader.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKKeychainStore.h" + #import "FBSDKKeychainStoreViaBundleID.h" + #import "FBSDKLogger.h" + #import "FBSDKLogo.h" + #import "FBSDKMath.h" + #import "FBSDKMonitorHeaders.h" + #import "FBSDKRestrictiveDataFilterManager.h" + #import "FBSDKServerConfiguration.h" + #import "FBSDKServerConfiguration+Internal.h" + #import "FBSDKServerConfigurationManager.h" + #import "FBSDKServerConfigurationManager+Internal.h" + #import "FBSDKSettings+Internal.h" + #import "FBSDKSwizzler.h" + #import "FBSDKTimeSpentData.h" -#if !TARGET_OS_TV -#import "../AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.h" -#import "../AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchyMacros.h" -#import "../AppEvents/Internal/Codeless/FBSDKCodelessIndexer.h" -#import "../AppEvents/Internal/AAM/FBSDKMetadataIndexer.h" -#import "../AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.h" -#import "Cryptography/FBSDKCrypto.h" -#import "FBSDKAudioResourceLoader.h" -#import "FBSDKContainerViewController.h" -#import "BridgeAPI/FBSDKBridgeAPI.h" -#import "FBSDKMonotonicTime.h" -#import "FBSDKTriStateBOOL.h" -#import "UI/FBSDKCloseIcon.h" -#import "UI/FBSDKColor.h" -#import "UI/FBSDKMaleSilhouetteIcon.h" -#import "UI/FBSDKUIUtility.h" -#import "UI/FBSDKViewImpressionTracker.h" -#import "WebDialog/FBSDKWebDialog.h" #else -#import "Device/FBSDKDeviceButton+Internal.h" -#import "Device/FBSDKDeviceDialogView.h" -#import "Device/FBSDKSmartDeviceDialogView.h" -#import "Device/FBSDKDeviceViewControllerBase+Internal.h" -#import "Device/FBSDKModalFormPresentationController.h" -#endif -#import "../AppEvents/Internal/FBSDKAppEvents+Internal.h" -#import "../AppEvents/Internal/FBSDKAppEventsState.h" -#import "../AppEvents/Internal/FBSDKAppEventsStateManager.h" -#import "../AppEvents/Internal/FBSDKAppEventsUtility.h" -#import "../AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.h" -#import "../AppEvents/Internal/FBSDKTimeSpentData.h" -#import "../AppEvents/Internal/FBSDKUserDataStore.h" -#import "Base64/FBSDKBase64.h" -#import "ErrorRecovery/FBSDKErrorRecoveryAttempter.h" -#import "FBSDKDynamicFrameworkLoader.h" -#import "FBSDKApplicationObserving.h" -#import "FBSDKApplicationDelegate+Internal.h" -#import "FBSDKDeviceRequestsHelper.h" -#import "FBSDKError.h" -#import "FBSDKImageDownloader.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKLogger.h" -#import "FBSDKMath.h" -#import "FBSDKSettings+Internal.h" -#import "FBSDKSwizzler.h" -#import "../Basics/Internal/FBSDKTypeUtility.h" -#import "../Basics/Internal/FBSDKBasicUtility.h" -#import "../Basics/Internal/FBSDKSafeCast.h" -#import "../Basics/Internal/FBSDKURLSession.h" -#import "../Basics/Internal/FBSDKURLSessionTask.h" -#import "../Basics/Instrument/FBSDKCrashHandler.h" -#import "../Basics/Instrument/FBSDKLibAnalyzer.h" -#import "../Basics/Instrument/FBSDKCrashObserving.h" -#import "Monitoring/FBSDKMonitorHeaders.h" -#import "Network/FBSDKGraphRequest+Internal.h" -#import "Network/FBSDKGraphRequestConnection+Internal.h" -#import "Network/FBSDKGraphRequestMetadata.h" -#import "ServerConfiguration/FBSDKDialogConfiguration.h" -#import "ServerConfiguration/FBSDKServerConfiguration+Internal.h" -#import "ServerConfiguration/FBSDKServerConfiguration.h" -#import "ServerConfiguration/FBSDKServerConfigurationManager+Internal.h" -#import "ServerConfiguration/FBSDKServerConfigurationManager.h" -#import "ServerConfiguration/FBSDKGateKeeperManager.h" -#import "TokenCaching/FBSDKAccessTokenCache.h" -#import "TokenCaching/FBSDKAccessTokenCaching.h" -#import "TokenCaching/FBSDKKeychainStore.h" -#import "TokenCaching/FBSDKKeychainStoreViaBundleID.h" -#import "UI/FBSDKButton+Subclass.h" -#import "UI/FBSDKIcon.h" -#import "UI/FBSDKLogo.h" + #if !TARGET_OS_TV + #import "../AppEvents/Internal/AAM/FBSDKMetadataIndexer.h" + #import "../AppEvents/Internal/Codeless/FBSDKCodelessIndexer.h" + #import "../AppEvents/Internal/SKAdNetwork/FBSDKSKAdNetworkReporter.h" + #import "../AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.h" + #import "../AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.h" + #import "../AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchyMacros.h" + #import "BridgeAPI/FBSDKBridgeAPI.h" + #import "BridgeAPI/FBSDKBridgeAPI+Internal.h" + #import "Cryptography/FBSDKCrypto.h" + #import "FBSDKAudioResourceLoader.h" + #import "FBSDKContainerViewController.h" + #import "FBSDKMonotonicTime.h" + #import "FBSDKTriStateBOOL.h" + #import "UI/FBSDKCloseIcon.h" + #import "UI/FBSDKColor.h" + #import "UI/FBSDKMaleSilhouetteIcon.h" + #import "UI/FBSDKUIUtility.h" + #import "UI/FBSDKViewImpressionTracker.h" + #import "WebDialog/FBSDKWebDialog.h" + #else + #import "Device/FBSDKDeviceButton+Internal.h" + #import "Device/FBSDKDeviceDialogView.h" + #import "Device/FBSDKDeviceViewControllerBase+Internal.h" + #import "Device/FBSDKModalFormPresentationController.h" + #import "Device/FBSDKSmartDeviceDialogView.h" + #endif + + #import "../../../Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h" + #import "../AppEvents/Internal/FBSDKAppEvents+Internal.h" + #import "../AppEvents/Internal/FBSDKAppEventsConfiguration.h" + #import "../AppEvents/Internal/FBSDKAppEventsConfigurationManager.h" + #import "../AppEvents/Internal/FBSDKAppEventsState.h" + #import "../AppEvents/Internal/FBSDKAppEventsStateManager.h" + #import "../AppEvents/Internal/FBSDKAppEventsUtility.h" + #import "../AppEvents/Internal/FBSDKTimeSpentData.h" + #import "../AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.h" + #import "Base64/FBSDKBase64.h" + #import "ErrorRecovery/FBSDKErrorRecoveryAttempter.h" + #import "FBSDKApplicationDelegate+Internal.h" + #import "FBSDKApplicationObserving.h" + #import "FBSDKDeviceRequestsHelper.h" + #import "FBSDKDynamicFrameworkLoader.h" + #import "FBSDKError.h" + #import "FBSDKImageDownloader.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKLogger.h" + #import "FBSDKMath.h" + #import "FBSDKSettings+Internal.h" + #import "FBSDKSwizzler.h" + #import "Monitoring/FBSDKMonitorHeaders.h" + #import "Network/FBSDKGraphRequest+Internal.h" + #import "Network/FBSDKGraphRequestConnection+Internal.h" + #import "Network/FBSDKGraphRequestMetadata.h" + #import "ServerConfiguration/FBSDKDialogConfiguration.h" + #import "ServerConfiguration/FBSDKGateKeeperManager.h" + #import "ServerConfiguration/FBSDKServerConfiguration.h" + #import "ServerConfiguration/FBSDKServerConfiguration+Internal.h" + #import "ServerConfiguration/FBSDKServerConfigurationManager.h" + #import "ServerConfiguration/FBSDKServerConfigurationManager+Internal.h" + #import "TokenCaching/FBSDKAccessTokenCache.h" + #import "TokenCaching/FBSDKAccessTokenCaching.h" + #import "TokenCaching/FBSDKKeychainStore.h" + #import "TokenCaching/FBSDKKeychainStoreViaBundleID.h" + #import "UI/FBSDKButton+Subclass.h" + #import "UI/FBSDKIcon.h" + #import "UI/FBSDKLogo.h" #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDeviceRequestsHelper.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDeviceRequestsHelper.m index 4bd13d8018..f7fff410c2 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDeviceRequestsHelper.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDeviceRequestsHelper.m @@ -18,19 +18,19 @@ #import "FBSDKDeviceRequestsHelper.h" -#import - #import +#import + #import "FBSDKCoreKit+Internal.h" #define FBSDK_DEVICE_INFO_DEVICE @"device" #define FBSDK_DEVICE_INFO_MODEL @"model" #define FBSDK_HEADER @"fbsdk" #if !TARGET_OS_TV -#define FBSDK_FLAVOR @"ios" + #define FBSDK_FLAVOR @"ios" #else -#define FBSDK_FLAVOR @"tvos" + #define FBSDK_FLAVOR @"tvos" #endif #define FBSDK_SERVICE_TYPE @"_fb._tcp." @@ -40,7 +40,8 @@ @implementation FBSDKDeviceRequestsHelper #pragma mark - Class Methods -+ (void)initialize { ++ (void)initialize +{ // We use weak to strong in order to retain the advertisement services // without having to pass them back to the delegate that started them // Note that in case the delegate is destroyed before it had a chance to @@ -54,37 +55,37 @@ + (NSString *)getDeviceInfo struct utsname systemInfo; uname(&systemInfo); NSDictionary *deviceInfo = @{ - FBSDK_DEVICE_INFO_DEVICE: @(systemInfo.machine), - FBSDK_DEVICE_INFO_MODEL: [UIDevice currentDevice].model, - }; + FBSDK_DEVICE_INFO_DEVICE : @(systemInfo.machine), + FBSDK_DEVICE_INFO_MODEL : [UIDevice currentDevice].model, + }; NSError *err; NSData *jsonDeviceInfo = [FBSDKTypeUtility dataWithJSONObject:deviceInfo - options:0 - error:&err]; + options:0 + error:&err]; return [[NSString alloc] initWithData:jsonDeviceInfo encoding:NSUTF8StringEncoding]; } + (BOOL)startAdvertisementService:(NSString *)loginCode withDelegate:(id)delegate { - static NSString *sdkVersion = nil; + static NSString *sdkVersion = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - // Dots in the version will mess up the bonjour DNS record parsing + // Dots in the version will mess up the bonjour DNS record parsing sdkVersion = [[FBSDKSettings sdkVersion] stringByReplacingOccurrencesOfString:@"." withString:@"|"]; - if (sdkVersion.length > 10 || - ![[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[sdkVersion characterAtIndex:0]]) { + if (sdkVersion.length > 10 + || ![[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[sdkVersion characterAtIndex:0]]) { sdkVersion = @"dev"; } }); NSString *serviceName = [NSString stringWithFormat:@"%@_%@_%@", - FBSDK_HEADER, - [NSString stringWithFormat:@"%@-%@", - FBSDK_FLAVOR, - sdkVersion - ], - loginCode - ]; + FBSDK_HEADER, + [NSString stringWithFormat:@"%@-%@", + FBSDK_FLAVOR, + sdkVersion + ], + loginCode + ]; if (serviceName.length > 60) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"serviceName exceeded 60 characters"]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.m index b1ed9704c8..4603843238 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.m @@ -106,6 +106,7 @@ + (NSError *)invalidArgumentErrorWithName:(NSString *)name message:message underlyingError:underlyingError]; } + + (NSError *)invalidArgumentErrorWithDomain:(NSErrorDomain)domain name:(NSString *)name value:(id)value @@ -141,7 +142,7 @@ + (NSError *)invalidCollectionErrorWithName:(NSString *)name { if (!message) { message = - [[NSString alloc] initWithFormat:@"Invalid item (%@) found in collection for %@: %@", item, name, collection]; + [[NSString alloc] initWithFormat:@"Invalid item (%@) found in collection for %@: %@", item, name, collection]; } NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:userInfo setObject:name forKey:FBSDKErrorArgumentNameKey]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.h index 5375a3d4b9..67faaedb5e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.h @@ -52,6 +52,9 @@ typedef NS_ENUM(NSUInteger, FBSDKFeature) FBSDKFeatureIntelligentIntegrity = 0x00010402, FBSDKFeatureModelRequest = 0x00010403, FBSDKFeatureEventDeactivation = 0x00010500, + FBSDKFeatureSKAdNetwork = 0x00010600, + FBSDKFeatureSKAdNetworkConversionValue = 0x00010601, + FBSDKFeatureATELogging = 0x00010700, /** Instrument */ FBSDKFeatureInstrument = 0x00020000, FBSDKFeatureCrashReport = 0x00020100, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.m index 314b61d80a..f685348ad0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKFeatureManager.m @@ -18,9 +18,8 @@ #import "FBSDKFeatureManager.h" -#import "ServerConfiguration/FBSDKGateKeeperManager.h" - #import "FBSDKSettings.h" +#import "ServerConfiguration/FBSDKGateKeeperManager.h" static NSString *const FBSDKFeatureManagerPrefix = @"com.facebook.sdk:FBSDKFeatureManager.FBSDKFeature"; @@ -42,7 +41,7 @@ + (void)checkFeature:(FBSDKFeature)feature return; } // check gk - [FBSDKGateKeeperManager loadGateKeepers:^(NSError * _Nullable error) { + [FBSDKGateKeeperManager loadGateKeepers:^(NSError *_Nullable error) { if (completionBlock) { completionBlock([FBSDKFeatureManager isEnabled:feature]); } @@ -78,7 +77,9 @@ + (FBSDKFeature)getParentFeature:(FBSDKFeature)feature return feature & 0xFFFF0000; } else if ((feature & 0xFF0000) > 0) { return feature & 0xFF000000; - } else return 0; + } else { + return 0; + } } + (BOOL)checkGK:(FBSDKFeature)feature @@ -104,11 +105,14 @@ + (NSString *)featureName:(FBSDKFeature)feature case FBSDKFeatureIntelligentIntegrity: featureName = @"IntelligentIntegrity"; break; case FBSDKFeatureModelRequest: featureName = @"ModelRequest"; break; case FBSDKFeatureEventDeactivation: featureName = @"EventDeactivation"; break; + case FBSDKFeatureSKAdNetwork: featureName = @"SKAdNetwork"; break; + case FBSDKFeatureSKAdNetworkConversionValue: featureName = @"SKAdNetworkConversionValue"; break; case FBSDKFeatureInstrument: featureName = @"Instrument"; break; case FBSDKFeatureCrashReport: featureName = @"CrashReport"; break; case FBSDKFeatureCrashShield: featureName = @"CrashShield"; break; case FBSDKFeatureErrorReport: featureName = @"ErrorReport"; break; case FBSDKFeatureMonitoring: featureName = @"Monitoring"; break; + case FBSDKFeatureATELogging: featureName = @"ATELogging"; break; case FBSDKFeatureLogin: featureName = @"LoginKit"; break; @@ -135,6 +139,9 @@ + (BOOL)defaultStatus:(FBSDKFeature)feature case FBSDKFeatureIntelligentIntegrity: case FBSDKFeatureModelRequest: case FBSDKFeatureMonitoring: + case FBSDKFeatureATELogging: + case FBSDKFeatureSKAdNetwork: + case FBSDKFeatureSKAdNetworkConversionValue: return NO; case FBSDKFeatureLogin: case FBDSDKFeatureShare: diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKImageDownloader.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKImageDownloader.m index 9b8f428439..8d41cf61f3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKImageDownloader.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKImageDownloader.m @@ -21,7 +21,8 @@ static NSString *const kImageDirectory = @"fbsdkimages"; static NSString *const kCachedResponseUserInfoKeyTimestamp = @"timestamp"; -@implementation FBSDKImageDownloader { +@implementation FBSDKImageDownloader +{ NSURLCache *_urlCache; } @@ -38,15 +39,15 @@ + (FBSDKImageDownloader *)sharedInstance - (instancetype)init { if ((self = [super init])) { -#if TARGET_OS_MACCATALYST - _urlCache = [[NSURLCache alloc] initWithMemoryCapacity:1024*1024*8 - diskCapacity:1024*1024*100 + #if TARGET_OS_MACCATALYST + _urlCache = [[NSURLCache alloc] initWithMemoryCapacity:1024 * 1024 * 8 + diskCapacity:1024 * 1024 * 100 directoryURL:[NSURL URLWithString:kImageDirectory]]; -#else - _urlCache = [[NSURLCache alloc] initWithMemoryCapacity:1024*1024*8 - diskCapacity:1024*1024*100 + #else + _urlCache = [[NSURLCache alloc] initWithMemoryCapacity:1024 * 1024 * 8 + diskCapacity:1024 * 1024 * 100 diskPath:kImageDirectory]; -#endif + #endif } return self; } @@ -65,7 +66,7 @@ - (void)downloadImageWithURL:(NSURL *)url NSDate *modificationDate = cachedResponse.userInfo[kCachedResponseUserInfoKeyTimestamp]; BOOL isExpired = ([[modificationDate dateByAddingTimeInterval:ttl] compare:[NSDate date]] == NSOrderedAscending); - void (^completionWrapper)(NSCachedURLResponse *) = ^(NSCachedURLResponse *responseData){ + void (^completionWrapper)(NSCachedURLResponse *) = ^(NSCachedURLResponse *responseData) { if (completion != NULL) { UIImage *image = [UIImage imageWithData:responseData.data]; completion(image); @@ -77,10 +78,10 @@ - (void)downloadImageWithURL:(NSURL *)url NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) { - if ([response isKindOfClass:[NSHTTPURLResponse class]] && - ((NSHTTPURLResponse *)response).statusCode == 200 && - error == nil && - data != nil) { + if ([response isKindOfClass:[NSHTTPURLResponse class]] + && ((NSHTTPURLResponse *)response).statusCode == 200 + && error == nil + && data != nil) { NSCachedURLResponse *responseToCache = [[NSCachedURLResponse alloc] initWithResponse:response data:data diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 850df429fa..9f5173901f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -18,36 +18,34 @@ #import "FBSDKInternalUtility.h" -#import - #import +#import #import "FBSDKCoreKit+Internal.h" #import "FBSDKError.h" -#import "FBSDKSettings+Internal.h" #import "FBSDKSettings.h" +#import "FBSDKSettings+Internal.h" -typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionMask) -{ +typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionMask) { FBSDKInternalUtilityMajorVersionMask = 0xFFFF0000, - //FBSDKInternalUtilityMinorVersionMask = 0x0000FF00, // unused - //FBSDKInternalUtilityPatchVersionMask = 0x000000FF, // unused + // FBSDKInternalUtilityMinorVersionMask = 0x0000FF00, // unused + // FBSDKInternalUtilityPatchVersionMask = 0x000000FF, // unused }; -typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionShift) -{ +typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionShift) { FBSDKInternalUtilityMajorVersionShift = 16, - //FBSDKInternalUtilityMinorVersionShift = 8, // unused - //FBSDKInternalUtilityPatchVersionShift = 0, // unused + // FBSDKInternalUtilityMinorVersionShift = 8, // unused + // FBSDKInternalUtilityPatchVersionShift = 0, // unused }; @implementation FBSDKInternalUtility -static BOOL ShouldOverrideHostWithGamingDomain(NSString *hostPrefix) { +static BOOL ShouldOverrideHostWithGamingDomain(NSString *hostPrefix) +{ return - [[FBSDKAccessToken currentAccessToken] respondsToSelector:@selector(graphDomain)] && - [[FBSDKAccessToken currentAccessToken].graphDomain isEqualToString:@"gaming"] && - ([hostPrefix isEqualToString:@"graph."] || [hostPrefix isEqualToString:@"graph-video."]); + [[FBSDKAccessToken currentAccessToken] respondsToSelector:@selector(graphDomain)] + && [[FBSDKAccessToken currentAccessToken].graphDomain isEqualToString:@"gaming"] + && ([hostPrefix isEqualToString:@"graph."] || [hostPrefix isEqualToString:@"graph-video."]); } #pragma mark - Class Methods @@ -56,7 +54,7 @@ + (NSString *)appURLScheme { NSString *appID = ([FBSDKSettings appID] ?: @""); NSString *suffix = ([FBSDKSettings appURLSchemeSuffix] ?: @""); - return [[NSString alloc] initWithFormat: @"fb%@%@", appID, suffix]; + return [[NSString alloc] initWithFormat:@"fb%@%@", appID, suffix]; } + (NSURL *)appURLWithHost:(NSString *)host @@ -122,7 +120,7 @@ + (void)extractPermissionsFromResponse:(NSDictionary *)responseObject } else if ([status isEqualToString:@"declined"]) { [declinedPermissions addObject:permissionName]; } else if ([status isEqualToString:@"expired"]) { - [expiredPermissions addObject:permissionName]; + [expiredPermissions addObject:permissionName]; } } } @@ -168,10 +166,10 @@ + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix if (path.length) { NSScanner *versionScanner = [[NSScanner alloc] initWithString:path]; - if ([versionScanner scanString:@"/v" intoString:NULL] && - [versionScanner scanInteger:NULL] && - [versionScanner scanString:@"." intoString:NULL] && - [versionScanner scanInteger:NULL]) { + if ([versionScanner scanString:@"/v" intoString:NULL] + && [versionScanner scanInteger:NULL] + && [versionScanner scanString:@"." intoString:NULL] + && [versionScanner scanInteger:NULL]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:[NSString stringWithFormat:@"Invalid Graph API version:%@, assuming %@ instead", version, @@ -199,8 +197,8 @@ + (BOOL)isBrowserURL:(NSURL *)URL + (BOOL)isFacebookBundleIdentifier:(NSString *)bundleIdentifier { - return ([bundleIdentifier hasPrefix:@"com.facebook."] || - [bundleIdentifier hasPrefix:@".com.facebook."]); + return ([bundleIdentifier hasPrefix:@"com.facebook."] + || [bundleIdentifier hasPrefix:@".com.facebook."]); } + (BOOL)isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version @@ -210,8 +208,8 @@ + (BOOL)isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version + (BOOL)isSafariBundleIdentifier:(NSString *)bundleIdentifier { - return ([bundleIdentifier isEqualToString:@"com.apple.mobilesafari"] || - [bundleIdentifier isEqualToString:@"com.apple.SafariViewService"]); + return ([bundleIdentifier isEqualToString:@"com.apple.mobilesafari"] + || [bundleIdentifier isEqualToString:@"com.apple.SafariViewService"]); } + (BOOL)isUIKitLinkTimeVersionAtLeast:(FBSDKUIKitVersion)version @@ -277,10 +275,10 @@ + (NSOperatingSystemVersion)operatingSystemVersion default: case 3: operatingSystemVersion.patchVersion = [[FBSDKTypeUtility array:components objectAtIndex:2] integerValue]; - // fall through + // fall through case 2: operatingSystemVersion.minorVersion = [[FBSDKTypeUtility array:components objectAtIndex:1] integerValue]; - // fall through + // fall through case 1: operatingSystemVersion.majorVersion = [[FBSDKTypeUtility array:components objectAtIndex:0] integerValue]; break; @@ -295,8 +293,8 @@ + (NSOperatingSystemVersion)operatingSystemVersion + (BOOL)shouldManuallyAdjustOrientation { - return (![self isUIKitLinkTimeVersionAtLeast:FBSDKUIKitVersion_8_0] || - ![self isUIKitRunTimeVersionAtLeast:FBSDKUIKitVersion_8_0]); + return (![self isUIKitLinkTimeVersionAtLeast:FBSDKUIKitVersion_8_0] + || ![self isUIKitRunTimeVersionAtLeast:FBSDKUIKitVersion_8_0]); } + (NSURL *)URLWithScheme:(NSString *)scheme @@ -460,12 +458,13 @@ + (void)validateAppID { if (![FBSDKSettings appID]) { NSString *reason = @"App ID not found. Add a string value with your app ID for the key " - @"FacebookAppID to the Info.plist or call [FBSDKSettings setAppID:]."; + @"FacebookAppID to the Info.plist or call [FBSDKSettings setAppID:]."; @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; } } -+ (NSString *)validateRequiredClientAccessToken { ++ (NSString *)validateRequiredClientAccessToken +{ if (![FBSDKSettings clientToken]) { NSString *reason = @"ClientToken is required to be set for this operation. " @"Set the FacebookClientToken in the Info.plist or call [FBSDKSettings setClientToken:]. " @@ -487,7 +486,7 @@ + (void)validateURLSchemes + (void)validateFacebookReservedURLSchemes { - for (NSString * fbUrlScheme in @[FBSDK_CANOPENURL_FACEBOOK, FBSDK_CANOPENURL_MESSENGER, FBSDK_CANOPENURL_FBAPI, FBSDK_CANOPENURL_SHARE_EXTENSION]) { + for (NSString *fbUrlScheme in @[FBSDK_CANOPENURL_FACEBOOK, FBSDK_CANOPENURL_MESSENGER, FBSDK_CANOPENURL_FBAPI, FBSDK_CANOPENURL_SHARE_EXTENSION]) { if ([self isRegisteredURLScheme:fbUrlScheme]) { NSString *reason = [NSString stringWithFormat:@"%@ is registered as a URL scheme. Please move the entry from CFBundleURLSchemes in your Info.plist to LSApplicationQueriesSchemes. If you are trying to resolve \"canOpenURL: failed\" warnings, those only indicate that the Facebook app is not installed on your device or simulator and can be ignored.", fbUrlScheme]; @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; @@ -497,10 +496,10 @@ + (void)validateFacebookReservedURLSchemes + (UIWindow *)findWindow { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" UIWindow *topWindow = [UIApplication sharedApplication].keyWindow; -#pragma clang diagnostic pop + #pragma clang diagnostic pop if (topWindow == nil || topWindow.windowLevel < UIWindowLevelNormal) { for (UIWindow *window in [UIApplication sharedApplication].windows) { if (window.windowLevel >= topWindow.windowLevel && !window.isHidden) { @@ -537,7 +536,7 @@ + (UIWindow *)findWindow if (topWindow == nil) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors - formatString:@"Unable to find a valid UIWindow", nil]; + formatString:@"Unable to find a valid UIWindow", nil]; } return topWindow; } @@ -572,6 +571,7 @@ + (UIInterfaceOrientation)statusBarOrientation return UIApplication.sharedApplication.statusBarOrientation; #endif } + #endif + (NSString *)hexadecimalStringFromData:(NSData *)data @@ -582,14 +582,15 @@ + (NSString *)hexadecimalStringFromData:(NSData *)data } const unsigned char *dataBuffer = data.bytes; - NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; + NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; for (int i = 0; i < dataLength; ++i) { [hexString appendFormat:@"%02x", dataBuffer[i]]; } return [hexString copy]; } -+ (BOOL)isRegisteredURLScheme:(NSString *)urlScheme { ++ (BOOL)isRegisteredURLScheme:(NSString *)urlScheme +{ static dispatch_once_t fetchBundleOnce; static NSArray *urlTypes = nil; @@ -622,7 +623,7 @@ + (void)checkRegisteredCanOpenURLScheme:(NSString *)urlScheme } } - if (![self isRegisteredCanOpenURLScheme:urlScheme]){ + if (![self isRegisteredCanOpenURLScheme:urlScheme]) { NSString *reason = [NSString stringWithFormat:@"%@ is missing from your Info.plist under LSApplicationQueriesSchemes and is required for iOS 9.0", urlScheme]; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:reason]; } @@ -642,11 +643,11 @@ + (BOOL)isRegisteredCanOpenURLScheme:(NSString *)urlScheme + (BOOL)isPublishPermission:(NSString *)permission { - return [permission hasPrefix:@"publish"] || - [permission hasPrefix:@"manage"] || - [permission isEqualToString:@"ads_management"] || - [permission isEqualToString:@"create_event"] || - [permission isEqualToString:@"rsvp_event"]; + return [permission hasPrefix:@"publish"] + || [permission hasPrefix:@"manage"] + || [permission isEqualToString:@"ads_management"] + || [permission isEqualToString:@"create_event"] + || [permission isEqualToString:@"rsvp_event"]; } + (BOOL)isUnity diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.m index f1eebcbdb8..38a471f80d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.m @@ -27,7 +27,7 @@ @interface FBSDKLogger () -@property (nonatomic, strong, readonly) NSMutableString *internalContents; +@property (nonatomic, readonly, strong) NSMutableString *internalContents; @end @@ -84,7 +84,6 @@ - (void)appendFormat:(NSString *)formatString, ... } } - - (void)appendKey:(NSString *)key value:(NSString *)value { if (_active && value.length) { @@ -95,7 +94,6 @@ - (void)appendKey:(NSString *)key value:(NSString *)value - (void)emitToNSLog { if (_active) { - for (NSString *key in [g_stringsToReplace keyEnumerator]) { [_internalContents replaceOccurrencesOfString:key withString:g_stringsToReplace[key] @@ -123,7 +121,8 @@ + (NSUInteger)generateSerialNumber } + (void)singleShotLogEntry:(NSString *)loggingBehavior - logEntry:(NSString *)logEntry { + logEntry:(NSString *)logEntry +{ if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) { FBSDKLogger *logger = [[FBSDKLogger alloc] initWithLoggingBehavior:loggingBehavior]; [logger appendString:logEntry]; @@ -132,8 +131,8 @@ + (void)singleShotLogEntry:(NSString *)loggingBehavior } + (void)singleShotLogEntry:(NSString *)loggingBehavior - formatString:(NSString *)formatString, ... { - + formatString:(NSString *)formatString, ... +{ if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) { va_list vaArguments; va_start(vaArguments, formatString); @@ -144,11 +143,10 @@ + (void)singleShotLogEntry:(NSString *)loggingBehavior } } - + (void)singleShotLogEntry:(NSString *)loggingBehavior timestampTag:(NSObject *)timestampTag - formatString:(NSString *)formatString, ... { - + formatString:(NSString *)formatString, ... +{ if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) { va_list vaArguments; va_start(vaArguments, formatString); @@ -164,7 +162,7 @@ + (void)singleShotLogEntry:(NSString *)loggingBehavior // Only log if there's been an associated start time. if (startTimeNumber != nil) { uint64_t elapsed = [FBSDKInternalUtility currentTimeInMilliseconds] - startTimeNumber.unsignedLongLongValue; - [g_startTimesWithTags removeObjectForKey:tagAsNumber]; // served its purpose, remove + [g_startTimesWithTags removeObjectForKey:tagAsNumber]; // served its purpose, remove // Log string is appended with "%d msec", with nothing intervening. This gives the most control to the caller. logString = [NSString stringWithFormat:@"%@%llu msec", logString, elapsed]; @@ -175,10 +173,9 @@ + (void)singleShotLogEntry:(NSString *)loggingBehavior } + (void)registerCurrentTime:(NSString *)loggingBehavior - withTag:(NSObject *)timestampTag { - + withTag:(NSObject *)timestampTag +{ if ([FBSDKSettings.loggingBehaviors containsObject:loggingBehavior]) { - if (!g_startTimesWithTags) { g_startTimesWithTags = [[NSMutableDictionary alloc] init]; } @@ -197,14 +194,12 @@ + (void)registerCurrentTime:(NSString *)loggingBehavior } } - + (void)registerStringToReplace:(NSString *)replace - replaceWith:(NSString *)replaceWith { - + replaceWith:(NSString *)replaceWith +{ // Strings sent in here never get cleaned up, but that's OK, don't ever expect too many. - if (FBSDKSettings.loggingBehaviors.count > 0) { // otherwise there's no logging. - + if (FBSDKSettings.loggingBehaviors.count > 0) { // otherwise there's no logging. if (!g_stringsToReplace) { g_stringsToReplace = [[NSMutableDictionary alloc] init]; } @@ -213,6 +208,4 @@ + (void)registerStringToReplace:(NSString *)replace } } - - @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.m index 302e80b170..0117061ba7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.m @@ -117,7 +117,7 @@ + (NSUInteger)hashWithLong:(unsigned long long)value { value = (~value) + (value << 18); // key = (key << 18) - key - 1; value ^= (value >> 31); - value *= 21; // key = (key + (key << 2)) + (key << 4); + value *= 21; // key = (key + (key << 2)) + (key << 4); value ^= (value >> 11); value += (value << 6); value ^= (value >> 22); @@ -128,18 +128,18 @@ + (NSUInteger)hashWithPointer:(const void *)value { NSUInteger hash = (NSUInteger)value; #if !TARGET_RT_64_BIT - hash = ~hash + (hash << 15); // key = (key << 15) - key - 1; + hash = ~hash + (hash << 15); // key = (key << 15) - key - 1; hash ^= (hash >> 12); hash += (hash << 2); hash ^= (hash >> 4); - hash *= 2057; // key = (key + (key << 3)) + (key << 11); + hash *= 2057; // key = (key + (key << 3)) + (key << 11); hash ^= (hash >> 16); #else - hash += ~hash + (hash << 21); // key = (key << 21) - key - 1; + hash += ~hash + (hash << 21); // key = (key << 21) - key - 1; hash ^= (hash >> 24); hash = (hash + (hash << 3)) + (hash << 8); hash ^= (hash >> 14); - hash = (hash + (hash << 2)) + (hash << 4); // key * 21 + hash = (hash + (hash << 2)) + (hash << 4); // key * 21 hash ^= (hash >> 28); hash += (hash << 31); #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMeasurementEvent_Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMeasurementEvent_Internal.h index f90322ad2b..68b3257d02 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMeasurementEvent_Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMeasurementEvent_Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKMeasurementEvent.h" + #import "FBSDKMeasurementEvent.h" NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.h index 6717c91035..32c28ec638 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#include + #include typedef double FBSDKMonotonicTimeSeconds; typedef uint64_t FBSDKMonotonicTimeMilliseconds; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.m index 362834c199..49705470f4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.m @@ -20,13 +20,12 @@ #if !TARGET_OS_TV -#import "FBSDKMonotonicTime.h" + #import "FBSDKMonotonicTime.h" -#include -#include -#include - -#include + #include + #include + #include + #include /** * PLEASE NOTE: FBSDKSDKMonotonicTimeTests work fine, but are disabled @@ -35,59 +34,59 @@ */ static uint64_t _get_time_nanoseconds(void) { - static struct mach_timebase_info tb_info = {0}; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - int ret = mach_timebase_info(&tb_info); - assert(0 == ret); - }); + static struct mach_timebase_info tb_info = {0}; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + int ret = mach_timebase_info(&tb_info); + assert(0 == ret); + }); - return (mach_absolute_time() * tb_info.numer) / tb_info.denom; + return (mach_absolute_time() * tb_info.numer) / tb_info.denom; } FBSDKMonotonicTimeSeconds FBSDKMonotonicTimeGetCurrentSeconds(void) { - const uint64_t nowNanoSeconds = _get_time_nanoseconds(); - return (FBSDKMonotonicTimeSeconds)nowNanoSeconds / (FBSDKMonotonicTimeSeconds)1000000000.0; + const uint64_t nowNanoSeconds = _get_time_nanoseconds(); + return (FBSDKMonotonicTimeSeconds)nowNanoSeconds / (FBSDKMonotonicTimeSeconds)1000000000.0; } FBSDKMonotonicTimeMilliseconds FBSDKMonotonicTimeGetCurrentMilliseconds(void) { - const uint64_t nowNanoSeconds = _get_time_nanoseconds(); - return nowNanoSeconds / 1000000; + const uint64_t nowNanoSeconds = _get_time_nanoseconds(); + return nowNanoSeconds / 1000000; } FBSDKMonotonicTimeNanoseconds FBSDKMonotonicTimeGetCurrentNanoseconds(void) { - return _get_time_nanoseconds(); + return _get_time_nanoseconds(); } FBSDKMachAbsoluteTimeUnits FBSDKMonotonicTimeConvertSecondsToMachUnits(FBSDKMonotonicTimeSeconds seconds) { - static double ratio = 0; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - struct mach_timebase_info tb_info = {0}; - int ret = mach_timebase_info(&tb_info); - assert(0 == ret); - ratio = ((double) tb_info.denom / (double)tb_info.numer) * 1000000000.0; - }); + static double ratio = 0; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + struct mach_timebase_info tb_info = {0}; + int ret = mach_timebase_info(&tb_info); + assert(0 == ret); + ratio = ((double) tb_info.denom / (double)tb_info.numer) * 1000000000.0; + }); - return seconds * ratio; + return seconds * ratio; } FBSDKMonotonicTimeSeconds FBSDKMonotonicTimeConvertMachUnitsToSeconds(FBSDKMachAbsoluteTimeUnits machUnits) { - static double ratio = 0; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - struct mach_timebase_info tb_info = {0}; - int ret = mach_timebase_info(&tb_info); - assert(0 == ret); - ratio = ((double) tb_info.numer / (double)tb_info.denom) / 1000000000.0; - }); + static double ratio = 0; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + struct mach_timebase_info tb_info = {0}; + int ret = mach_timebase_info(&tb_info); + assert(0 == ret); + ratio = ((double) tb_info.numer / (double)tb_info.denom) / 1000000000.0; + }); - return ratio * (double)machUnits; + return ratio * (double)machUnits; } #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h index 12b07a9a2a..2322d67765 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h @@ -20,11 +20,11 @@ #if !TARGET_OS_TV -#import "FBSDKProfile.h" + #import "FBSDKProfile.h" NS_ASSUME_NONNULL_BEGIN -@interface FBSDKProfile(Internal) +@interface FBSDKProfile (Internal) + (void)cacheProfile:(nullable FBSDKProfile *)profile; + (nullable FBSDKProfile *)fetchCachedProfile; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h index 2e8c803220..a018c37683 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h @@ -17,30 +17,48 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if SWIFT_PACKAGE -#import "FBSDKSettings.h" + #import "FBSDKSettings.h" #else -#import + #import #endif +#import "FBSDKCoreKit+Internal.h" + #define DATA_PROCESSING_OPTIONS @"data_processing_options" #define DATA_PROCESSING_OPTIONS_COUNTRY @"data_processing_options_country" #define DATA_PROCESSING_OPTIONS_STATE @"data_processing_options_state" @protocol FBSDKAccessTokenCaching; -@interface FBSDKSettings(Internal) +@interface FBSDKSettings (Internal) + (nullable NSObject *)accessTokenCache; + (void)setAccessTokenCache:(nullable NSObject *)accessTokenCache; ++ (FBSDKAdvertisingTrackingStatus)getAdvertisingTrackingStatus; + ++ (void)setAdvertiserTrackingStatus:(FBSDKAdvertisingTrackingStatus)status; + + (nullable NSDictionary *)dataProcessingOptions; + (BOOL)isDataProcessingRestricted; -@property (class, nonatomic, copy, readonly, nullable) NSString *graphAPIDebugParamValue; ++ (void)recordInstall; + ++ (void)recordSetAdvertiserTrackingEnabled; + ++ (BOOL)isEventDelayTimerExpired; + ++ (BOOL)isSetATETimeExceedsInstallTime; + ++ (NSDate *_Nullable)getInstallTimestamp; + ++ (NSDate *_Nullable)getSetAdvertiserTrackingEnabledTimestamp; + +@property (class, nullable, nonatomic, readonly, copy) NSString *graphAPIDebugParamValue; // used by Unity. -@property (class, nonatomic, copy, nullable) NSString *userAgentSuffix; +@property (class, nullable, nonatomic, copy) NSString *userAgentSuffix; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSwizzler.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSwizzler.m index 75f0017aca..80616a51d8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSwizzler.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSwizzler.m @@ -30,8 +30,6 @@ #define FB_REMOVE_SELECTOR \ [FBSDKSwizzler object:self ofClass:swizzlingOnClass.bindingClass removeSelector:_cmd]; - - @interface FBSDKSwizzle : NSObject @property (nonatomic, assign) Class class; @@ -49,7 +47,6 @@ - (instancetype)initWithBlock:(swizzleBlock)aBlock @end - @interface FBSDKSwizzlingOnClass : NSObject @property FBSDKSwizzle *bindingSwizzle; @@ -60,7 +57,6 @@ - (instancetype)initWithSwizzle:(FBSDKSwizzle *)aSwizzle @end - @interface FBSDKSwizzler () + (void)object:(id)anObject ofClass:(Class)aClass addSelector:(SEL)aSelector; @@ -69,12 +65,12 @@ + (BOOL)object:(id)anObject ofClass:(Class)aClass isCallingSelector:(SEL)aSelect @end - static NSMapTable *swizzles; static NSMutableSet *selectorCallingSet; static dispatch_queue_t swizzleQueue; -static FBSDKSwizzlingOnClass* fb_findSwizzle(id self, SEL _cmd){ +static FBSDKSwizzlingOnClass *fb_findSwizzle(id self, SEL _cmd) +{ Method aMethod = class_getInstanceMethod([self class], _cmd); Class this_class = [self class]; FBSDKSwizzle *swizzle = nil; @@ -83,7 +79,7 @@ + (BOOL)object:(id)anObject ofClass:(Class)aClass isCallingSelector:(SEL)aSelect swizzle = (FBSDKSwizzle *)[swizzles objectForKey:MAPTABLE_ID(aMethod)]; } - while (!swizzle && class_getSuperclass(this_class)){ + while (!swizzle && class_getSuperclass(this_class)) { this_class = class_getSuperclass(this_class); aMethod = class_getInstanceMethod(this_class, _cmd); @@ -104,7 +100,7 @@ static void fb_swizzledMethod_2(id self, SEL _cmd) { FB_FIND_SWIZZLE; if (swizzle) { - ((void(*)(id, SEL))swizzle.originalMethod)(self, _cmd); + ((void (*)(id, SEL))swizzle.originalMethod)(self, _cmd); NSEnumerator *blocks = [swizzle.blocks objectEnumerator]; swizzleBlock block; @@ -119,7 +115,7 @@ static void fb_swizzledMethod_3(id self, SEL _cmd, id arg) { FB_FIND_SWIZZLE; if (swizzle) { - ((void(*)(id, SEL, id))swizzle.originalMethod)(self, _cmd, arg); + ((void (*)(id, SEL, id))swizzle.originalMethod)(self, _cmd, arg); NSEnumerator *blocks = [swizzle.blocks objectEnumerator]; swizzleBlock block; @@ -134,7 +130,7 @@ static void fb_swizzledMethod_4(id self, SEL _cmd, id arg, id arg2) { FB_FIND_SWIZZLE; if (swizzle) { - ((void(*)(id, SEL, id, id))swizzle.originalMethod)(self, _cmd, arg, arg2); + ((void (*)(id, SEL, id, id))swizzle.originalMethod)(self, _cmd, arg, arg2); NSEnumerator *blocks = [swizzle.blocks objectEnumerator]; swizzleBlock block; @@ -149,7 +145,7 @@ static void fb_swizzledMethod_5(id self, SEL _cmd, id arg, id arg2, id arg3) { FB_FIND_SWIZZLE; if (swizzle) { - ((void(*)(id, SEL, id, id, id))swizzle.originalMethod)(self, _cmd, arg, arg2, arg3); + ((void (*)(id, SEL, id, id, id))swizzle.originalMethod)(self, _cmd, arg, arg2, arg3); NSEnumerator *blocks = [swizzle.blocks objectEnumerator]; swizzleBlock block; @@ -164,7 +160,7 @@ static void fb_swizzleMethod_4_io(id self, SEL _cmd, NSInteger arg, id arg2) { FB_FIND_SWIZZLE; if (swizzle) { - ((void(*)(id, SEL, NSInteger, id))swizzle.originalMethod)(self, _cmd, arg, arg2); + ((void (*)(id, SEL, NSInteger, id))swizzle.originalMethod)(self, _cmd, arg, arg2); NSEnumerator *blocks = [swizzle.blocks objectEnumerator]; swizzleBlock block; @@ -186,10 +182,10 @@ @implementation FBSDKSwizzler + (void)initialize { - swizzles = [NSMapTable mapTableWithKeyOptions:(NSPointerFunctionsOpaqueMemory | - NSPointerFunctionsOpaquePersonality) - valueOptions:(NSPointerFunctionsStrongMemory | - NSPointerFunctionsObjectPointerPersonality)]; + swizzles = [NSMapTable mapTableWithKeyOptions:(NSPointerFunctionsOpaqueMemory + | NSPointerFunctionsOpaquePersonality) + valueOptions:(NSPointerFunctionsStrongMemory + | NSPointerFunctionsObjectPointerPersonality)]; selectorCallingSet = [NSMutableSet set]; swizzleQueue = dispatch_queue_create("com.facebook.swizzler", DISPATCH_QUEUE_SERIAL); [FBSDKSwizzler resolveConflict]; @@ -247,57 +243,59 @@ + (BOOL)isLocallyDefinedMethod:(Method)aMethod onClass:(Class)aClass + (void)swizzleSelector:(SEL)aSelector onClass:(Class)aClass withBlock:(swizzleBlock)aBlock named:(NSString *)aName { dispatch_async(swizzleQueue, ^{ - Method aMethod = class_getInstanceMethod(aClass, aSelector); - if (aMethod) { - uint numArgs = method_getNumberOfArguments(aMethod); - if (numArgs >= MIN_ARGS && numArgs <= MAX_ARGS) { - - BOOL isLocal = [FBSDKSwizzler isLocallyDefinedMethod:aMethod onClass:aClass]; - IMP swizzledMethod = (IMP)fb_swizzledMethods[numArgs - 2]; - // Check whether the first parameter is integer - if (4 == numArgs) { - char *type = method_copyArgumentType(aMethod, 2); - NSString *firstType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding]; - NSString *integerTypes = @"islq"; - if ([integerTypes containsString:firstType.lowercaseString]) { - swizzledMethod = (IMP)fb_swizzleMethod_4_io; + @try { + Method aMethod = class_getInstanceMethod(aClass, aSelector); + if (aMethod) { + uint numArgs = method_getNumberOfArguments(aMethod); + if (numArgs >= MIN_ARGS && numArgs <= MAX_ARGS) { + BOOL isLocal = [FBSDKSwizzler isLocallyDefinedMethod:aMethod onClass:aClass]; + IMP swizzledMethod = (IMP)fb_swizzledMethods[numArgs - 2]; + // Check whether the first parameter is integer + if (4 == numArgs) { + char *type = method_copyArgumentType(aMethod, 2); + NSString *firstType = [NSString stringWithCString:type encoding:NSUTF8StringEncoding]; + NSString *integerTypes = @"islq"; + if ([integerTypes containsString:firstType.lowercaseString]) { + swizzledMethod = (IMP)fb_swizzleMethod_4_io; + } + free(type); } - free(type); - } - - FBSDKSwizzle *swizzle = [FBSDKSwizzler swizzleForMethod:aMethod]; - if (isLocal) { - if (!swizzle) { - IMP originalMethod = method_getImplementation(aMethod); + FBSDKSwizzle *swizzle = [FBSDKSwizzler swizzleForMethod:aMethod]; - // Replace the local implementation of this method with the swizzled one - method_setImplementation(aMethod,swizzledMethod); + if (isLocal) { + if (!swizzle) { + IMP originalMethod = method_getImplementation(aMethod); - // Create and add the swizzle - swizzle = [[FBSDKSwizzle alloc] initWithBlock:aBlock named:aName forClass:aClass selector:aSelector originalMethod:originalMethod withNumArgs:numArgs]; - [FBSDKSwizzler setSwizzle:swizzle forMethod:aMethod]; + // Replace the local implementation of this method with the swizzled one + method_setImplementation(aMethod, swizzledMethod); + // Create and add the swizzle + swizzle = [[FBSDKSwizzle alloc] initWithBlock:aBlock named:aName forClass:aClass selector:aSelector originalMethod:originalMethod withNumArgs:numArgs]; + [FBSDKSwizzler setSwizzle:swizzle forMethod:aMethod]; + } else { + [swizzle.blocks setObject:aBlock forKey:aName]; + } } else { - [swizzle.blocks setObject:aBlock forKey:aName]; - } - } else { - IMP originalMethod = swizzle ? swizzle.originalMethod : method_getImplementation(aMethod); - - // Add the swizzle as a new local method on the class. - if (!class_addMethod(aClass, aSelector, swizzledMethod, method_getTypeEncoding(aMethod))) { - return; + IMP originalMethod = swizzle ? swizzle.originalMethod : method_getImplementation(aMethod); + + // Add the swizzle as a new local method on the class. + if (!class_addMethod(aClass, aSelector, swizzledMethod, method_getTypeEncoding(aMethod))) { + return; + } + // Now re-get the Method, it should be the one we just added. + Method newMethod = class_getInstanceMethod(aClass, aSelector); + if (aMethod == newMethod) { + return; + } + + FBSDKSwizzle *newSwizzle = [[FBSDKSwizzle alloc] initWithBlock:aBlock named:aName forClass:aClass selector:aSelector originalMethod:originalMethod withNumArgs:numArgs]; + [FBSDKSwizzler setSwizzle:newSwizzle forMethod:newMethod]; } - // Now re-get the Method, it should be the one we just added. - Method newMethod = class_getInstanceMethod(aClass, aSelector); - if (aMethod == newMethod) { - return; - } - - FBSDKSwizzle *newSwizzle = [[FBSDKSwizzle alloc] initWithBlock:aBlock named:aName forClass:aClass selector:aSelector originalMethod:originalMethod withNumArgs:numArgs]; - [FBSDKSwizzler setSwizzle:newSwizzle forMethod:newMethod]; } } + } @catch (NSException *exception) { + NSLog(@"Fail to swizzle selector. Exception reason: %@", exception.reason); } }); } @@ -318,23 +316,27 @@ + (void)unswizzleSelector:(SEL)aSelector onClass:(Class)aClass */ + (void)unswizzleSelector:(SEL)aSelector onClass:(Class)aClass named:(NSString *)aName { - Method aMethod = class_getInstanceMethod(aClass, aSelector); - FBSDKSwizzle *swizzle = [FBSDKSwizzler swizzleForMethod:aMethod]; - if (swizzle) { - if (aName) { - [swizzle.blocks removeObjectForKey:aName]; - } - if (!aName || swizzle.blocks.count == 0) { - method_setImplementation(aMethod, swizzle.originalMethod); - [FBSDKSwizzler removeSwizzleForMethod:aMethod]; + @try { + Method aMethod = class_getInstanceMethod(aClass, aSelector); + FBSDKSwizzle *swizzle = [FBSDKSwizzler swizzleForMethod:aMethod]; + if (swizzle) { + if (aName) { + [swizzle.blocks removeObjectForKey:aName]; + } + if (!aName || swizzle.blocks.count == 0) { + method_setImplementation(aMethod, swizzle.originalMethod); + [FBSDKSwizzler removeSwizzleForMethod:aMethod]; + } } + } @catch (NSException *exception) { + NSLog(@"Fail to remove the named swizzle from given class/selector. Exception reason: %@", exception.reason); } } + (void)object:(id)anObject ofClass:(Class)aClass addSelector:(SEL)aSelector { NSString *objectClassSelectorString = [NSString stringWithFormat:@"%p %@ %@", anObject, NSStringFromClass(aClass), NSStringFromSelector(aSelector)]; - @synchronized (selectorCallingSet) { + @synchronized(selectorCallingSet) { [selectorCallingSet addObject:objectClassSelectorString]; } } @@ -342,7 +344,7 @@ + (void)object:(id)anObject ofClass:(Class)aClass addSelector:(SEL)aSelector + (void)object:(id)anObject ofClass:(Class)aClass removeSelector:(SEL)aSelector { NSString *objectClassSelectorString = [NSString stringWithFormat:@"%p %@ %@", anObject, NSStringFromClass(aClass), NSStringFromSelector(aSelector)]; - @synchronized (selectorCallingSet) { + @synchronized(selectorCallingSet) { [selectorCallingSet removeObject:objectClassSelectorString]; } } @@ -358,16 +360,15 @@ + (BOOL)object:(id)anObject ofClass:(Class)aClass isCallingSelector:(SEL)aSelect @end - @implementation FBSDKSwizzle - (instancetype)init { if (self = [super init]) { self.blocks = [NSMapTable mapTableWithKeyOptions:(NSPointerFunctionsStrongMemory - | NSPointerFunctionsObjectPersonality) + | NSPointerFunctionsObjectPersonality) valueOptions:(NSPointerFunctionsStrongMemory - | NSPointerFunctionsObjectPointerPersonality)]; + | NSPointerFunctionsObjectPointerPersonality)]; } return self; } @@ -403,7 +404,6 @@ - (NSString *)description @end - @implementation FBSDKSwizzlingOnClass - (instancetype)initWithSwizzle:(FBSDKSwizzle *)aSwizzle diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m index 727752a8d8..14d02f7c4e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKTriStateBOOL.h" + #import "FBSDKTriStateBOOL.h" FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value) { @@ -29,9 +29,9 @@ FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value) FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value) { - return ([value isKindOfClass:[NSNumber class]] ? - FBSDKTriStateBOOLFromBOOL(value.boolValue) : - FBSDKTriStateBOOLValueUnknown); + return ([value isKindOfClass:[NSNumber class]] + ? FBSDKTriStateBOOLFromBOOL(value.boolValue) + : FBSDKTriStateBOOLValueUnknown); } BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKURL_Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKURL_Internal.h index e5da05163c..f17259ddcb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKURL_Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKURL_Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKURL.h" + #import "FBSDKURL.h" @interface FBSDKURL (Internal) + (FBSDKURL *)URLForRenderBackToReferrerBarURL:(NSURL *)url; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.h index f7ea35bced..f53c8dcfc7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.h @@ -18,11 +18,11 @@ #import -#import "FBSDKCrashObserving.h" +#import "FBSDKInternalUtility.h" NS_ASSUME_NONNULL_BEGIN -@interface FBSDKCrashObserver : NSObject +@interface FBSDKCrashObserver : NSObject + (void)enable; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.m index fcfb13e5c8..62df5eaa6b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashObserver.m @@ -18,15 +18,12 @@ #import "FBSDKCrashObserver.h" -#import "FBSDKCrashHandler.h" #import "FBSDKCrashShield.h" #import "FBSDKFeatureManager.h" #import "FBSDKGraphRequest.h" #import "FBSDKGraphRequestConnection.h" -#import "FBSDKLibAnalyzer.h" #import "FBSDKSettings.h" #import "FBSDKSettings+Internal.h" -#import "FBSDKTypeUtility.h" @implementation FBSDKCrashObserver diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m index 1514586197..0b38e76d2f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m @@ -21,9 +21,9 @@ #import "FBSDKFeatureManager.h" #import "FBSDKGraphRequest.h" #import "FBSDKGraphRequestConnection.h" +#import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" #import "FBSDKSettings+Internal.h" -#import "FBSDKTypeUtility.h" @implementation FBSDKCrashShield @@ -35,37 +35,43 @@ + (void)initialize _featureMapping = @{ @"AAM" : @[ - @"FBSDKMetadataIndexer", + @"FBSDKMetadataIndexer", ], @"CodelessEvents" : @[ - @"FBSDKCodelessIndexer", - @"FBSDKEventBinding", - @"FBSDKEventBindingManager", - @"FBSDKViewHierarchy", - @"FBSDKCodelessPathComponent", - @"FBSDKCodelessParameterComponent", + @"FBSDKCodelessIndexer", + @"FBSDKEventBinding", + @"FBSDKEventBindingManager", + @"FBSDKViewHierarchy", + @"FBSDKCodelessPathComponent", + @"FBSDKCodelessParameterComponent", ], @"RestrictiveDataFiltering" : @[ - @"FBSDKRestrictiveDataFilterManager", + @"FBSDKRestrictiveDataFilterManager", ], @"ErrorReport" : @[ - @"FBSDKErrorReport", + @"FBSDKErrorReport", ], @"PrivacyProtection" : @[ - @"FBSDKModelManager", + @"FBSDKModelManager", ], @"SuggestedEvents" : @[ - @"FBSDKSuggestedEventsIndexer", - @"FBSDKFeatureExtractor", + @"FBSDKSuggestedEventsIndexer", + @"FBSDKFeatureExtractor", ], @"IntelligentIntegrity" : @[ - @"FBSDKIntegrityManager", + @"FBSDKIntegrityManager", ], @"EventDeactivation" : @[ - @"FBSDKEventDeactivationManager", + @"FBSDKEventDeactivationManager", + ], + @"SKAdNetworkConversionValue" : @[ + @"FBSDKSKAdNetworkReporter", + @"FBSDKSKAdNetworkConversionConfiguration", + @"FBSDKSKAdNetworkRule", + @"FBSDKSKAdNetworkEvent", ], @"Monitoring" : @[ - @"FBSDKMonitor", + @"FBSDKMonitor", ], }; } @@ -77,25 +83,24 @@ + (void)analyze:(NSArray *> *)crashLogs for (NSDictionary *crashLog in crashLogs) { NSArray *callstack = crashLog[@"callstack"]; NSString *featureName = [self getFeature:callstack]; - if (featureName) { - [FBSDKFeatureManager disableFeature:featureName]; - [disabledFeatues addObject:featureName]; - continue; - } + if (featureName) { + [FBSDKFeatureManager disableFeature:featureName]; + [disabledFeatues addObject:featureName]; + continue; + } } if ([FBSDKSettings isDataProcessingRestricted]) { return; } if (disabledFeatues.count > 0) { - NSDictionary *disabledFeatureLog = @{@"feature_names":[disabledFeatues allObjects], - @"timestamp":[NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]], - }; + NSDictionary *disabledFeatureLog = @{@"feature_names" : [disabledFeatues allObjects], + @"timestamp" : [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]], }; NSData *jsonData = [FBSDKTypeUtility dataWithJSONObject:disabledFeatureLog options:0 error:nil]; if (jsonData) { NSString *disabledFeatureReport = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; if (disabledFeatureReport) { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/instruments", [FBSDKSettings appID]] - parameters:@{@"crash_shield":disabledFeatureReport} + parameters:@{@"crash_shield" : disabledFeatureReport} HTTPMethod:FBSDKHTTPMethodPOST]; [request startWithCompletionHandler:nil]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.h index 16d1c6604e..b73dfa66bd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.h @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import + #import "FBSDKError.h" NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m index 2803adf994..a39661867f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m @@ -20,10 +20,10 @@ #import "FBSDKGraphRequest.h" #import "FBSDKGraphRequestConnection.h" +#import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" #import "FBSDKSettings+Internal.h" -#import "FBSDKTypeUtility.h" #define FBSDK_MAX_ERROR_REPORT_LOGS 1000 @@ -61,7 +61,7 @@ + (void)uploadError return [self clearErrorInfo]; } NSData *jsonData = [FBSDKTypeUtility dataWithJSONObject:errorReports options:0 error:nil]; - if (!jsonData){ + if (!jsonData) { return; } NSString *errorData = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; @@ -81,35 +81,35 @@ + (void)saveError:(NSInteger)errorCode message:(nullable NSString *)message { NSString *timestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; - [self saveErrorInfoToDisk: @{ - kFBSDKErrorCode:@(errorCode), - kFBSDKErrorDomain:errorDomain, - kFBSDKErrorTimestamp:timestamp, - }]; + [self saveErrorInfoToDisk:@{ + kFBSDKErrorCode : @(errorCode), + kFBSDKErrorDomain : errorDomain, + kFBSDKErrorTimestamp : timestamp, + }]; } + (NSArray *> *)loadErrorReports { NSMutableArray *> *errorReportArr = [NSMutableArray array]; NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:NULL]; - NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL (id _Nullable evaluatedObject, NSDictionary *_Nullable bindings) { NSString *str = (NSString *)evaluatedObject; return [str hasPrefix:@"error_report_"] && [str hasSuffix:@".json"]; }]; fileNames = [fileNames filteredArrayUsingPredicate:predicate]; - fileNames = [fileNames sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2){ + fileNames = [fileNames sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { return [obj2 compare:obj1]; }]; - if (fileNames.count > 0){ + if (fileNames.count > 0) { fileNames = [fileNames subarrayWithRange:NSMakeRange(0, MIN(fileNames.count, FBSDK_MAX_ERROR_REPORT_LOGS))]; for (NSUInteger i = 0; i < fileNames.count; i++) { NSData *data = [NSData dataWithContentsOfFile:[directoryPath stringByAppendingPathComponent:[FBSDKTypeUtility array:fileNames objectAtIndex:i]] options:NSDataReadingMappedIfSafe error:nil]; if (data) { - NSDictionary *errorReport = [FBSDKTypeUtility JSONObjectWithData:data - options:0 - error:nil]; + NSDictionary *errorReport = [FBSDKTypeUtility JSONObjectWithData:data + options:0 + error:nil]; if (errorReport) { [FBSDKTypeUtility array:errorReportArr addObject:errorReport]; } @@ -143,6 +143,7 @@ + (void)saveErrorInfoToDisk:(NSDictionary *)errorInfo + (NSString *)pathToErrorInfoFile { NSString *timestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; - return [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"error_report_%@.json",timestamp]]; + return [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"error_report_%@.json", timestamp]]; } + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.h index 15ffa668a4..877ebd1921 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN `FBSDKMethodUsageMonitor` to record methods. That will create and persist an entry. */ -@interface FBSDKMethodUsageMonitorEntry : NSObject +@interface FBSDKMethodUsageMonitorEntry : NSObject + (instancetype)new NS_UNAVAILABLE; + (instancetype)entryFromClass:(Class)clazz withMethod:(SEL)method; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.m index 7905d339ac..f507adeaa6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMethodUsageMonitorEntry.m @@ -18,10 +18,11 @@ #import "FBSDKMethodUsageMonitorEntry.h" -static NSString * const FBSDKMethodUsageNameKey = @"event_name"; -static NSString * const FBSDKMethodUsageClassKey = @"method_usage_class"; +static NSString *const FBSDKMethodUsageNameKey = @"event_name"; +static NSString *const FBSDKMethodUsageClassKey = @"method_usage_class"; -@implementation FBSDKMethodUsageMonitorEntry { +@implementation FBSDKMethodUsageMonitorEntry +{ SEL _method; Class _class; NSString *_name; @@ -66,7 +67,7 @@ - (NSString *)name - (NSDictionary *)dictionaryRepresentation { - return @{FBSDKMethodUsageNameKey: [self name]}; + return @{FBSDKMethodUsageNameKey : [self name]}; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitor.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitor.m index 88a99cf6cb..d671e4f3c1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitor.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitor.m @@ -24,7 +24,7 @@ @interface FBSDKMonitor () -@property (class, nonatomic, copy, readonly) NSMutableArray> *entries; +@property (class, nonatomic, readonly, copy) NSMutableArray> *entries; @property (class, nonatomic) FBSDKMonitorStore *store; @end @@ -116,7 +116,7 @@ + (void)registerNotifications + (void)unregisterNotifications { - [[NSNotificationCenter defaultCenter] removeObserver: [self class]]; + [[NSNotificationCenter defaultCenter] removeObserver:[self class]]; } + (void)applicationDidBecomeActive diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorHeaders.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorHeaders.h index 41d7b764e5..3a5fe1c17a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorHeaders.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorHeaders.h @@ -22,10 +22,10 @@ #import "FBSDKMethodUsageMonitor.h" #import "FBSDKMethodUsageMonitorEntry.h" #import "FBSDKMonitor.h" -#import "FBSDKMonitoringConfiguration.h" #import "FBSDKMonitorEntry.h" #import "FBSDKMonitorNetworker.h" #import "FBSDKMonitorStore.h" +#import "FBSDKMonitoringConfiguration.h" #import "FBSDKPerformanceMonitor.h" #import "FBSDKPerformanceMonitorEntry.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorNetworker.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorNetworker.m index 4507cd18bb..85a1d48f8e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorNetworker.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorNetworker.m @@ -16,17 +16,17 @@ // 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 "FBSDKMonitorNetworker.h" + #import #import "FBSDKCoreKit+Internal.h" -#import "FBSDKMonitorNetworker.h" - -static NSString * const FBSDKAppIdentifierKey = @"id"; -static NSString * const FBSDKBundleIdentifierKey = @"unique_application_identifier"; -static NSString * const FBSDKDeviceModelKey = @"device_model"; -static NSString * const FBSDKMonitoringsKey = @"monitorings"; -static NSString * const FBSDKOsVersionKey = @"device_os_version"; +static NSString *const FBSDKAppIdentifierKey = @"id"; +static NSString *const FBSDKBundleIdentifierKey = @"unique_application_identifier"; +static NSString *const FBSDKDeviceModelKey = @"device_model"; +static NSString *const FBSDKMonitoringsKey = @"monitorings"; +static NSString *const FBSDKOsVersionKey = @"device_os_version"; @interface FBSDKMonitorNetworker () @end @@ -80,7 +80,7 @@ + (nullable NSString *)JSONStringForEntries:(NSArray> *)en invalidObjectHandler:NULL]; } -+ (NSString * _Nonnull)deviceModel ++ (NSString *_Nonnull)deviceModel { struct utsname systemInfo; uname(&systemInfo); diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorStore.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorStore.m index 31e263fea2..062482500b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorStore.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitorStore.m @@ -29,7 +29,6 @@ @implementation FBSDKMonitorStore - (instancetype)initWithFilename:(NSString *)filename { if ((self = [super init])) { - NSURL *temporaryDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; _filePath = [temporaryDirectory URLByAppendingPathComponent:filename]; _skipDiskCheck = YES; @@ -43,6 +42,7 @@ - (void)clear error:nil]; self.skipDiskCheck = YES; } + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (void)persist:(NSArray> *)entries @@ -55,7 +55,8 @@ - (void)persist:(NSArray> *)entries self.skipDiskCheck = NO; } -- (NSArray> *)retrieveEntries { +- (NSArray> *)retrieveEntries +{ NSMutableArray *items = [NSMutableArray array]; if (!self.skipDiskCheck) { @@ -63,9 +64,10 @@ - (void)persist:(NSArray> *)entries [self clear]; } - + return [items copy]; } + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.h index e7e5bd89ea..d888bc00e1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface FBSDKMonitoringConfiguration : NSObject +@interface FBSDKMonitoringConfiguration : NSObject @property (nonatomic, readonly) int defaultSamplingRate; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.m index 01905108e6..8538cb2a51 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKMonitoringConfiguration.m @@ -16,16 +16,17 @@ // 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 "FBSDKCoreKit+Internal.h" - #import "FBSDKMonitoringConfiguration.h" +#import "FBSDKCoreKit+Internal.h" + static NSString *defaultRateKey = @"default"; static NSString *sampleRatesKey = @"sample_rates"; static NSString *sampleRateNameKey = @"key"; static NSString *sampleRateValueKey = @"value"; -@implementation FBSDKMonitoringConfiguration { +@implementation FBSDKMonitoringConfiguration +{ NSDictionary *_sampleRates; } @@ -78,11 +79,13 @@ - (int)sampleRateForEntry:(nonnull id)entry return [[FBSDKTypeUtility dictionary:_sampleRates objectForKey:entry.name ofType:NSObject.class] intValue] ?: self.defaultSamplingRate; } -- (void)encodeWithCoder:(nonnull NSCoder *)encoder { +- (void)encodeWithCoder:(nonnull NSCoder *)encoder +{ [encoder encodeObject:_sampleRates forKey:sampleRatesKey]; } -- (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder { +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder +{ _sampleRates = [decoder decodeObjectOfClass:[SampleRates class] forKey:sampleRatesKey]; return self; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitor.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitor.m index 8f61be1470..d474f7cc29 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitor.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitor.m @@ -16,6 +16,7 @@ // 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 "FBSDKPerformanceMonitor.h" + #import "FBSDKMonitorHeaders.h" @implementation FBSDKPerformanceMonitor diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.h index cc3cddbcf4..8c6dbb7f15 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN `FBSDKPerformanceMonitor` to record metrics with their start times and durations. That will create and persist an entry. */ -@interface FBSDKPerformanceMonitorEntry : NSObject +@interface FBSDKPerformanceMonitorEntry : NSObject + (instancetype)new NS_UNAVAILABLE; + (instancetype _Nullable)entryWithName:(NSString *)name startTime:(NSDate *)startTime endTime:(NSDate *)endTime; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.m index 66947613ff..df40618d9e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Monitoring/FBSDKPerformanceMonitorEntry.m @@ -18,14 +18,15 @@ #import "FBSDKPerformanceMonitorEntry.h" -#import "FBSDKTypeUtility.h" +#import "FBSDKInternalUtility.h" -static NSString * const FBSDKPerformanceNameKey = @"event_name"; -static NSString * const FBSDKPerformanceStartTimeKey = @"time_start"; -static NSString * const FBSDKPerformanceEndTimeKey = @"time_end"; -static NSString * const FBSDKPerformanceTimeSpentKey = @"time_spent"; +static NSString *const FBSDKPerformanceNameKey = @"event_name"; +static NSString *const FBSDKPerformanceStartTimeKey = @"time_start"; +static NSString *const FBSDKPerformanceEndTimeKey = @"time_end"; +static NSString *const FBSDKPerformanceTimeSpentKey = @"time_spent"; -@implementation FBSDKPerformanceMonitorEntry { +@implementation FBSDKPerformanceMonitorEntry +{ NSString *_name; NSDate *_startTime; NSDate *_endTime; @@ -52,7 +53,8 @@ - (NSString *)name return [_name copy]; } -- (void)encodeWithCoder:(nonnull NSCoder *)encoder { +- (void)encodeWithCoder:(nonnull NSCoder *)encoder +{ if (_name && _startTime && _endTime) { [encoder encodeObject:_name forKey:FBSDKPerformanceNameKey]; [encoder encodeObject:_startTime forKey:FBSDKPerformanceStartTimeKey]; @@ -60,7 +62,8 @@ - (void)encodeWithCoder:(nonnull NSCoder *)encoder { } } -- (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder { +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder +{ _name = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPerformanceNameKey]; _startTime = [decoder decodeObjectOfClass:[NSDate class] forKey:FBSDKPerformanceStartTimeKey]; _endTime = [decoder decodeObjectOfClass:[NSDate class] forKey:FBSDKPerformanceEndTimeKey]; @@ -72,9 +75,10 @@ - (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder { return nil; } -- (nonnull NSDictionary *)dictionaryRepresentation { +- (nonnull NSDictionary *)dictionaryRepresentation +{ NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - + [FBSDKTypeUtility dictionary:dict setObject:_name forKey:FBSDKPerformanceNameKey]; [FBSDKTypeUtility dictionary:dict diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequest+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequest+Internal.h index 11aff98515..c64c10c7c9 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequest+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequest+Internal.h @@ -19,13 +19,12 @@ #import #if SWIFT_PACKAGE -#import "FBSDKGraphRequest.h" + #import "FBSDKGraphRequest.h" #else -#import + #import #endif -typedef NS_OPTIONS(NSUInteger, FBSDKGraphRequestFlags) -{ +typedef NS_OPTIONS(NSUInteger, FBSDKGraphRequestFlags) { FBSDKGraphRequestFlagNone = 0, // indicates this request should not use a client token as its token parameter FBSDKGraphRequestFlagSkipClientToken = 1 << 1, @@ -49,7 +48,7 @@ typedef NS_OPTIONS(NSUInteger, FBSDKGraphRequestFlags) // so that we don't cause a sudden change in token state or trigger recovery // out of context of any user action. @property (nonatomic, assign) FBSDKGraphRequestFlags flags; -@property (nonatomic, readonly, getter=isGraphErrorRecoveryDisabled) BOOL graphErrorRecoveryDisabled; +@property (nonatomic, readonly, getter = isGraphErrorRecoveryDisabled) BOOL graphErrorRecoveryDisabled; @property (nonatomic, readonly) BOOL hasAttachments; + (BOOL)isAttachment:(id)item; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h index 56d32239f8..a07c20181c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h @@ -19,14 +19,21 @@ @class FBSDKURLSession; #if SWIFT_PACKAGE -#import "FBSDKGraphRequestConnection.h" + #import "FBSDKGraphRequestConnection.h" #else -#import + #import #endif -@interface FBSDKGraphRequestConnection(Internal) +@interface FBSDKGraphRequestConnection (Internal) @property (nonatomic, readonly) NSMutableArray *requests; @property (nonatomic, strong) FBSDKURLSession *session; +/** + Get the graph request url for a single graph request + @param request The Graph Request we need the url for + @param forBatch whether the request is a batch request. + */ +- (NSString *)urlStringForSingleRequest:(FBSDKGraphRequest *)request forBatch:(BOOL)forBatch; + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.m index 2f09f8cd23..da018ae749 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.m @@ -24,8 +24,8 @@ @implementation FBSDKGraphRequestMetadata - (instancetype)initWithRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestBlock)handler - batchParameters:(NSDictionary *)batchParameters { - + batchParameters:(NSDictionary *)batchParameters +{ if ((self = [super init])) { _request = request; _batchParameters = [batchParameters copy]; @@ -36,7 +36,8 @@ - (instancetype)initWithRequest:(FBSDKGraphRequest *)request - (void)invokeCompletionHandlerForConnection:(FBSDKGraphRequestConnection *)connection withResults:(id)results - error:(NSError *)error { + error:(NSError *)error +{ if (self.completionHandler) { self.completionHandler(connection, results, error); } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m index e3d2899ad0..2525d8d82a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m @@ -20,8 +20,8 @@ #import "FBSDKCoreKit+Internal.h" -static int const FBSDKTokenRefreshThresholdSeconds = 24 * 60 * 60; // day -static int const FBSDKTokenRefreshRetrySeconds = 60 * 60; // hour +static int const FBSDKTokenRefreshThresholdSeconds = 24 * 60 * 60; // day +static int const FBSDKTokenRefreshRetrySeconds = 60 * 60; // hour @implementation FBSDKGraphRequestPiggybackManager @@ -30,8 +30,8 @@ + (void)addPiggybackRequests:(FBSDKGraphRequestConnection *)connection if ([FBSDKSettings appID].length > 0) { BOOL safeForPiggyback = YES; for (FBSDKGraphRequestMetadata *metadata in connection.requests) { - if (![metadata.request.version isEqualToString:[FBSDKSettings graphAPIVersion]] || - metadata.request.hasAttachments) { + if (![metadata.request.version isEqualToString:[FBSDKSettings graphAPIVersion]] + || metadata.request.hasAttachments) { safeForPiggyback = NO; break; } @@ -59,25 +59,25 @@ + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permission FBSDKAccessToken *currentToken = [FBSDKAccessToken currentAccessToken]; NSDate *expirationDate = currentToken.expirationDate; if (expirationDateNumber != nil) { - expirationDate = (expirationDateNumber.doubleValue > 0 ? - [NSDate dateWithTimeIntervalSince1970:expirationDateNumber.doubleValue] : - [NSDate distantFuture]); + expirationDate = (expirationDateNumber.doubleValue > 0 + ? [NSDate dateWithTimeIntervalSince1970:expirationDateNumber.doubleValue] + : [NSDate distantFuture]); } NSDate *dataExpirationDate = currentToken.dataAccessExpirationDate; if (dataAccessExpirationDateNumber != nil) { - dataExpirationDate = (dataAccessExpirationDateNumber.doubleValue > 0 ? - [NSDate dateWithTimeIntervalSince1970:dataAccessExpirationDateNumber.doubleValue] : - [NSDate distantFuture]); + dataExpirationDate = (dataAccessExpirationDateNumber.doubleValue > 0 + ? [NSDate dateWithTimeIntervalSince1970:dataAccessExpirationDateNumber.doubleValue] + : [NSDate distantFuture]); } FBSDKAccessToken *refreshedToken = [[FBSDKAccessToken alloc] initWithTokenString:tokenString ?: currentToken.tokenString permissions:(permissions ?: currentToken.permissions).allObjects declinedPermissions:(declinedPermissions ?: currentToken.declinedPermissions).allObjects - expiredPermissions:(expiredPermissions ?: currentToken.expiredPermissions).allObjects + expiredPermissions:(expiredPermissions ?: currentToken.expiredPermissions).allObjects appID:currentToken.appID userID:currentToken.userID expirationDate:expirationDate refreshDate:[NSDate date] - dataAccessExpirationDate:dataExpirationDate + dataAccessExpirationDate:dataExpirationDate graphDomain:graphDomain ?: currentToken.graphDomain]; if (expectedToken == currentToken) { [FBSDKAccessToken setCurrentAccessToken:refreshedToken]; @@ -85,11 +85,10 @@ + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permission } }; FBSDKGraphRequest *extendRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"oauth/access_token" - parameters:@{@"grant_type" : @"fb_extend_sso_token", - @"fields": @"", - @"client_id": expectedToken.appID - } - flags:FBSDKGraphRequestFlagDisableErrorRecovery]; + parameters:@{@"grant_type" : @"fb_extend_sso_token", + @"fields" : @"", + @"client_id" : expectedToken.appID} + flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:extendRequest completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { tokenString = result[@"access_token"]; @@ -99,8 +98,8 @@ + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permission expectingCallbackComplete(); }]; FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/permissions" - parameters:@{@"fields": @""} - flags:FBSDKGraphRequestFlagDisableErrorRecovery]; + parameters:@{@"fields" : @""} + flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:permissionsRequest completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { if (!error) { @@ -133,9 +132,9 @@ + (void)addRefreshPiggybackIfStale:(FBSDKGraphRequestConnection *)connection NSDate *now = [NSDate date]; NSDate *tokenRefreshDate = [FBSDKAccessToken currentAccessToken].refreshDate; - if (tokenRefreshDate && - [now timeIntervalSinceDate:lastRefreshTry] > FBSDKTokenRefreshRetrySeconds && - [now timeIntervalSinceDate:tokenRefreshDate] > FBSDKTokenRefreshThresholdSeconds) { + if (tokenRefreshDate + && [now timeIntervalSinceDate:lastRefreshTry] > FBSDKTokenRefreshRetrySeconds + && [now timeIntervalSinceDate:tokenRefreshDate] > FBSDKTokenRefreshThresholdSeconds) { [self addRefreshPiggyback:connection permissionHandler:NULL]; lastRefreshTry = [NSDate date]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.m index 7ed4443bf5..ebe63b5a3c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.m @@ -19,7 +19,6 @@ #import "FBSDKErrorConfiguration.h" #import "FBSDKCoreKit+Internal.h" - #import "FBSDKErrorRecoveryConfiguration.h" static NSString *const kErrorCategoryOther = @"other"; @@ -41,39 +40,53 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary } else { _configurationDictionary = [NSMutableDictionary dictionary]; NSString *localizedOK = - NSLocalizedStringWithDefaultValue(@"ErrorRecovery.OK", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"OK", - @"The title of the label to start attempting error recovery"); + NSLocalizedStringWithDefaultValue( + @"ErrorRecovery.OK", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"OK", + @"The title of the label to start attempting error recovery" + ); NSString *localizedCancel = - NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Cancel", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Cancel", - @"The title of the label to decline attempting error recovery"); + NSLocalizedStringWithDefaultValue( + @"ErrorRecovery.Cancel", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Cancel", + @"The title of the label to decline attempting error recovery" + ); NSString *localizedTransientSuggestion = - NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Transient.Suggestion", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"The server is temporarily busy, please try again.", - @"The fallback message to display to retry transient errors"); + NSLocalizedStringWithDefaultValue( + @"ErrorRecovery.Transient.Suggestion", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"The server is temporarily busy, please try again.", + @"The fallback message to display to retry transient errors" + ); NSString *localizedLoginRecoverableSuggestion = - NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Login.Suggestion", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Please log into this app again to reconnect your Facebook account.", - @"The fallback message to display to recover invalidated tokens"); + NSLocalizedStringWithDefaultValue( + @"ErrorRecovery.Login.Suggestion", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Please log into this app again to reconnect your Facebook account.", + @"The fallback message to display to recover invalidated tokens" + ); NSArray *fallbackArray = @[ - @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @102 }, - @{ @"code" : @190 } ], - @"recovery_message" : localizedLoginRecoverableSuggestion, - @"recovery_options" : @[ localizedOK, localizedCancel] - }, - @{ @"name" : @"transient", - @"items" : @[ @{ @"code" : @1 }, - @{ @"code" : @2 }, - @{ @"code" : @4 }, - @{ @"code" : @9 }, - @{ @"code" : @17 }, - @{ @"code" : @341 } ], - @"recovery_message" : localizedTransientSuggestion, - @"recovery_options" : @[ localizedOK] - }, - ]; + @{ @"name" : @"login", + @"items" : @[@{ @"code" : @102 }, + @{ @"code" : @190 }], + @"recovery_message" : localizedLoginRecoverableSuggestion, + @"recovery_options" : @[localizedOK, localizedCancel]}, + @{ @"name" : @"transient", + @"items" : @[@{ @"code" : @1 }, + @{ @"code" : @2 }, + @{ @"code" : @4 }, + @{ @"code" : @9 }, + @{ @"code" : @17 }, + @{ @"code" : @341 }], + @"recovery_message" : localizedTransientSuggestion, + @"recovery_options" : @[localizedOK]}, + ]; [self parseArray:fallbackArray]; } } @@ -84,26 +97,26 @@ - (FBSDKErrorRecoveryConfiguration *)recoveryConfigurationForCode:(NSString *)co { code = code ?: @"*"; subcode = subcode ?: @"*"; - FBSDKErrorRecoveryConfiguration *configuration = (_configurationDictionary[code][subcode] ?: - _configurationDictionary[code][@"*"] ?: - _configurationDictionary[@"*"][subcode] ?: - _configurationDictionary[@"*"][@"*"]); - if (configuration.errorCategory == FBSDKGraphRequestErrorRecoverable && - [FBSDKSettings clientToken] && - [request.parameters[@"access_token"] hasSuffix:[FBSDKSettings clientToken]]) { + FBSDKErrorRecoveryConfiguration *configuration = (_configurationDictionary[code][subcode] + ?: _configurationDictionary[code][@"*"] + ?: _configurationDictionary[@"*"][subcode] + ?: _configurationDictionary[@"*"][@"*"]); + if (configuration.errorCategory == FBSDKGraphRequestErrorRecoverable + && [FBSDKSettings clientToken] + && [request.parameters[@"access_token"] hasSuffix:[FBSDKSettings clientToken]]) { // do not attempt to recovery client tokens. return nil; } return configuration; } -- (void)parseArray:(NSArray *)array +- (void)parseArray:(NSArray *)array { for (NSDictionary *dictionary in [FBSDKTypeUtility arrayValue:array]) { [FBSDKTypeUtility dictionary:dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { FBSDKGraphRequestError category; NSString *action = [FBSDKTypeUtility stringValue:dictionary[@"name"]]; - if ( [action isEqualToString:kErrorCategoryOther]) { + if ([action isEqualToString:kErrorCategoryOther]) { category = FBSDKGraphRequestErrorOther; } else if ([action isEqualToString:kErrorCategoryTransient]) { category = FBSDKGraphRequestErrorTransient; @@ -140,17 +153,17 @@ - (void)parseArray:(NSArray *)array continue; } [FBSDKTypeUtility dictionary:currentSubcodes setObject:[[FBSDKErrorRecoveryConfiguration alloc] - initWithRecoveryDescription:suggestion - optionDescriptions:options - category:category - recoveryActionName:action] forKey:validSubcodeNumber.stringValue]; + initWithRecoveryDescription:suggestion + optionDescriptions:options + category:category + recoveryActionName:action] forKey:validSubcodeNumber.stringValue]; } } else { [FBSDKTypeUtility dictionary:currentSubcodes setObject:[[FBSDKErrorRecoveryConfiguration alloc] - initWithRecoveryDescription:suggestion - optionDescriptions:options - category:category - recoveryActionName:action] forKey:@"*"]; + initWithRecoveryDescription:suggestion + optionDescriptions:options + category:category + recoveryActionName:action] forKey:@"*"]; } } }]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.m index 97eb061033..a8540426e4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.m @@ -28,7 +28,8 @@ @implementation FBSDKErrorRecoveryConfiguration - (instancetype)initWithRecoveryDescription:(NSString *)description optionDescriptions:(NSArray *)optionDescriptions category:(FBSDKGraphRequestError)category - recoveryActionName:(NSString *)recoveryActionName { + recoveryActionName:(NSString *)recoveryActionName +{ if ((self = [super init])) { _localizedRecoveryDescription = [description copy]; _localizedRecoveryOptionDescriptions = [optionDescriptions copy]; @@ -70,7 +71,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder - (id)copyWithZone:(NSZone *)zone { - //immutable + // immutable return self; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.m index 6ab38a7dae..e699bf2063 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.m @@ -16,19 +16,17 @@ // 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 "FBSDKGateKeeperManager.h" -#import - #import +#import + #import "FBSDKAppEventsUtility.h" -#import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequest.h" +#import "FBSDKGraphRequest+Internal.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" #define FBSDK_GATEKEEPERS_USER_DEFAULTS_KEY @"com.facebook.sdk:GateKeepers%@" @@ -63,64 +61,67 @@ + (BOOL)boolForKey:(NSString *)key defaultValue:(BOOL)defaultValue #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (void)loadGateKeepers:(FBSDKGKManagerBlock)completionBlock { - @synchronized(self) { - NSString *appID = [FBSDKSettings appID]; - if (!appID) { - _gateKeepers = nil; - if (completionBlock != NULL) { - completionBlock(nil); + @try { + @synchronized(self) { + NSString *appID = [FBSDKSettings appID]; + if (!appID) { + _gateKeepers = nil; + if (completionBlock != NULL) { + completionBlock(nil); + } + return; } - return; - } - if (!_gateKeepers) { - // load the defaults - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSString *defaultKey = [NSString stringWithFormat:FBSDK_GATEKEEPERS_USER_DEFAULTS_KEY, - appID]; - NSData *data = [defaults objectForKey:defaultKey]; - if ([data isKindOfClass:[NSData class]]) { - NSDictionary *gatekeeper = [NSKeyedUnarchiver unarchiveObjectWithData:data]; - if (gatekeeper != nil && [gatekeeper isKindOfClass:[NSDictionary class]]) { - _gateKeepers = gatekeeper; + if (!_gateKeepers) { + // load the defaults + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *defaultKey = [NSString stringWithFormat:FBSDK_GATEKEEPERS_USER_DEFAULTS_KEY, + appID]; + NSData *data = [defaults objectForKey:defaultKey]; + if ([data isKindOfClass:[NSData class]]) { + NSDictionary *gatekeeper = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + if (gatekeeper != nil && [gatekeeper isKindOfClass:[NSDictionary class]]) { + _gateKeepers = gatekeeper; + } } } - } - // Query the server when the requery is not finished for app start or the timestamp is not valid - if ([self _gateKeeperIsValid]) { - if (completionBlock) { - completionBlock(nil); - } - } else { - [FBSDKTypeUtility array:_completionBlocks addObject:completionBlock]; - if (!_loadingGateKeepers) { - _loadingGateKeepers = YES; - FBSDKGraphRequest *request = [[self class] requestToLoadGateKeepers]; - - // start request with specified timeout instead of the default 180s - FBSDKGraphRequestConnection *requestConnection = [[FBSDKGraphRequestConnection alloc] init]; - requestConnection.timeout = kTimeout; - [requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - _requeryFinishedForAppStart = YES; - [self processLoadRequestResponse:result error:error]; - }]; - [requestConnection start]; + // Query the server when the requery is not finished for app start or the timestamp is not valid + if ([self _gateKeeperIsValid]) { + if (completionBlock) { + completionBlock(nil); + } + } else { + [FBSDKTypeUtility array:_completionBlocks addObject:completionBlock]; + if (!_loadingGateKeepers) { + _loadingGateKeepers = YES; + FBSDKGraphRequest *request = [[self class] requestToLoadGateKeepers]; + + // start request with specified timeout instead of the default 180s + FBSDKGraphRequestConnection *requestConnection = [FBSDKGraphRequestConnection new]; + requestConnection.timeout = kTimeout; + [requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + _requeryFinishedForAppStart = YES; + [self processLoadRequestResponse:result error:error]; + }]; + [requestConnection start]; + } } } - } + } @catch (NSException *exception) {} } + #pragma clang diagnostic pop #pragma mark - Internal Class Methods + (FBSDKGraphRequest *)requestToLoadGateKeepers { - NSString *sdkVersion = [FBSDKSettings sdkVersion]; - - NSDictionary *parameters = @{ @"platform": @"ios" , - @"sdk_version": sdkVersion, - @"fields": FBSDK_GATEKEEPER_APP_GATEKEEPER_FIELDS}; + NSMutableDictionary *parameters = [NSMutableDictionary new]; + [FBSDKTypeUtility dictionary:parameters setObject:@"ios" forKey:@"platform"]; + [FBSDKTypeUtility dictionary:parameters setObject:[FBSDKSettings sdkVersion] forKey:@"sdk_version"]; + [FBSDKTypeUtility dictionary:parameters setObject:FBSDK_GATEKEEPER_APP_GATEKEEPER_FIELDS forKey:@"fields"]; + [FBSDKTypeUtility dictionary:parameters setObject:[UIDevice currentDevice].systemVersion forKey:@"os_version"]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/%@", [FBSDKSettings appID], FBSDK_GATEKEEPER_APP_GATEKEEPER_EDGE] @@ -176,6 +177,7 @@ + (void)processLoadRequestResponse:(id)result error:(NSError *)error [self _didProcessGKFromNetwork:error]; } } + #pragma clang diagnostic pop + (void)_didProcessGKFromNetwork:(NSError *)error diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration+Internal.h index 6163c76f13..b5c14cb2b3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration+Internal.h @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import + #import "FBSDKServerConfiguration.h" FOUNDATION_EXPORT NSString *const FBSDKDialogConfigurationNameDefault; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m index 6e0cd79596..273fcf4751 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m @@ -18,8 +18,9 @@ #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfiguration+Internal.h" -#import "FBSDKMonitoringConfiguration.h" + #import "FBSDKInternalUtility.h" +#import "FBSDKMonitoringConfiguration.h" // one minute #define DEFAULT_SESSION_TIMEOUT_INTERVAL 60 @@ -82,32 +83,32 @@ @implementation FBSDKServerConfiguration #pragma mark - Object Lifecycle -- (instancetype)initWithAppID:(NSString *)appID - appName:(NSString *)appName - loginTooltipEnabled:(BOOL)loginTooltipEnabled - loginTooltipText:(NSString *)loginTooltipText - defaultShareMode:(NSString*)defaultShareMode - advertisingIDEnabled:(BOOL)advertisingIDEnabled - implicitLoggingEnabled:(BOOL)implicitLoggingEnabled -implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled - codelessEventsEnabled:(BOOL)codelessEventsEnabled - uninstallTrackingEnabled:(BOOL)uninstallTrackingEnabled - dialogConfigurations:(NSDictionary *)dialogConfigurations - dialogFlows:(NSDictionary *)dialogFlows - timestamp:(NSDate *)timestamp - errorConfiguration:(FBSDKErrorConfiguration *)errorConfiguration - sessionTimeoutInterval:(NSTimeInterval) sessionTimeoutInterval - defaults:(BOOL)defaults - loggingToken:(NSString *)loggingToken - smartLoginOptions:(FBSDKServerConfigurationSmartLoginOptions)smartLoginOptions - smartLoginBookmarkIconURL:(NSURL *)smartLoginBookmarkIconURL - smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL - updateMessage:(NSString *)updateMessage - eventBindings:(NSArray *)eventBindings - restrictiveParams:(NSDictionary *)restrictiveParams - AAMRules:(NSDictionary *)AAMRules - suggestedEventsSetting:(NSDictionary *)suggestedEventsSetting - monitoringConfiguration:(FBSDKMonitoringConfiguration *)monitoringConfiguration +- (instancetype) initWithAppID:(NSString *)appID + appName:(NSString *)appName + loginTooltipEnabled:(BOOL)loginTooltipEnabled + loginTooltipText:(NSString *)loginTooltipText + defaultShareMode:(NSString *)defaultShareMode + advertisingIDEnabled:(BOOL)advertisingIDEnabled + implicitLoggingEnabled:(BOOL)implicitLoggingEnabled + implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled + codelessEventsEnabled:(BOOL)codelessEventsEnabled + uninstallTrackingEnabled:(BOOL)uninstallTrackingEnabled + dialogConfigurations:(NSDictionary *)dialogConfigurations + dialogFlows:(NSDictionary *)dialogFlows + timestamp:(NSDate *)timestamp + errorConfiguration:(FBSDKErrorConfiguration *)errorConfiguration + sessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval + defaults:(BOOL)defaults + loggingToken:(NSString *)loggingToken + smartLoginOptions:(FBSDKServerConfigurationSmartLoginOptions)smartLoginOptions + smartLoginBookmarkIconURL:(NSURL *)smartLoginBookmarkIconURL + smartLoginMenuIconURL:(NSURL *)smartLoginMenuIconURL + updateMessage:(NSString *)updateMessage + eventBindings:(NSArray *)eventBindings + restrictiveParams:(NSDictionary *)restrictiveParams + AAMRules:(NSDictionary *)AAMRules + suggestedEventsSetting:(NSDictionary *)suggestedEventsSetting + monitoringConfiguration:(FBSDKMonitoringConfiguration *)monitoringConfiguration { if ((self = [super init])) { _appID = [appID copy]; @@ -150,18 +151,18 @@ + (FBSDKServerConfiguration *)defaultServerConfigurationForAppID:(NSString *)app if (![_defaultServerConfiguration.appID isEqualToString:appID]) { // Bypass the native dialog flow for iOS 9+, as it produces a series of additional confirmation dialogs that lead to // extra friction that is not desirable. - NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; + NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; BOOL useNativeFlow = ![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]; // Also enable SFSafariViewController by default. NSDictionary *dialogFlows = @{ - FBSDKDialogConfigurationNameDefault: @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @(useNativeFlow), - FBSDKDialogConfigurationFeatureUseSafariViewController: @YES, - }, - FBSDKDialogConfigurationNameMessage: @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @YES, - }, - }; + FBSDKDialogConfigurationNameDefault : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @(useNativeFlow), + FBSDKDialogConfigurationFeatureUseSafariViewController : @YES, + }, + FBSDKDialogConfigurationNameMessage : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, + }, + }; _defaultServerConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID appName:nil loginTooltipEnabled:NO @@ -188,7 +189,7 @@ + (FBSDKServerConfiguration *)defaultServerConfigurationForAppID:(NSString *)app AAMRules:nil suggestedEventsSetting:nil monitoringConfiguration:FBSDKMonitoringConfiguration.defaultConfiguration - ]; + ]; } return _defaultServerConfiguration; } @@ -215,12 +216,12 @@ - (BOOL)useSafariViewControllerForDialogName:(NSString *)dialogName - (BOOL)_useFeatureWithKey:(NSString *)key dialogName:(NSString *)dialogName { if ([dialogName isEqualToString:FBSDKDialogConfigurationNameLogin]) { - return ((NSNumber *)(_dialogFlows[dialogName][key] ?: - _dialogFlows[FBSDKDialogConfigurationNameDefault][key])).boolValue; + return ((NSNumber *)(_dialogFlows[dialogName][key] + ?: _dialogFlows[FBSDKDialogConfigurationNameDefault][key])).boolValue; } else { - return ((NSNumber *)(_dialogFlows[dialogName][key] ?: - _dialogFlows[FBSDKDialogConfigurationNameSharing][key] ?: - _dialogFlows[FBSDKDialogConfigurationNameDefault][key])).boolValue; + return ((NSNumber *)(_dialogFlows[dialogName][key] + ?: _dialogFlows[FBSDKDialogConfigurationNameSharing][key] + ?: _dialogFlows[FBSDKDialogConfigurationNameDefault][key])).boolValue; } } @@ -231,7 +232,7 @@ + (BOOL)supportsSecureCoding return YES; } -- (id)initWithCoder:(NSCoder *)decoder +- (instancetype)initWithCoder:(NSCoder *)decoder { NSString *appID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_APP_ID_KEY]; NSString *appName = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_APP_NAME_KEY]; @@ -276,32 +277,32 @@ - (id)initWithCoder:(NSCoder *)decoder NSInteger version = [decoder decodeIntegerForKey:FBSDK_SERVER_CONFIGURATION_VERSION_KEY]; FBSDKMonitoringConfiguration *monitoringConfiguration = [decoder decodeObjectOfClass:FBSDKMonitoringConfiguration.class forKey:FBSDK_SERVER_CONFIGURATION_MONITORING_CONFIGURATION_KEY]; FBSDKServerConfiguration *configuration = [self initWithAppID:appID - appName:appName - loginTooltipEnabled:loginTooltipEnabled - loginTooltipText:loginTooltipText - defaultShareMode:defaultShareMode - advertisingIDEnabled:advertisingIDEnabled - implicitLoggingEnabled:implicitLoggingEnabled - implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabled - codelessEventsEnabled:codelessEventsEnabled - uninstallTrackingEnabled:uninstallTrackingEnabled - dialogConfigurations:dialogConfigurations - dialogFlows:dialogFlows - timestamp:timestamp - errorConfiguration:errorConfiguration - sessionTimeoutInterval:sessionTimeoutInterval - defaults:NO - loggingToken:loggingToken - smartLoginOptions:smartLoginOptions - smartLoginBookmarkIconURL:smartLoginBookmarkIconURL - smartLoginMenuIconURL:smartLoginMenuIconURL - updateMessage:updateMessage - eventBindings:eventBindings - restrictiveParams:restrictiveParams - AAMRules:AAMRules - suggestedEventsSetting:suggestedEventsSetting - monitoringConfiguration:monitoringConfiguration - ]; + appName:appName + loginTooltipEnabled:loginTooltipEnabled + loginTooltipText:loginTooltipText + defaultShareMode:defaultShareMode + advertisingIDEnabled:advertisingIDEnabled + implicitLoggingEnabled:implicitLoggingEnabled + implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabled + codelessEventsEnabled:codelessEventsEnabled + uninstallTrackingEnabled:uninstallTrackingEnabled + dialogConfigurations:dialogConfigurations + dialogFlows:dialogFlows + timestamp:timestamp + errorConfiguration:errorConfiguration + sessionTimeoutInterval:sessionTimeoutInterval + defaults:NO + loggingToken:loggingToken + smartLoginOptions:smartLoginOptions + smartLoginBookmarkIconURL:smartLoginBookmarkIconURL + smartLoginMenuIconURL:smartLoginMenuIconURL + updateMessage:updateMessage + eventBindings:eventBindings + restrictiveParams:restrictiveParams + AAMRules:AAMRules + suggestedEventsSetting:suggestedEventsSetting + monitoringConfiguration:monitoringConfiguration + ]; configuration->_version = version; return configuration; } @@ -341,7 +342,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder #pragma mark - NSCopying -- (id)copyWithZone:(NSZone *)zone +- (instancetype)copyWithZone:(NSZone *)zone { return self; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m index 2cd89c1224..a137480151 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m @@ -22,15 +22,14 @@ #import "FBSDKAppEventsUtility.h" #import "FBSDKGateKeeperManager.h" -#import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequest.h" +#import "FBSDKGraphRequest+Internal.h" #import "FBSDKImageDownloader.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" -#import "FBSDKServerConfiguration+Internal.h" #import "FBSDKServerConfiguration.h" +#import "FBSDKServerConfiguration+Internal.h" #import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" #define FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY @"com.facebook.sdk:serverConfiguration%@" @@ -68,11 +67,11 @@ @implementation FBSDKServerConfigurationManager typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures) { - FBSDKServerConfigurationManagerAppEventsFeaturesNone = 0, - FBSDKServerConfigurationManagerAppEventsFeaturesAdvertisingIDEnabled = 1 << 0, - FBSDKServerConfigurationManagerAppEventsFeaturesImplicitPurchaseLoggingEnabled = 1 << 1, - FBSDKServerConfigurationManagerAppEventsFeaturesCodelessEventsTriggerEnabled = 1 << 5, - FBSDKServerConfigurationManagerAppEventsFeaturesUninstallTrackingEnabled = 1 << 7, + FBSDKServerConfigurationManagerAppEventsFeaturesNone = 0, + FBSDKServerConfigurationManagerAppEventsFeaturesAdvertisingIDEnabled = 1 << 0, + FBSDKServerConfigurationManagerAppEventsFeaturesImplicitPurchaseLoggingEnabled = 1 << 1, + FBSDKServerConfigurationManagerAppEventsFeaturesCodelessEventsTriggerEnabled = 1 << 5, + FBSDKServerConfigurationManagerAppEventsFeaturesUninstallTrackingEnabled = 1 << 7, }; #pragma mark - Public Class Methods @@ -111,159 +110,166 @@ + (FBSDKServerConfiguration *)cachedServerConfiguration #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (void)loadServerConfigurationWithCompletionBlock:(FBSDKServerConfigurationBlock)completionBlock { - void (^loadBlock)(void) = nil; - NSString *appID = [FBSDKSettings appID]; - @synchronized(self) { - // validate the cached configuration has the correct appID - if (_serverConfiguration && ![_serverConfiguration.appID isEqualToString:appID]) { - _serverConfiguration = nil; - _serverConfigurationError = nil; - _serverConfigurationErrorTimestamp = nil; - } + @try { + void (^loadBlock)(void) = nil; + NSString *appID = [FBSDKSettings appID]; + @synchronized(self) { + // validate the cached configuration has the correct appID + if (_serverConfiguration && ![_serverConfiguration.appID isEqualToString:appID]) { + _serverConfiguration = nil; + _serverConfigurationError = nil; + _serverConfigurationErrorTimestamp = nil; + } - // load the configuration from NSUserDefaults - if (!_serverConfiguration) { - // load the defaults - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, appID]; - NSData *data = [defaults objectForKey:defaultsKey]; - if ([data isKindOfClass:[NSData class]]) { - // decode the configuration - FBSDKServerConfiguration *serverConfiguration = [NSKeyedUnarchiver unarchiveObjectWithData:data]; - if ([serverConfiguration isKindOfClass:[FBSDKServerConfiguration class]]) { - // ensure that the configuration points to the current appID - if ([serverConfiguration.appID isEqualToString:appID]) { - _serverConfiguration = serverConfiguration; + // load the configuration from NSUserDefaults + if (!_serverConfiguration) { + // load the defaults + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, appID]; + NSData *data = [defaults objectForKey:defaultsKey]; + if ([data isKindOfClass:[NSData class]]) { + // decode the configuration + FBSDKServerConfiguration *serverConfiguration = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + if ([serverConfiguration isKindOfClass:[FBSDKServerConfiguration class]]) { + // ensure that the configuration points to the current appID + if ([serverConfiguration.appID isEqualToString:appID]) { + _serverConfiguration = serverConfiguration; + } } } } - } - if (_requeryFinishedForAppStart && - ((_serverConfiguration && [self _serverConfigurationTimestampIsValid:_serverConfiguration.timestamp] && _serverConfiguration.version >= FBSDKServerConfigurationVersion))) { - // we have a valid server configuration, use that - loadBlock = [self _wrapperBlockForLoadBlock:completionBlock]; - } else { - // hold onto the completion block - [FBSDKTypeUtility array:_completionBlocks addObject:[completionBlock copy]]; - - // check if we are already loading - if (!_loadingServerConfiguration) { - // load the configuration from the network - _loadingServerConfiguration = YES; - FBSDKGraphRequest *request = [[self class] requestToLoadServerConfiguration:appID]; - - // start request with specified timeout instead of the default 180s - FBSDKGraphRequestConnection *requestConnection = [[FBSDKGraphRequestConnection alloc] init]; - requestConnection.timeout = kTimeout; - [requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - _requeryFinishedForAppStart = YES; - [self processLoadRequestResponse:result error:error appID:appID]; - }]; - [requestConnection start]; + if (_requeryFinishedForAppStart + && ((_serverConfiguration && [self _serverConfigurationTimestampIsValid:_serverConfiguration.timestamp] && _serverConfiguration.version >= FBSDKServerConfigurationVersion))) { + // we have a valid server configuration, use that + loadBlock = [self _wrapperBlockForLoadBlock:completionBlock]; + } else { + // hold onto the completion block + [FBSDKTypeUtility array:_completionBlocks addObject:[completionBlock copy]]; + + // check if we are already loading + if (!_loadingServerConfiguration) { + // load the configuration from the network + _loadingServerConfiguration = YES; + FBSDKGraphRequest *request = [[self class] requestToLoadServerConfiguration:appID]; + + // start request with specified timeout instead of the default 180s + FBSDKGraphRequestConnection *requestConnection = [FBSDKGraphRequestConnection new]; + requestConnection.timeout = kTimeout; + [requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + _requeryFinishedForAppStart = YES; + [self processLoadRequestResponse:result error:error appID:appID]; + }]; + [requestConnection start]; + } } } - } - if (loadBlock) { - loadBlock(); - } + if (loadBlock) { + loadBlock(); + } - // Fetch app gatekeepers - [FBSDKGateKeeperManager loadGateKeepers:nil]; + // Fetch app gatekeepers + [FBSDKGateKeeperManager loadGateKeepers:nil]; + } @catch (NSException *exception) {} } + #pragma clang diagnostic pop #pragma mark - Internal Class Methods + (void)processLoadRequestResponse:(id)result error:(NSError *)error appID:(NSString *)appID { - if (error) { - [self _didProcessConfigurationFromNetwork:nil appID:appID error:error]; - return; - } + @try { + if (error) { + [self _didProcessConfigurationFromNetwork:nil appID:appID error:error]; + return; + } - NSDictionary *resultDictionary = [FBSDKTypeUtility dictionaryValue:result]; - NSUInteger appEventsFeatures = [FBSDKTypeUtility unsignedIntegerValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_APP_EVENTS_FEATURES_FIELD]]; - BOOL advertisingIDEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesAdvertisingIDEnabled) != 0; - BOOL implicitPurchaseLoggingEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesImplicitPurchaseLoggingEnabled) != 0; - BOOL codelessEventsEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesCodelessEventsTriggerEnabled) != 0; - BOOL uninstallTrackingEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesUninstallTrackingEnabled) != 0; - NSString *appName = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_APP_NAME_FIELD]]; - BOOL loginTooltipEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_FIELD]]; - NSString *loginTooltipText = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD]]; - NSString *defaultShareMode = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_FIELD]]; - BOOL implicitLoggingEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_FIELD]]; - NSDictionary *dialogConfigurations = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_FIELD]]; - dialogConfigurations = [self _parseDialogConfigurations:dialogConfigurations]; - NSDictionary *dialogFlows = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD]]; - FBSDKErrorConfiguration *errorConfiguration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; - [errorConfiguration parseArray:resultDictionary[FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGURATION_FIELD]]; - NSTimeInterval sessionTimeoutInterval = [FBSDKTypeUtility timeIntervalValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD]]; - NSString *loggingToken = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD]]; - FBSDKServerConfigurationSmartLoginOptions smartLoginOptions = [FBSDKTypeUtility integerValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_OPTIONS_FIELD]]; - NSURL *smartLoginBookmarkIconURL = [FBSDKTypeUtility URLValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_BOOKMARK_ICON_URL_FIELD]]; - NSURL *smartLoginMenuIconURL = [FBSDKTypeUtility URLValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD]]; - NSString *updateMessage = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD]]; - NSArray *eventBindings = [FBSDKTypeUtility arrayValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD]]; - NSDictionary *restrictiveParams = [FBSDKBasicUtility objectForJSONString:resultDictionary[FBSDK_SERVER_CONFIGURATION_RESTRICTIVE_PARAMS_FIELD] error:nil]; - NSDictionary *AAMRules = [FBSDKBasicUtility objectForJSONString:resultDictionary[FBSDK_SERVER_CONFIGURATION_AAM_RULES_FIELD] error:nil]; - NSDictionary *suggestedEventsSetting = [FBSDKBasicUtility objectForJSONString:resultDictionary[FBSDK_SERVER_CONFIGURATION_SUGGESTED_EVENTS_SETTING_FIELD] error:nil]; - FBSDKMonitoringConfiguration *monitoringConfiguration = [FBSDKMonitoringConfiguration fromDictionary:resultDictionary[FBSDK_SERVER_CONFIGURATION_MONITORING_CONFIG_FIELD]]; - FBSDKServerConfiguration *serverConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID - appName:appName - loginTooltipEnabled:loginTooltipEnabled - loginTooltipText:loginTooltipText - defaultShareMode:defaultShareMode - advertisingIDEnabled:advertisingIDEnabled - implicitLoggingEnabled:implicitLoggingEnabled - implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabled - codelessEventsEnabled:codelessEventsEnabled - uninstallTrackingEnabled:uninstallTrackingEnabled - dialogConfigurations:dialogConfigurations - dialogFlows:dialogFlows - timestamp:[NSDate date] - errorConfiguration:errorConfiguration - sessionTimeoutInterval:sessionTimeoutInterval - defaults:NO - loggingToken:loggingToken - smartLoginOptions:smartLoginOptions - smartLoginBookmarkIconURL:smartLoginBookmarkIconURL - smartLoginMenuIconURL:smartLoginMenuIconURL - updateMessage:updateMessage - eventBindings:eventBindings - restrictiveParams:restrictiveParams - AAMRules:AAMRules - suggestedEventsSetting:suggestedEventsSetting - monitoringConfiguration:monitoringConfiguration]; -#if TARGET_OS_TV - // don't download icons more than once a day. - static const NSTimeInterval kSmartLoginIconsTTL = 60 * 60 * 24; - - BOOL smartLoginEnabled = (smartLoginOptions & FBSDKServerConfigurationSmartLoginOptionsEnabled); - // for TVs go ahead and prime the images - if (smartLoginEnabled && - smartLoginMenuIconURL && - smartLoginBookmarkIconURL) { + NSDictionary *resultDictionary = [FBSDKTypeUtility dictionaryValue:result]; + NSUInteger appEventsFeatures = [FBSDKTypeUtility unsignedIntegerValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_APP_EVENTS_FEATURES_FIELD]]; + BOOL advertisingIDEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesAdvertisingIDEnabled) != 0; + BOOL implicitPurchaseLoggingEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesImplicitPurchaseLoggingEnabled) != 0; + BOOL codelessEventsEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesCodelessEventsTriggerEnabled) != 0; + BOOL uninstallTrackingEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesUninstallTrackingEnabled) != 0; + NSString *appName = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_APP_NAME_FIELD]]; + BOOL loginTooltipEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_FIELD]]; + NSString *loginTooltipText = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD]]; + NSString *defaultShareMode = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_FIELD]]; + BOOL implicitLoggingEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_FIELD]]; + NSDictionary *dialogConfigurations = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_FIELD]]; + dialogConfigurations = [self _parseDialogConfigurations:dialogConfigurations]; + NSDictionary *dialogFlows = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD]]; + FBSDKErrorConfiguration *errorConfiguration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; + [errorConfiguration parseArray:resultDictionary[FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGURATION_FIELD]]; + NSTimeInterval sessionTimeoutInterval = [FBSDKTypeUtility timeIntervalValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD]]; + NSString *loggingToken = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD]]; + FBSDKServerConfigurationSmartLoginOptions smartLoginOptions = [FBSDKTypeUtility integerValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_OPTIONS_FIELD]]; + NSURL *smartLoginBookmarkIconURL = [FBSDKTypeUtility URLValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_BOOKMARK_ICON_URL_FIELD]]; + NSURL *smartLoginMenuIconURL = [FBSDKTypeUtility URLValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD]]; + NSString *updateMessage = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD]]; + NSArray *eventBindings = [FBSDKTypeUtility arrayValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD]]; + NSDictionary *restrictiveParams = [FBSDKBasicUtility objectForJSONString:resultDictionary[FBSDK_SERVER_CONFIGURATION_RESTRICTIVE_PARAMS_FIELD] error:nil]; + NSDictionary *AAMRules = [FBSDKBasicUtility objectForJSONString:resultDictionary[FBSDK_SERVER_CONFIGURATION_AAM_RULES_FIELD] error:nil]; + NSDictionary *suggestedEventsSetting = [FBSDKBasicUtility objectForJSONString:resultDictionary[FBSDK_SERVER_CONFIGURATION_SUGGESTED_EVENTS_SETTING_FIELD] error:nil]; + FBSDKMonitoringConfiguration *monitoringConfiguration = [FBSDKMonitoringConfiguration fromDictionary:resultDictionary[FBSDK_SERVER_CONFIGURATION_MONITORING_CONFIG_FIELD]]; + FBSDKServerConfiguration *serverConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID + appName:appName + loginTooltipEnabled:loginTooltipEnabled + loginTooltipText:loginTooltipText + defaultShareMode:defaultShareMode + advertisingIDEnabled:advertisingIDEnabled + implicitLoggingEnabled:implicitLoggingEnabled + implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabled + codelessEventsEnabled:codelessEventsEnabled + uninstallTrackingEnabled:uninstallTrackingEnabled + dialogConfigurations:dialogConfigurations + dialogFlows:dialogFlows + timestamp:[NSDate date] + errorConfiguration:errorConfiguration + sessionTimeoutInterval:sessionTimeoutInterval + defaults:NO + loggingToken:loggingToken + smartLoginOptions:smartLoginOptions + smartLoginBookmarkIconURL:smartLoginBookmarkIconURL + smartLoginMenuIconURL:smartLoginMenuIconURL + updateMessage:updateMessage + eventBindings:eventBindings + restrictiveParams:restrictiveParams + AAMRules:AAMRules + suggestedEventsSetting:suggestedEventsSetting + monitoringConfiguration:monitoringConfiguration]; + #if TARGET_OS_TV + // don't download icons more than once a day. + static const NSTimeInterval kSmartLoginIconsTTL = 60 * 60 * 24; + + BOOL smartLoginEnabled = (smartLoginOptions & FBSDKServerConfigurationSmartLoginOptionsEnabled); + // for TVs go ahead and prime the images + if (smartLoginEnabled + && smartLoginMenuIconURL + && smartLoginBookmarkIconURL) { [[FBSDKImageDownloader sharedInstance] downloadImageWithURL:serverConfiguration.smartLoginBookmarkIconURL ttl:kSmartLoginIconsTTL completion:nil]; [[FBSDKImageDownloader sharedInstance] downloadImageWithURL:serverConfiguration.smartLoginMenuIconURL ttl:kSmartLoginIconsTTL completion:nil]; - } -#endif - [self _didProcessConfigurationFromNetwork:serverConfiguration appID:appID error:nil]; + } + #endif + [self _didProcessConfigurationFromNetwork:serverConfiguration appID:appID error:nil]; + } @catch (NSException *exception) {} } + (FBSDKGraphRequest *)requestToLoadServerConfiguration:(NSString *)appID { NSOperatingSystemVersion operatingSystemVersion = [FBSDKInternalUtility operatingSystemVersion]; - NSString *dialogFlowsField = [NSString stringWithFormat:@"%@.os_version(%ti.%ti.%ti)", + NSString *osVersion = [NSString stringWithFormat:@"%ti.%ti.%ti", + operatingSystemVersion.majorVersion, + operatingSystemVersion.minorVersion, + operatingSystemVersion.patchVersion]; + NSString *dialogFlowsField = [NSString stringWithFormat:@"%@.os_version(%@)", FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD, - operatingSystemVersion.majorVersion, - operatingSystemVersion.minorVersion, - operatingSystemVersion.patchVersion]; + osVersion]; NSArray *fields = @[FBSDK_SERVER_CONFIGURATION_APP_EVENTS_FEATURES_FIELD, FBSDK_SERVER_CONFIGURATION_APP_NAME_FIELD, FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_FIELD, @@ -278,19 +284,20 @@ + (FBSDKGraphRequest *)requestToLoadServerConfiguration:(NSString *)appID FBSDK_SERVER_CONFIGURATION_RESTRICTIVE_PARAMS_FIELD, FBSDK_SERVER_CONFIGURATION_AAM_RULES_FIELD, FBSDK_SERVER_CONFIGURATION_SUGGESTED_EVENTS_SETTING_FIELD -#if !TARGET_OS_TV - ,FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD -#endif -#ifdef DEBUG - ,FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD -#endif -#if TARGET_OS_TV - ,FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_OPTIONS_FIELD, + #if !TARGET_OS_TV + , FBSDK_SERVER_CONFIGURATION_EVENT_BINDINGS_FIELD + #endif + #ifdef DEBUG + , FBSDK_SERVER_CONFIGURATION_UPDATE_MESSAGE_FIELD + #endif + #if TARGET_OS_TV + , FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_OPTIONS_FIELD, FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_BOOKMARK_ICON_URL_FIELD, FBSDK_SERVER_CONFIGURATION_SMART_LOGIN_MENU_ICON_URL_FIELD -#endif - ]; - NSDictionary *parameters = @{ @"fields": [fields componentsJoinedByString:@","]}; + #endif + ]; + NSDictionary *parameters = @{ @"fields" : [fields componentsJoinedByString:@","], + @"os_version" : osVersion}; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID parameters:parameters @@ -327,13 +334,13 @@ + (void)_didProcessConfigurationFromNetwork:(FBSDKServerConfiguration *)serverCo _serverConfigurationError = nil; _serverConfigurationErrorTimestamp = nil; -#ifdef DEBUG + #ifdef DEBUG NSString *updateMessage = _serverConfiguration.updateMessage; if (updateMessage && updateMessage.length > 0 && !_printedUpdateMessage) { _printedUpdateMessage = YES; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorInformational logEntry:updateMessage]; } -#endif + #endif if (!_printedUpdateMessage) { _printedUpdateMessage = _printedUpdateMessage; @@ -344,10 +351,10 @@ + (void)_didProcessConfigurationFromNetwork:(FBSDKServerConfiguration *)serverCo NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, appID]; if (serverConfiguration) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSData *data = [NSKeyedArchiver archivedDataWithRootObject:serverConfiguration]; -#pragma clang diagnostic pop + #pragma clang diagnostic pop [defaults setObject:data forKey:defaultsKey]; } @@ -377,8 +384,8 @@ + (NSDictionary *)_parseDialogConfigurations:(NSDictionary *)dictionary NSURL *URL = [FBSDKTypeUtility URLValue:dialogConfigurationDictionary[@"url"]]; NSArray *appVersions = [FBSDKTypeUtility arrayValue:dialogConfigurationDictionary[@"versions"]]; [FBSDKTypeUtility dictionary:dialogConfigurations setObject:[[FBSDKDialogConfiguration alloc] initWithName:name - URL:URL - appVersions:appVersions] forKey:name]; + URL:URL + appVersions:appVersions] forKey:name]; } } } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m index 2ae910e4f7..6a52b245f1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m @@ -80,14 +80,15 @@ - (void)setAccessToken:(FBSDKAccessToken *)token } NSData *tokenData = [NSKeyedArchiver archivedDataWithRootObject:token]; NSDictionary *dict = @{ - kFBSDKAccessTokenUUIDKey : uuid, - kFBSDKAccessTokenEncodedKey : tokenData - }; + kFBSDKAccessTokenUUIDKey : uuid, + kFBSDKAccessTokenEncodedKey : tokenData + }; [_keychainStore setDictionary:dict forKey:kFBSDKAccessTokenKeychainKey accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; } + #pragma clang diagnostic pop - (void)clearCache @@ -99,4 +100,5 @@ - (void)clearCache [defaults removeObjectForKey:kFBSDKAccessTokenUserDefaultsKey]; [defaults synchronize]; } + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.m index 1efb30b2c3..7099c7aa5d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.m @@ -19,9 +19,9 @@ #import "FBSDKKeychainStore.h" #import "FBSDKDynamicFrameworkLoader.h" +#import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" @implementation FBSDKKeychainStore @@ -58,6 +58,7 @@ - (NSDictionary *)dictionaryForKey:(NSString *)key return dict; } + #pragma clang diagnostic pop - (BOOL)setString:(NSString *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility @@ -96,15 +97,15 @@ - (BOOL)setData:(NSData *)value forKey:(NSString *)key accessibility:(CFTypeRef) NSMutableDictionary *attributesToUpdate = [NSMutableDictionary dictionary]; [attributesToUpdate setObject:value forKey:[FBSDKDynamicFrameworkLoader loadkSecValueData]]; - status = fbsdkdfl_SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate); - if (status == errSecItemNotFound) { -#if !TARGET_OS_TV - if (@available(macOS 10.9, iOS 8, *)) { - if (accessibility) { - [query setObject:(__bridge id)(accessibility) forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessible]]; - } + status = fbsdkdfl_SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate); + if (status == errSecItemNotFound) { + #if !TARGET_OS_TV + if (@available(macOS 10.9, iOS 8, *)) { + if (accessibility) { + [query setObject:(__bridge id)(accessibility) forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessible]]; } -#endif + } + #endif [query setObject:value forKey:[FBSDKDynamicFrameworkLoader loadkSecValueData]]; status = fbsdkdfl_SecItemAdd((__bridge CFDictionaryRef)query, NULL); diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.m index 1aa2f5f0e0..dcd38e9a3f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.m @@ -33,7 +33,7 @@ - (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)acce return [self init]; } -- (NSMutableDictionary*)queryForKey:(NSString *)key +- (NSMutableDictionary *)queryForKey:(NSString *)key { NSMutableDictionary *query = [NSMutableDictionary dictionary]; [FBSDKTypeUtility dictionary:query setObject:(__bridge id)([FBSDKDynamicFrameworkLoader loadkSecClassGenericPassword]) forKey:(__bridge id)[FBSDKDynamicFrameworkLoader loadkSecClass]]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m index 244efcaad8..b02e4e54cf 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m @@ -20,11 +20,11 @@ #if !TARGET_OS_TV -#import "FBSDKCloseIcon.h" + #import "FBSDKCloseIcon.h" @implementation FBSDKCloseIcon -#pragma mark - Public API + #pragma mark - Public API - (UIImage *)imageWithSize:(CGSize)size { @@ -40,11 +40,11 @@ - (UIImage *)imageWithSize:(CGSize)size // shadow rect = CGRectIntegral(CGRectInset(rect, step, step)); NSArray *colors = @[ - (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.7].CGColor, - (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.3].CGColor, - (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.1].CGColor, - (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.0].CGColor, - ]; + (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.7].CGColor, + (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.3].CGColor, + (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.1].CGColor, + (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.0].CGColor, + ]; CGFloat locations[4] = { 0.70, 0.80, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.h index f18c98db8f..565ea0f18d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import UIColor *FBSDKUIColorWithRGBA(uint8_t r, uint8_t g, uint8_t b, CGFloat a); UIColor *FBSDKUIColorWithRGB(uint8_t r, uint8_t g, uint8_t b); diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.m index 2d27478f41..9638d5948b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.m @@ -20,18 +20,18 @@ #if !TARGET_OS_TV -#import "FBSDKColor.h" + #import "FBSDKColor.h" static const CGFloat kFBRGBMax = 255.0; UIColor *FBSDKUIColorWithRGBA(uint8_t r, uint8_t g, uint8_t b, CGFloat a) { - return [UIColor colorWithRed:(r / kFBRGBMax) green:(g / kFBRGBMax) blue:(b / kFBRGBMax) alpha:a]; + return [UIColor colorWithRed:(r / kFBRGBMax) green:(g / kFBRGBMax) blue:(b / kFBRGBMax) alpha:a]; } UIColor *FBSDKUIColorWithRGB(uint8_t r, uint8_t g, uint8_t b) { - return FBSDKUIColorWithRGBA(r, g, b, 1.0); + return FBSDKUIColorWithRGBA(r, g, b, 1.0); } #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.m index f13364f061..88794b52b6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.m @@ -22,50 +22,50 @@ @implementation FBSDKLogo - (CGPathRef)pathWithSize:(CGSize)size { - CGFloat originalCanvasWidth = 1366; - CGFloat originalCanvasHeight = 1366; + CGFloat originalCanvasWidth = 1366; + CGFloat originalCanvasHeight = 1366; - CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / originalCanvasWidth, size.height / originalCanvasHeight); + CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / originalCanvasWidth, size.height / originalCanvasHeight); - UIBezierPath* path = [UIBezierPath bezierPath]; - [path moveToPoint: CGPointMake(1365.33, 682.67)]; - [path addCurveToPoint: CGPointMake(682.67, -0) - controlPoint1: CGPointMake(1365.33, 305.64) - controlPoint2: CGPointMake(1059.69, -0)]; - [path addCurveToPoint: CGPointMake(0, 682.67) - controlPoint1: CGPointMake(305.64, -0) - controlPoint2: CGPointMake(0, 305.64)]; - [path addCurveToPoint: CGPointMake(576, 1357.04) - controlPoint1: CGPointMake(0, 1023.41) - controlPoint2: CGPointMake(249.64, 1305.83)]; - [path addLineToPoint: CGPointMake(576, 880)]; - [path addLineToPoint: CGPointMake(402.67, 880)]; - [path addLineToPoint: CGPointMake(402.67, 682.67)]; - [path addLineToPoint: CGPointMake(576, 682.67)]; - [path addLineToPoint: CGPointMake(576, 532.27)]; - [path addCurveToPoint: CGPointMake(833.85, 266.67) - controlPoint1: CGPointMake(576, 361.17) - controlPoint2: CGPointMake(677.92, 266.67)]; - [path addCurveToPoint: CGPointMake(986.67, 280) - controlPoint1: CGPointMake(908.54, 266.67) - controlPoint2: CGPointMake(986.67, 280)]; - [path addLineToPoint: CGPointMake(986.67, 448)]; - [path addLineToPoint: CGPointMake(900.58, 448)]; - [path addCurveToPoint: CGPointMake(789.33, 554.61) - controlPoint1: CGPointMake(815.78, 448) - controlPoint2: CGPointMake(789.33, 500.62)]; - [path addLineToPoint: CGPointMake(789.33, 682.67)]; - [path addLineToPoint: CGPointMake(978.67, 682.67)]; - [path addLineToPoint: CGPointMake(948.4, 880)]; - [path addLineToPoint: CGPointMake(789.33, 880)]; - [path addLineToPoint: CGPointMake(789.33, 1357.04)]; - [path addCurveToPoint: CGPointMake(1365.33, 682.67) - controlPoint1: CGPointMake(1115.69, 1305.83) - controlPoint2: CGPointMake(1365.33, 1023.41)]; - [path closePath]; - [path applyTransform:transformValue]; + UIBezierPath *path = [UIBezierPath bezierPath]; + [path moveToPoint:CGPointMake(1365.33, 682.67)]; + [path addCurveToPoint:CGPointMake(682.67, -0) + controlPoint1:CGPointMake(1365.33, 305.64) + controlPoint2:CGPointMake(1059.69, -0)]; + [path addCurveToPoint:CGPointMake(0, 682.67) + controlPoint1:CGPointMake(305.64, -0) + controlPoint2:CGPointMake(0, 305.64)]; + [path addCurveToPoint:CGPointMake(576, 1357.04) + controlPoint1:CGPointMake(0, 1023.41) + controlPoint2:CGPointMake(249.64, 1305.83)]; + [path addLineToPoint:CGPointMake(576, 880)]; + [path addLineToPoint:CGPointMake(402.67, 880)]; + [path addLineToPoint:CGPointMake(402.67, 682.67)]; + [path addLineToPoint:CGPointMake(576, 682.67)]; + [path addLineToPoint:CGPointMake(576, 532.27)]; + [path addCurveToPoint:CGPointMake(833.85, 266.67) + controlPoint1:CGPointMake(576, 361.17) + controlPoint2:CGPointMake(677.92, 266.67)]; + [path addCurveToPoint:CGPointMake(986.67, 280) + controlPoint1:CGPointMake(908.54, 266.67) + controlPoint2:CGPointMake(986.67, 280)]; + [path addLineToPoint:CGPointMake(986.67, 448)]; + [path addLineToPoint:CGPointMake(900.58, 448)]; + [path addCurveToPoint:CGPointMake(789.33, 554.61) + controlPoint1:CGPointMake(815.78, 448) + controlPoint2:CGPointMake(789.33, 500.62)]; + [path addLineToPoint:CGPointMake(789.33, 682.67)]; + [path addLineToPoint:CGPointMake(978.67, 682.67)]; + [path addLineToPoint:CGPointMake(948.4, 880)]; + [path addLineToPoint:CGPointMake(789.33, 880)]; + [path addLineToPoint:CGPointMake(789.33, 1357.04)]; + [path addCurveToPoint:CGPointMake(1365.33, 682.67) + controlPoint1:CGPointMake(1115.69, 1305.83) + controlPoint2:CGPointMake(1365.33, 1023.41)]; + [path closePath]; + [path applyTransform:transformValue]; - return [path CGPath]; + return [path CGPath]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m index bdd5912524..c7b81f5f18 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKMaleSilhouetteIcon.h" + #import "FBSDKMaleSilhouetteIcon.h" @implementation FBSDKMaleSilhouetteIcon diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h index dfa023356c..759d7678fe 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h @@ -33,8 +33,10 @@ static inline CGSize FBSDKEdgeInsetsInsetSize(CGSize size, UIEdgeInsets insets) */ static inline CGSize FBSDKEdgeInsetsOutsetSize(CGSize size, UIEdgeInsets insets) { - return CGSizeMake(insets.left + size.width + insets.right, - insets.top + size.height + insets.bottom); + return CGSizeMake( + insets.left + size.width + insets.right, + insets.top + size.height + insets.bottom + ); } /** @@ -64,14 +66,14 @@ static inline CGSize FBSDKTextSize(NSString *text, NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = lineBreakMode; NSDictionary *attributes = @{ - NSFontAttributeName: font, - NSParagraphStyleAttributeName: paragraphStyle, - }; + NSFontAttributeName : font, + NSParagraphStyleAttributeName : paragraphStyle, + }; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:attributes]; CGSize size = [attributedString boundingRectWithSize:constrainedSize - options:(NSStringDrawingUsesDeviceMetrics | - NSStringDrawingUsesLineFragmentOrigin | - NSStringDrawingUsesFontLeading) + options:(NSStringDrawingUsesDeviceMetrics + | NSStringDrawingUsesLineFragmentOrigin + | NSStringDrawingUsesFontLeading) context:NULL].size; return CGSizeMake(ceilf(size.width), ceilf(size.height)); } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.m index 9bc6f1b6a3..4d25e69084 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.m @@ -20,7 +20,7 @@ #import "FBSDKAccessToken.h" #import "FBSDKAppEvents+Internal.h" -#import "FBSDKTypeUtility.h" +#import "FBSDKInternalUtility.h" @implementation FBSDKViewImpressionTracker { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m index 07117cf8d4..967b108cd4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m @@ -20,19 +20,17 @@ #if !TARGET_OS_TV -#import "FBSDKWebDialog.h" + #import "FBSDKWebDialog.h" -#import "FBSDKAccessToken.h" -#import "FBSDKDynamicFrameworkLoader.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKLogger.h" -#import "FBSDKSettings.h" -#import "FBSDKTypeUtility.h" -#import "FBSDKWebDialogView.h" -#import "FBSDKInternalUtility.h" + #import "FBSDKAccessToken.h" + #import "FBSDKDynamicFrameworkLoader.h" + #import "FBSDKInternalUtility.h" + #import "FBSDKLogger.h" + #import "FBSDKSettings.h" + #import "FBSDKWebDialogView.h" -#define FBSDK_WEB_DIALOG_SHOW_ANIMATION_DURATION 0.2 -#define FBSDK_WEB_DIALOG_DISMISS_ANIMATION_DURATION 0.3 + #define FBSDK_WEB_DIALOG_SHOW_ANIMATION_DURATION 0.2 + #define FBSDK_WEB_DIALOG_DISMISS_ANIMATION_DURATION 0.3 typedef void (^FBSDKBoolBlock)(BOOL finished); @@ -47,7 +45,7 @@ @implementation FBSDKWebDialog FBSDKWebDialogView *_dialogView; } -#pragma mark - Class Methods + #pragma mark - Class Methods + (instancetype)showWithName:(NSString *)name parameters:(NSDictionary *)parameters @@ -61,7 +59,7 @@ + (instancetype)showWithName:(NSString *)name return dialog; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (void)dealloc { @@ -71,7 +69,7 @@ - (void)dealloc [_backgroundView removeFromSuperview]; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (BOOL)show { @@ -110,7 +108,7 @@ - (BOOL)show return YES; } -#pragma mark - FBSDKWebDialogViewDelegate + #pragma mark - FBSDKWebDialogViewDelegate - (void)webDialogView:(FBSDKWebDialogView *)webDialogView didCompleteWithResults:(NSDictionary *)results { @@ -130,15 +128,16 @@ - (void)webDialogViewDidCancel:(FBSDKWebDialogView *)webDialogView - (void)webDialogViewDidFinishLoad:(FBSDKWebDialogView *)webDialogView { if (_deferVisibility) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - if (self->_dialogView) { - [self _showWebView]; - } - }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + if (self->_dialogView) { + [self _showWebView]; + } + }); } } -#pragma mark - Notifications + #pragma mark - Notifications - (void)_addObservers { @@ -167,7 +166,7 @@ - (void)_removeObservers [nc removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_cancel { @@ -191,15 +190,15 @@ - (void)_dismissAnimated:(BOOL)animated FBSDKWebDialogView *dialogView = _dialogView; _dialogView.delegate = nil; _dialogView = nil; - void(^didDismiss)(BOOL) = ^(BOOL finished){ + void (^didDismiss)(BOOL) = ^(BOOL finished) { [backgroundView removeFromSuperview]; [dialogView removeFromSuperview]; }; if (animated) { [UIView animateWithDuration:FBSDK_WEB_DIALOG_DISMISS_ANIMATION_DURATION animations:^{ - dialogView.alpha = 0.0; - backgroundView.alpha = 0.0; - } completion:didDismiss]; + dialogView.alpha = 0.0; + backgroundView.alpha = 0.0; + } completion:didDismiss]; } else { didDismiss(YES); } @@ -225,8 +224,8 @@ - (NSURL *)_generateURL:(NSError **)errorRef [FBSDKTypeUtility dictionary:parameters setObject:@"fbconnect://success" forKey:@"redirect_uri"]; [FBSDKTypeUtility dictionary:parameters setObject:[FBSDKSettings appID] forKey:@"app_id"]; [FBSDKTypeUtility dictionary:parameters - setObject:[FBSDKAccessToken currentAccessToken].tokenString - forKey:@"access_token"]; + setObject:[FBSDKAccessToken currentAccessToken].tokenString + forKey:@"access_token"]; [parameters addEntriesFromDictionary:self.parameters]; return [FBSDKInternalUtility facebookURLWithHostPrefix:@"m" path:[@"/dialog/" stringByAppendingString:self.name] @@ -272,7 +271,7 @@ - (CGAffineTransform)_transformForOrientation case UIInterfaceOrientationLandscapeLeft: return CGAffineTransformMakeRotation(M_PI * 1.5); case UIInterfaceOrientationLandscapeRight: - return CGAffineTransformMakeRotation(M_PI/2); + return CGAffineTransformMakeRotation(M_PI / 2); case UIInterfaceOrientationPortraitUpsideDown: return CGAffineTransformMakeRotation(-M_PI); case UIInterfaceOrientationPortrait: @@ -296,10 +295,10 @@ - (CGRect)_applicationFrameForOrientation #endif if (insets.top == 0.0) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" insets.top = [[UIApplication sharedApplication] statusBarFrame].size.height; -#pragma clang diagnostic pop + #pragma clang diagnostic pop } applicationFrame.origin.x += insets.left; applicationFrame.origin.y += insets.top; @@ -335,10 +334,12 @@ - (void)_updateViewsWithScale:(CGFloat)scale _dialogView.transform = transform; } transform = CGAffineTransformScale([self _transformForOrientation], scale, scale); - void(^updateBlock)(void) = ^{ + void (^updateBlock)(void) = ^{ self->_dialogView.transform = transform; - self->_dialogView.center = CGPointMake(CGRectGetMidX(applicationFrame), - CGRectGetMidY(applicationFrame)); + self->_dialogView.center = CGPointMake( + CGRectGetMidX(applicationFrame), + CGRectGetMidY(applicationFrame) + ); self->_dialogView.alpha = alpha; self->_backgroundView.alpha = alpha; }; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m index a5efb139a3..20ed7e20a1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m @@ -20,16 +20,15 @@ #if !TARGET_OS_TV -#import "FBSDKWebDialogView.h" + #import "FBSDKWebDialogView.h" -#import + #import -#import "FBSDKCloseIcon.h" -#import "FBSDKError.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKTypeUtility.h" + #import "FBSDKCloseIcon.h" + #import "FBSDKError.h" + #import "FBSDKInternalUtility.h" -#define FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH 10.0 + #define FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH 10.0 @interface FBSDKWebDialogView () @end @@ -41,10 +40,10 @@ @implementation FBSDKWebDialogView WKWebView *_webView; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { @@ -58,9 +57,9 @@ - (instancetype)initWithFrame:(CGRect)frame _closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; UIImage *closeImage = [[[FBSDKCloseIcon alloc] init] imageWithSize:CGSizeMake(29.0, 29.0)]; [_closeButton setImage:closeImage forState:UIControlStateNormal]; - [_closeButton setTitleColor:[UIColor colorWithRed:167.0/255.0 - green:184.0/255.0 - blue:216.0/255.0 + [_closeButton setTitleColor:[UIColor colorWithRed:167.0 / 255.0 + green:184.0 / 255.0 + blue:216.0 / 255.0 alpha:1.0] forState:UIControlStateNormal]; [_closeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; _closeButton.showsTouchWhenHighlighted = YES; @@ -74,14 +73,15 @@ - (instancetype)initWithFrame:(CGRect)frame } return self; } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop - (void)dealloc { _webView.navigationDelegate = nil; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (void)loadURL:(NSURL *)URL { @@ -94,7 +94,7 @@ - (void)stopLoading [_webView stopLoading]; } -#pragma mark - Layout + #pragma mark - Layout - (void)drawRect:(CGRect)rect { @@ -109,8 +109,8 @@ - (void)drawRect:(CGRect)rect [super drawRect:rect]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (void)layoutSubviews { [super layoutSubviews]; @@ -122,10 +122,12 @@ - (void)layoutSubviews UIEdgeInsets iPadInsets = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset); bounds = UIEdgeInsetsInsetRect(bounds, iPadInsets); } - UIEdgeInsets webViewInsets = UIEdgeInsetsMake(FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, - FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, - FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, - FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH); + UIEdgeInsets webViewInsets = UIEdgeInsetsMake( + FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, + FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, + FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, + FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH + ); _webView.frame = CGRectIntegral(UIEdgeInsetsInsetRect(bounds, webViewInsets)); CGRect webViewBounds = _webView.bounds; @@ -140,16 +142,17 @@ - (void)layoutSubviews _closeButton.frame = CGRectIntegral(closeButtonFrame); } } -#pragma clang diagnostic pop -#pragma mark - Actions + #pragma clang diagnostic pop + + #pragma mark - Actions - (void)_close:(id)sender { [_delegate webDialogViewDidCancel:self]; } -#pragma mark - WKNavigationDelegate + #pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { @@ -160,17 +163,17 @@ - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigatio // away before the page has completely loaded, if we find cases where we want this to result in dialog failure // (usually this just means quick-user), then we should add something more robust here to account for differences in // application needs - if (!(([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) || - ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102))) { + if (!(([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) + || ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102))) { [_delegate webDialogView:self didFailWithError:error]; } } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -- (void)webView:(WKWebView *)webView -decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction -decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void) webView:(WKWebView *)webView + decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction + decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURL *URL = navigationAction.request.URL; @@ -197,7 +200,8 @@ - (void)webView:(WKWebView *)webView decisionHandler(WKNavigationActionPolicyAllow); } } -#pragma clang diagnostic pop + + #pragma clang diagnostic pop - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m b/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m index 291cc83622..3fd62d9231 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m @@ -18,12 +18,12 @@ #import "FBSDKDynamicFrameworkLoader.h" -#import - #import #import #import +#import + #import "FBSDKLogger.h" #import "FBSDKSettings.h" @@ -31,11 +31,10 @@ #pragma mark - Library and Symbol Loading -struct FBSDKDFLLoadSymbolContext -{ +struct FBSDKDFLLoadSymbolContext { void *(*library)(void); // function to retrieve the library handle (it's a function instead of void * so it can be staticlly bound) - const char *name; // name of the symbol to retrieve - void **address; // [out] address of the symbol in the process address space + const char *name; // name of the symbol to retrieve + void **address; // [out] address of the symbol in the process address space }; // Retrieves the handle for a library for framework. The paths for each are constructed @@ -60,18 +59,18 @@ // Implements the callback for dispatch_once() that loads the handle for specified framework name #define _fbsdkdfl_load_framework_once_impl_(FRAMEWORK) \ - static void fbsdkdfl_load_##FRAMEWORK##_once(void *context) { \ + static void fbsdkdfl_load_ ## FRAMEWORK ## _once(void *context) { \ *(void **)context = fbsdkdfl_load_framework_once(@#FRAMEWORK); \ } // Implements the framework/library retrieval function for the given name. // It calls the loading function once and caches the handle in a local static variable #define _fbsdkdfl_handle_get_impl_(LIBRARY) \ - static void *fbsdkdfl_handle_get_##LIBRARY(void) { \ - static void *LIBRARY##_handle; \ - static dispatch_once_t LIBRARY##_once; \ - dispatch_once_f(&LIBRARY##_once, &LIBRARY##_handle, &fbsdkdfl_load_##LIBRARY##_once); \ - return LIBRARY##_handle;\ + static void *fbsdkdfl_handle_get_ ## LIBRARY(void) { \ + static void *LIBRARY ## _handle; \ + static dispatch_once_t LIBRARY ## _once; \ + dispatch_once_f(&LIBRARY ## _once, &LIBRARY ## _handle, &fbsdkdfl_load_ ## LIBRARY ## _once); \ + return LIBRARY ## _handle; \ } // Callback from dispatch_once() to load a specific symbol @@ -84,13 +83,13 @@ static void fbsdkdfl_load_symbol_once(void *context) // The boilerplate code for loading a symbol from a given library once and caching it in a static local #define _fbsdkdfl_symbol_get(LIBRARY, PREFIX, SYMBOL, TYPE, VARIABLE_NAME) \ static TYPE VARIABLE_NAME; \ - static dispatch_once_t SYMBOL##_once; \ - static struct FBSDKDFLLoadSymbolContext ctx = { .library = &fbsdkdfl_handle_get_##LIBRARY, .name = PREFIX #SYMBOL, .address = (void *)&VARIABLE_NAME }; \ - dispatch_once_f(&SYMBOL##_once, &ctx, &fbsdkdfl_load_symbol_once) + static dispatch_once_t SYMBOL ## _once; \ + static struct FBSDKDFLLoadSymbolContext ctx = { .library = &fbsdkdfl_handle_get_ ## LIBRARY, .name = PREFIX #SYMBOL, .address = (void *)&VARIABLE_NAME }; \ + dispatch_once_f(&SYMBOL ## _once, &ctx, &fbsdkdfl_load_symbol_once) #define _fbsdkdfl_symbol_get_c(LIBRARY, SYMBOL) _fbsdkdfl_symbol_get(LIBRARY, "OBJC_CLASS_$_", SYMBOL, Class, c) // convenience symbol retrieval macro for getting an Objective-C class symbol and storing it in the local static c -#define _fbsdkdfl_symbol_get_f(LIBRARY, SYMBOL) _fbsdkdfl_symbol_get(LIBRARY, "", SYMBOL, SYMBOL##_type, f) // convenience symbol retrieval macro for getting a function pointer and storing it in the local static f -#define _fbsdkdfl_symbol_get_k(LIBRARY, SYMBOL, TYPE) _fbsdkdfl_symbol_get(LIBRARY, "", SYMBOL, TYPE, k) // convenience symbol retrieval macro for getting a pointer to a named variable and storing it in the local static k +#define _fbsdkdfl_symbol_get_f(LIBRARY, SYMBOL) _fbsdkdfl_symbol_get(LIBRARY, "", SYMBOL, SYMBOL ## _type, f) // convenience symbol retrieval macro for getting a function pointer and storing it in the local static f +#define _fbsdkdfl_symbol_get_k(LIBRARY, SYMBOL, TYPE) _fbsdkdfl_symbol_get(LIBRARY, "", SYMBOL, TYPE, k) // convenience symbol retrieval macro for getting a pointer to a named variable and storing it in the local static k // convenience macro for verifying a pointer to a named variable was successfully loaded and returns the value #define _fbsdkdfl_return_k(FRAMEWORK, SYMBOL) \ @@ -473,8 +472,8 @@ Class fbsdkdfl_ALAssetsLibraryClass(void) Class fbsdkdfl_CTTelephonyNetworkInfoClass(void) { - _fbsdkdfl_CoreTelephonyLibrary_get_c(CTTelephonyNetworkInfo); - return c; + _fbsdkdfl_CoreTelephonyLibrary_get_c(CTTelephonyNetworkInfo); + return c; } #pragma mark - CoreImage @@ -485,7 +484,6 @@ Class fbsdkdfl_CTTelephonyNetworkInfoClass(void) #define _fbsdkdfl_CoreImage_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(CoreImage, SYMBOL); #define _fbsdkdfl_CoreImage_get_and_return_NSString(SYMBOL) _fbsdkdfl_get_and_return_NSString(CoreImage, SYMBOL) - Class fbsdkdfl_CIImageClass(void) { _fbsdkdfl_CoreImage_get_c(CIImage); @@ -541,8 +539,8 @@ Class fbsdkdfl_PHAssetChangeRequest(void) #define _fbsdkdfl_MobileCoreServices_get_k(SYMBOL) _fbsdkdfl_symbol_get_k(MobileCoreServices, SYMBOL, CFStringRef *) #define _fbsdkdfl_MobileCoreServices_get_and_return_k(SYMBOL) \ -_fbsdkdfl_MobileCoreServices_get_k(SYMBOL); \ -_fbsdkdfl_return_k(MobileCoreServices, SYMBOL) + _fbsdkdfl_MobileCoreServices_get_k(SYMBOL); \ + _fbsdkdfl_return_k(MobileCoreServices, SYMBOL) #define _fbsdkdfl_MobileCoreServices_get_f(SYMBOL) _fbsdkdfl_symbol_get_f(MobileCoreServices, SYMBOL) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Swift/Imports.swift b/FBSDKCoreKit/FBSDKCoreKit/Swift/Imports.swift new file mode 100644 index 0000000000..ad8ed5ecf9 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Swift/Imports.swift @@ -0,0 +1,19 @@ +// Copyright (c) 2016-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 Accelerate diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m index c6920b2ff3..df1a6a8623 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKAppLinkUtility.h" @@ -41,4 +40,5 @@ - (void)testWithPromoCode XCTAssertNotNil(promoCode); XCTAssertEqualObjects(promoCode, @"PROMOWORKS"); } + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index aad2c1b69c..c71ba75e0e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -16,96 +16,353 @@ // 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 "NotificationCenterSpy.h" +#import "AppDelegateObserverFake.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" +#import "FBSDKTestCase.h" +#import "SampleAccessToken.h" +#import "UserDefaultsSpy.h" + +@interface FBSDKApplicationDelegate (Testing) -// An extension that redeclares a private method so that it can be mocked -@interface FBSDKApplicationDelegate () - (BOOL)isAppLaunched; +- (void)setIsAppLaunched:(BOOL)isLaunched; +- (NSHashTable> *)applicationObservers; +- (void)resetApplicationObserverCache; +- (void)_logSDKInitialize; +- (void)applicationDidBecomeActive:(NSNotification *)notification; +- (void)applicationWillResignActive:(NSNotification *)notification; + +@end + +@interface FBSDKBridgeAPI (ApplicationObserving) @end -@interface FBSDKApplicationDelegateTests : XCTestCase { +@interface FBSDKApplicationDelegateTests : FBSDKTestCase +{ FBSDKApplicationDelegate *_delegate; - id _delegateMock; - id _settingsMock; + UserDefaultsSpy *_defaultsSpy; + FBSDKProfile *_profile; + id _partialDelegateMock; + NotificationCenterSpy *_notificationCenterSpy; } - @end -static id g_mockNSBundle; +@implementation FBSDKApplicationDelegateTests + +- (void)setUp +{ + [super setUp]; -@interface FBSDKApplicationDelegate(Test) + _delegate = FBSDKApplicationDelegate.sharedInstance; + _delegate.isAppLaunched = NO; -- (void)_logSDKInitialize; -- (void)applicationDidBecomeActive:(NSNotification *)notification; + _defaultsSpy = [UserDefaultsSpy new]; + [self stubUserDefaultsWith:_defaultsSpy]; -@end + _notificationCenterSpy = [NotificationCenterSpy new]; + [self stubDefaultNotificationCenterWith:_notificationCenterSpy]; -@implementation FBSDKApplicationDelegateTests + _profile = [[FBSDKProfile alloc] initWithUserID:self.name + firstName:nil + middleName:nil + lastName:nil + name:nil + linkURL:nil + refreshDate:nil]; -- (void)setUp { - [super setUp]; - g_mockNSBundle = [FBSDKCoreKitTestUtility mainBundleMock]; - _settingsMock = OCMStrictClassMock([FBSDKSettings class]); + // Avoid actually calling log initialize b/c of the side effects. + _partialDelegateMock = OCMPartialMock(_delegate); + OCMStub([_partialDelegateMock _logSDKInitialize]); + + [_delegate resetApplicationObserverCache]; + + [self stubAppEventsSingletonWith:self.appEventsMock]; + [self stubLoadingAdNetworkReporterConfiguration]; +} + +- (void)tearDown +{ + [super tearDown]; + + _delegate = nil; + + _defaultsSpy = nil; + _profile = nil; + + [_partialDelegateMock stopMocking]; + _partialDelegateMock = nil; +} + +// MARK: - Observers + +- (void)testDefaultObservers +{ + // Note: in reality this will have one observer from the BridgeAPI load method. + // this needs to be re-architected to avoid this. + XCTAssertEqual( + _delegate.applicationObservers.count, + 0, + "Should have no observers by default" + ); +} + +- (void)testAddingNewObserver +{ + ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; + [_delegate addObserver:observer]; + + XCTAssertEqual( + [_delegate applicationObservers].count, + 1, + "Should be able to add a single observer" + ); +} + +- (void)testAddingDuplicateObservers +{ + ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; + [_delegate addObserver:observer]; + [_delegate addObserver:observer]; + + XCTAssertEqual( + [_delegate applicationObservers].count, + 1, + "Should only add one instance of a given observer" + ); +} + +- (void)testRemovingObserver +{ + ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; + [_delegate addObserver:observer]; + [_delegate removeObserver:observer]; + + XCTAssertEqual( + _delegate.applicationObservers.count, + 0, + "Should be able to remove observers that are present in the stored list" + ); +} + +- (void)testRemovingMissingObserver +{ + ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; + [_delegate removeObserver:observer]; + + XCTAssertEqual( + _delegate.applicationObservers.count, + 0, + "Should not be able to remove absent observers" + ); +} + +// MARK: - Lifecycle Methods + +- (void)testDidFinishLaunchingLaunchedApp +{ + _delegate.isAppLaunched = YES; + + XCTAssertFalse( + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil], + "Should return false if the application is already launched" + ); + // TODO: check that side effects do not occur +} + +- (void)testDidFinishLaunchingSetsCurrentAccessTokenWithCache +{ + FBSDKAccessToken *expected = SampleAccessToken.validToken; + FakeAccessTokenCache *cache = [[FakeAccessTokenCache alloc] initWithToken:expected]; + [self stubAccessTokenCacheWith:cache]; + + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + // Should set the current access token to the cached access token when it exists + OCMVerify(ClassMethod([self.accessTokenClassMock setCurrentAccessToken:expected])); +} + +- (void)testDidFinishLaunchingSetsCurrentAccessTokenWithoutCache +{ + [self stubAccessTokenCacheWith:[[FakeAccessTokenCache alloc] initWithToken:nil]]; - _delegate = [FBSDKApplicationDelegate sharedInstance]; - _delegateMock = OCMPartialMock(_delegate); - [OCMStub([_delegateMock isAppLaunched]) andReturnValue: OCMOCK_VALUE(NO)]; + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + // Should set the current access token to nil access token when there isn't a cached token + OCMVerify(ClassMethod([self.accessTokenClassMock setCurrentAccessToken:nil])); } -- (void)tearDown { - [g_mockNSBundle stopMocking]; - g_mockNSBundle = nil; - [_settingsMock stopMocking]; - _settingsMock = nil; - [_delegateMock stopMocking]; - _delegateMock = nil; +- (void)testDidFinishLaunchingLoadsServerConfiguration +{ + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + // Should load the server configuration on finishing launching + OCMVerify(ClassMethod([self.serverConfigurationManagerClassMock loadServerConfigurationWithCompletionBlock:nil])); +} + +- (void)testDidFinishLaunchingWithAutoLogEnabled +{ + [self stubIsAutoLogAppEventsEnabled:YES]; + + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + // Should log initialization when auto log app events is enabled + OCMVerify([_partialDelegateMock _logSDKInitialize]); } -- (void)testAutoLogAppEventsEnabled { +- (void)testDidFinishLaunchingWithAutoLogDisabled +{ + // Should not log initialization when auto log app events are disabled + OCMReject([_partialDelegateMock _logSDKInitialize]); + + [self stubIsAutoLogAppEventsEnabled:NO]; - [OCMStub(ClassMethod([_settingsMock isAutoLogAppEventsEnabled])) andReturnValue: OCMOCK_VALUE(YES)]; + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; +} - id app = OCMClassMock([UIApplication class]); +- (void)testDidFinishLaunchingSetsProfileWithCache +{ + [self stubCachedProfileWith:_profile]; - [_delegate application:app didFinishLaunchingWithOptions:nil]; + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; - OCMVerify([_delegateMock _logSDKInitialize]); + // Should set the current profile to the value fetched from the cache + OCMVerify([self.profileClassMock setCurrentProfile:_profile]); } -- (void)testAutoLogAppEventsDisabled { - [OCMStub(ClassMethod([_settingsMock isAutoLogAppEventsEnabled])) andReturnValue: OCMOCK_VALUE(NO)]; +- (void)testDidFinishLaunchingSetsProfileWithoutCache +{ + [self stubCachedProfileWith:nil]; - OCMReject([_delegateMock _logSDKInitialize]); + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; - id app = OCMClassMock([UIApplication class]); - [_delegate application:app didFinishLaunchingWithOptions:nil]; + // Should set the current profile to nil when the cache is empty + OCMVerify([self.profileClassMock setCurrentProfile:nil]); } -- (void)testAppEventsEnabled { +- (void)testDidFinishLaunchingWithObservers +{ + ApplicationDelegateObserverFake *observer1 = [ApplicationDelegateObserverFake new]; + ApplicationDelegateObserverFake *observer2 = [ApplicationDelegateObserverFake new]; - [OCMStub(ClassMethod([_settingsMock isAutoLogAppEventsEnabled])) andReturnValue: OCMOCK_VALUE(YES)]; + [_delegate addObserver:observer1]; + [_delegate addObserver:observer2]; - id appEvents = OCMClassMock([FBSDKAppEvents class]); + BOOL notifiedObservers = [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + XCTAssertEqual( + observer1.didFinishLaunchingCallCount, + 1, + "Should invoke did finish launching on all observers" + ); + XCTAssertEqual( + observer2.didFinishLaunchingCallCount, + 1, + "Should invoke did finish launching on all observers" + ); + XCTAssertTrue(notifiedObservers, "Should indicate if observers were notified"); +} + +- (void)testDidFinishLaunchingWithoutObservers +{ + BOOL notifiedObservers = [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + XCTAssertFalse(notifiedObservers, "Should indicate if no observers were notified"); +} + +- (void)testDidFinishLaunchingCalledFromAutoInit +{ + // Should not log that the SDK implements didFinishLaunching manually + OCMReject( + ClassMethod( + [self.appEventsMock logInternalEvent:@"fb_sdk_implements_did_finish_launching" + parameters:@{} + isImplicitlyLogged:OCMOCK_VALUE(YES)] + ) + ); + + // Stub all the dependencies of initializing SDK + [self stubFBApplicationDelegateSharedInstanceWith:_delegate]; + [self stubRegisterAppForAdNetworkAttribution]; + [self stubDefaultNotificationCenterWith:_notificationCenterSpy]; + OCMStub([_partialDelegateMock applicationDidBecomeActive:UIApplication.sharedApplication]); + [self stubCheckingFeatures]; + [self stubDefaultMeasurementEventListenerWith:[FBSDKMeasurementEventListener new]]; + OCMStub([self.timeSpentDataClassMock setSourceApplication:OCMArg.any openURL:OCMArg.any]); + OCMStub([self.timeSpentDataClassMock registerAutoResetSourceApplication]); + OCMStub([self.internalUtilityClassMock validateFacebookReservedURLSchemes]); + + NSDictionary *launchOptions = @{}; + ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; + [_delegate addObserver:observer]; + [FBSDKApplicationDelegate initializeSDK:launchOptions]; + + XCTAssertEqualObjects(observer.capturedLaunchOptions, @{}, "Observers should not be passed the modified launch arguments."); + // Should Modify the launch arguments when didFinishLaunching is invoked from the `initializeSDK` method + OCMVerify( + [_partialDelegateMock application:UIApplication.sharedApplication + didFinishLaunchingWithOptions:@{@"_calledFromAutoInitSDK" : @YES}] + ); +} + +- (void)testDidFinishLaunchingCalledManually +{ + NSDictionary *launchOptions = @{@"foo" : @"bar"}; + ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; + [_delegate addObserver:observer]; + [FBSDKApplicationDelegate.sharedInstance application:UIApplication.sharedApplication + didFinishLaunchingWithOptions:launchOptions]; + + XCTAssertEqualObjects(observer.capturedLaunchOptions, @{@"foo" : @"bar"}, "Observers should not be passed modified launch arguments."); + OCMVerify( + ClassMethod( + [self.appEventsMock logInternalEvent:@"fb_sdk_implements_did_finish_launching" + parameters:@{} + isImplicitlyLogged:OCMOCK_VALUE(YES)] + ) + ); +} + +- (void)testAppEventsEnabled +{ + [self stubIsAutoLogAppEventsEnabled:YES]; + OCMStub(ClassMethod([self.appEventsMock activateApp])); id notification = OCMClassMock([NSNotification class]); [_delegate applicationDidBecomeActive:notification]; - OCMVerify([appEvents activateApp]); + OCMVerify([self.appEventsMock activateApp]); } --(void)testAppEventsDisabled { - - [OCMStub(ClassMethod([_settingsMock isAutoLogAppEventsEnabled])) andReturnValue: OCMOCK_VALUE(NO)]; +- (void)testAppEventsDisabled +{ + [self stubIsAutoLogAppEventsEnabled:NO]; - id appEvents = OCMStrictClassMock([FBSDKAppEvents class]); - OCMReject([appEvents activateApp]); + OCMReject([self.appEventsMock activateApp]); + OCMStub(ClassMethod([self.appEventsMock activateApp])); id notification = OCMClassMock([NSNotification class]); [_delegate applicationDidBecomeActive:notification]; } + +- (void)testAppNotifyObserversWhenAppWillResignActive +{ + id observer = OCMStrictProtocolMock(@protocol(FBSDKApplicationObserving)); + [_delegate addObserver:observer]; + + NSNotification *notification = OCMClassMock([NSNotification class]); + id application = OCMClassMock([UIApplication class]); + [OCMStub([notification object]) andReturn:application]; + OCMExpect([observer applicationWillResignActive:application]); + + [_delegate applicationWillResignActive:notification]; + + OCMVerify([observer applicationWillResignActive:application]); +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTestUtility.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTestUtility.h index b679315ad0..9814b33e70 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTestUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTestUtility.h @@ -18,6 +18,17 @@ #import +/// OCMock helper for testing methods with non-object args. +#define OCMStubIgnoringNonObjectArgs(invocation) \ + ({ \ + _OCMSilenceWarnings( \ + [OCMMacroState beginStubMacro]; \ + [[[OCMMacroState globalState] recorder] ignoringNonObjectArgs]; \ + invocation; \ + [OCMMacroState endStubMacro]; \ + ); \ +}) + @interface FBSDKCoreKitTestUtility : NSObject /** diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m index eba1ec80f8..f695df1cfd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m @@ -16,55 +16,52 @@ // 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 - #import #import #import "FBSDKCoreKit.h" #import "FBSDKCoreKitTestUtility.h" +#import "FBSDKFeatureManager.h" #import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKSettings+Internal.h" +#import "FBSDKTestCase.h" + +@interface FBSDKGraphRequestConnectionTests : FBSDKTestCase -@interface FBSDKGraphRequestConnectionTests : XCTestCase { - id _settingsMock; -} @property (nonatomic, copy) void (^requestConnectionStartingCallback)(FBSDKGraphRequestConnection *connection); @property (nonatomic, copy) void (^requestConnectionCallback)(FBSDKGraphRequestConnection *connection, NSError *error); @end -static id g_mockNSBundle; - -static NSString *const _mockMobileAppInstallEventName = @"MOBILE_APP_INSTALL"; - @implementation FBSDKGraphRequestConnectionTests #pragma mark - XCTestCase - (void)setUp { - [FBSDKSettings setAppID:@"appid"]; - [FBSDKApplicationDelegate initializeSDK:nil]; - g_mockNSBundle = [FBSDKCoreKitTestUtility mainBundleMock]; - _settingsMock = OCMStrictClassMock([FBSDKSettings class]); + [super setUp]; + + [self stubAppID:self.appID]; + [self stubCheckingFeatures]; + [self stubIsSDKInitialized:YES]; + [self stubLoadingGateKeepers]; + [self stubFetchingCachedServerConfiguration]; } - (void)tearDown { + [super tearDown]; + [OHHTTPStubs removeAllStubs]; - [g_mockNSBundle stopMocking]; - g_mockNSBundle = nil; - [_settingsMock stopMocking]; - _settingsMock = nil; } #pragma mark - Helpers -//to prevent piggybacking of server config fetching +// to prevent piggybacking of server config fetching + (id)mockCachedServerConfiguration { id mockPiggybackManager = [OCMockObject niceMockForClass:[FBSDKGraphRequestPiggybackManager class]]; @@ -74,7 +71,6 @@ + (id)mockCachedServerConfiguration #pragma mark - FBSDKGraphRequestConnectionDelegate - - (void)requestConnection:(FBSDKGraphRequestConnection *)connection didFailWithError:(NSError *)error { if (self.requestConnectionCallback) { @@ -101,31 +97,31 @@ - (void)requestConnectionWillBeginLoading:(FBSDKGraphRequestConnection *)connect #pragma mark - Tests -- (void)_testClientToken +- (void)testClientToken { // if it's a batch request the body will be zipped so make sure we don't do that - id mockUtility = [OCMockObject niceMockForClass:[FBSDKBasicUtility class]]; + id mockUtility = [OCMockObject niceMockForClass:[FBSDKBasicUtility class]]; [[[mockUtility stub] andReturn:nil] gzip:[OCMArg any]]; XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; [FBSDKAccessToken setCurrentAccessToken:nil]; [FBSDKSettings setClientToken:@"clienttoken"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - // If it's a batch request, the token will be in the body. If it's a single request it will be in the url - // we should check that it's in one or the other. - NSString *url = request.URL.absoluteString; - NSString *body = [[NSString alloc] initWithData:request.OHHTTPStubs_HTTPBody encoding:NSUTF8StringEncoding]; - u_long tokenLength = ([body rangeOfString:@"access_token"].length + [url rangeOfString:@"access_token"].length); - XCTAssertTrue(tokenLength > 0); - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463, \"type\":\"OAuthException\"}}" dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + // If it's a batch request, the token will be in the body. If it's a single request it will be in the url + // we should check that it's in one or the other. + NSString *url = request.URL.absoluteString; + NSString *body = [[NSString alloc] initWithData:request.OHHTTPStubs_HTTPBody encoding:NSUTF8StringEncoding]; + u_long tokenLength = ([body rangeOfString:@"access_token"].length + [url rangeOfString:@"access_token"].length); + XCTAssertTrue(tokenLength > 0); + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463, \"type\":\"OAuthException\"}}" dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { // make sure there is no recovery info for client token failures. XCTAssertNil(error.localizedRecoverySuggestion); [exp fulfill]; @@ -141,17 +137,17 @@ - (void)testClientTokenSkipped XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; [FBSDKAccessToken setCurrentAccessToken:nil]; [FBSDKSettings setClientToken:@"clienttoken"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - XCTAssertTrue([[request.URL absoluteString] rangeOfString:@"access_token"].location == NSNotFound); - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""} flags:FBSDKGraphRequestFlagSkipClientToken] + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + XCTAssertTrue([[request.URL absoluteString] rangeOfString:@"access_token"].location == NSNotFound); + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""} flags:FBSDKGraphRequestFlagSkipClientToken] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { [exp fulfill]; }]; @@ -165,24 +161,24 @@ - (void)testConnectionDelegate { id mockPiggybackManager = [[self class] mockCachedServerConfiguration]; // stub out a batch response that returns /me.id twice - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSString *meResponse = [@"{ \"id\":\"userid\"}" stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - NSString *responseString = [NSString stringWithFormat:@"[ {\"code\":200,\"body\": \"%@\" }, {\"code\":200,\"body\": \"%@\" } ]", meResponse, meResponse]; - NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; - return [OHHTTPStubsResponse responseWithData:data - statusCode:200 - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSString *meResponse = [@"{ \"id\":\"userid\"}" stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + NSString *responseString = [NSString stringWithFormat:@"[ {\"code\":200,\"body\": \"%@\" }, {\"code\":200,\"body\": \"%@\" } ]", meResponse, meResponse]; + NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; + return [OHHTTPStubsResponse responseWithData:data + statusCode:200 + headers:nil]; + }]; FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; __block int actualCallbacksCount = 0; XCTestExpectation *expectation = [self expectationWithDescription:@"expected to receive delegate completion"]; - [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] + [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { XCTAssertEqual(1, actualCallbacksCount++, @"this should have been the second callback"); }]; - [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] + [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { XCTAssertEqual(2, actualCallbacksCount++, @"this should have been the third callback"); }]; @@ -206,23 +202,23 @@ - (void)testConnectionDelegate - (void)testNonErrorEmptyDictionaryOrNullResponse { id mockPiggybackManager = [[self class] mockCachedServerConfiguration]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSString *responseString = [NSString stringWithFormat:@"[ {\"code\":200,\"body\": null }, {\"code\":200,\"body\": {} } ]"]; - NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; - return [OHHTTPStubsResponse responseWithData:data - statusCode:200 - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSString *responseString = [NSString stringWithFormat:@"[ {\"code\":200,\"body\": null }, {\"code\":200,\"body\": {} } ]"]; + NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; + return [OHHTTPStubsResponse responseWithData:data + statusCode:200 + headers:nil]; + }]; FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; __block int actualCallbacksCount = 0; XCTestExpectation *expectation = [self expectationWithDescription:@"expected not to crash on null or empty dict responses"]; - [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] + [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { XCTAssertEqual(1, actualCallbacksCount++, @"this should have been the second callback"); }]; - [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] + [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { XCTAssertEqual(2, actualCallbacksCount++, @"this should have been the third callback"); }]; @@ -246,15 +242,15 @@ - (void)testNonErrorEmptyDictionaryOrNullResponse - (void)testConnectionDelegateWithNetworkError { id mockPiggybackManager = [[self class] mockCachedServerConfiguration]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - // stub a response indicating a disconnected network - return [OHHTTPStubsResponse responseWithError:[NSError errorWithDomain:@"NSURLErrorDomain" code:-1009 userInfo:nil]]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + // stub a response indicating a disconnected network + return [OHHTTPStubsResponse responseWithError:[NSError errorWithDomain:@"NSURLErrorDomain" code:-1009 userInfo:nil]]; + }]; FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; XCTestExpectation *expectation = [self expectationWithDescription:@"expected to receive network error"]; - [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] + [connection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; self.requestConnectionCallback = ^(FBSDKGraphRequestConnection *conn, NSError *error) { NSCAssert(error != nil, @"didFinishLoading shouldn't have been called"); @@ -275,23 +271,23 @@ - (void)testTokenPiggyback id mockPiggybackManager = [[self class] mockCachedServerConfiguration]; [FBSDKAccessToken setCurrentAccessToken:nil]; // use stubs because test tokens are not refreshable. - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSString *meResponse = [@"{ \"id\":\"userid\"}" stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - NSString *refreshResponse = [[NSString stringWithFormat:@"{ \"access_token\":\"123\", \"expires_at\":%.0f }", [NSDate dateWithTimeIntervalSinceNow:60].timeIntervalSince1970] stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - NSString *permissionsResponse = [@"{ \"data\": [ { \"permission\" : \"public_profile\", \"status\" : \"granted\" }, { \"permission\" : \"email\", \"status\" : \"granted\" }, { \"permission\" : \"user_friends\", \"status\" : \"declined\" } ] }" stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; - NSString *responseString = [NSString stringWithFormat:@"[ {\"code\":200,\"body\": \"%@\" }," - @"{\"code\":200,\"body\": \"%@\" }," - @"{\"code\":200,\"body\": \"%@\" } ]", - meResponse, - refreshResponse, - permissionsResponse]; - NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; - return [OHHTTPStubsResponse responseWithData:data - statusCode:200 - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSString *meResponse = [@"{ \"id\":\"userid\"}" stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + NSString *refreshResponse = [[NSString stringWithFormat:@"{ \"access_token\":\"123\", \"expires_at\":%.0f }", [NSDate dateWithTimeIntervalSinceNow:60].timeIntervalSince1970] stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + NSString *permissionsResponse = [@"{ \"data\": [ { \"permission\" : \"public_profile\", \"status\" : \"granted\" }, { \"permission\" : \"email\", \"status\" : \"granted\" }, { \"permission\" : \"user_friends\", \"status\" : \"declined\" } ] }" stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + NSString *responseString = [NSString stringWithFormat:@"[ {\"code\":200,\"body\": \"%@\" }," + @"{\"code\":200,\"body\": \"%@\" }," + @"{\"code\":200,\"body\": \"%@\" } ]", + meResponse, + refreshResponse, + permissionsResponse]; + NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; + return [OHHTTPStubsResponse responseWithData:data + statusCode:200 + headers:nil]; + }]; FBSDKAccessToken *tokenThatNeedsRefresh = [[FBSDKAccessToken alloc] initWithTokenString:@"token" permissions:@[] @@ -303,7 +299,7 @@ - (void)testTokenPiggyback refreshDate:[NSDate distantPast] dataAccessExpirationDate:[NSDate distantPast]]; [FBSDKAccessToken setCurrentAccessToken:tokenThatNeedsRefresh]; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}]; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}]; XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { XCTAssertEqualObjects(tokenThatNeedsRefresh.userID, result[@"id"]); @@ -337,19 +333,19 @@ - (void)testTokenPiggybackSkipped refreshDate:[NSDate date] dataAccessExpirationDate:[NSDate distantPast]]; [FBSDKAccessToken setCurrentAccessToken:tokenNoRefresh]; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}]; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}]; XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *r) { - // assert the path of r is "me"; since piggyback would go to root batch endpoint. - XCTAssertTrue([r.URL.path hasSuffix:@"me"]); - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *r) { - NSString *responseString = @"{ \"id\" : \"userid\"}"; - NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; - return [OHHTTPStubsResponse responseWithData:data - statusCode:200 - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *r) { + // assert the path of r is "me"; since piggyback would go to root batch endpoint. + XCTAssertTrue([r.URL.path hasSuffix:@"me"]); + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *r) { + NSString *responseString = @"{ \"id\" : \"userid\"}"; + NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; + return [OHHTTPStubsResponse responseWithData:data + statusCode:200 + headers:nil]; + }]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { XCTAssertEqualObjects(tokenNoRefresh.userID, result[@"id"]); [exp fulfill]; @@ -368,7 +364,7 @@ - (void)testUnsettingAccessToken __block int tokenChangeCount = 0; [self expectationForNotification:FBSDKAccessTokenDidChangeNotification object:nil - handler:^BOOL(NSNotification *notification) { + handler:^BOOL (NSNotification *notification) { if (++tokenChangeCount == 2) { XCTAssertNil(notification.userInfo[FBSDKAccessTokenChangeNewKey]); XCTAssertNotNil(notification.userInfo[FBSDKAccessTokenChangeOldKey]); @@ -379,23 +375,23 @@ - (void)testUnsettingAccessToken FBSDKAccessToken *accessToken = [[FBSDKAccessToken alloc] initWithTokenString:@"token" permissions:@[@"public_profile"] declinedPermissions:@[] - expiredPermissions:@[] + expiredPermissions:@[] appID:@"appid" userID:@"userid" expirationDate:nil refreshDate:nil dataAccessExpirationDate:nil]; [FBSDKAccessToken setCurrentAccessToken:accessToken]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { XCTAssertNil(result); XCTAssertEqualObjects(@"Token is broke", error.userInfo[FBSDKErrorDeveloperMessageKey]); @@ -415,7 +411,7 @@ - (void)testUnsettingAccessTokenSkipped XCTestExpectation *expectation = [self expectationWithDescription:@"completed request"]; [self expectationForNotification:FBSDKAccessTokenDidChangeNotification object:nil - handler:^BOOL(NSNotification *notification) { + handler:^BOOL (NSNotification *notification) { XCTAssertNotNil(notification.userInfo[FBSDKAccessTokenChangeNewKey]); return YES; }]; @@ -430,17 +426,17 @@ - (void)testUnsettingAccessTokenSkipped dataAccessExpirationDate:nil]; [FBSDKAccessToken setCurrentAccessToken:accessToken]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" - parameters:@{@"fields":@""} + parameters:@{@"fields" : @""} tokenString:@"notCurrentToken" version:nil HTTPMethod:@""] @@ -463,7 +459,7 @@ - (void)testUnsettingAccessTokenFlag XCTestExpectation *expectation = [self expectationWithDescription:@"completed request"]; [self expectationForNotification:FBSDKAccessTokenDidChangeNotification object:nil - handler:^BOOL(NSNotification *notification) { + handler:^BOOL (NSNotification *notification) { XCTAssertNotNil(notification.userInfo[FBSDKAccessTokenChangeNewKey]); return YES; }]; @@ -478,16 +474,16 @@ - (void)testUnsettingAccessTokenFlag dataAccessExpirationDate:nil]; [FBSDKAccessToken setCurrentAccessToken:accessToken]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""} flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError] + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": {\"message\": \"Token is broke\",\"code\": 190,\"error_subcode\": 463}}" dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""} flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { XCTAssertNil(result); XCTAssertEqualObjects(@"Token is broke", error.userInfo[FBSDKErrorDeveloperMessageKey]); @@ -504,40 +500,40 @@ - (void)testUnsettingAccessTokenFlag - (void)testUserAgentSuffix { // Disable compressing network request - id mockUtility = [OCMockObject niceMockForClass:[FBSDKBasicUtility class]]; + id mockUtility = [OCMockObject niceMockForClass:[FBSDKBasicUtility class]]; [[[mockUtility stub] andReturn:nil] gzip:[OCMArg any]]; XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; XCTestExpectation *exp2 = [self expectationWithDescription:@"completed request 2"]; [FBSDKAccessToken setCurrentAccessToken:nil]; [FBSDKSettings setUserAgentSuffix:@"UnitTest.1.0.0"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - NSString *actualUserAgent = [request valueForHTTPHeaderField:@"User-Agent"]; - NSString *body = [[NSString alloc] initWithData:request.OHHTTPStubs_HTTPBody encoding:NSUTF8StringEncoding]; - if ([body containsString:@"with_suffix"] || [body containsString:@"without_suffix"]) { - BOOL expectUserAgentSuffix = [body containsString:@"fields=with_suffix"]; - if (expectUserAgentSuffix) { - XCTAssertTrue([actualUserAgent hasSuffix:@"/UnitTest.1.0.0"], @"unexpected user agent %@", actualUserAgent); - } else { - XCTAssertFalse([actualUserAgent hasSuffix:@"/UnitTest.1.0.0"], @"unexpected user agent %@", actualUserAgent); - } - } - - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": {\"message\": \"Missing oktne\",\"code\": 190, \"type\":\"OAuthException\"}}" dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@"with_suffix"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + NSString *actualUserAgent = [request valueForHTTPHeaderField:@"User-Agent"]; + NSString *body = [[NSString alloc] initWithData:request.OHHTTPStubs_HTTPBody encoding:NSUTF8StringEncoding]; + if ([body containsString:@"with_suffix"] || [body containsString:@"without_suffix"]) { + BOOL expectUserAgentSuffix = [body containsString:@"fields=with_suffix"]; + if (expectUserAgentSuffix) { + XCTAssertTrue([actualUserAgent hasSuffix:@"/UnitTest.1.0.0"], @"unexpected user agent %@", actualUserAgent); + } else { + XCTAssertFalse([actualUserAgent hasSuffix:@"/UnitTest.1.0.0"], @"unexpected user agent %@", actualUserAgent); + } + } + + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": {\"message\": \"Missing oktne\",\"code\": 190, \"type\":\"OAuthException\"}}" dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @"with_suffix"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { [exp fulfill]; }]; [FBSDKSettings setUserAgentSuffix:nil]; // issue a second request o verify clearing out of user agent suffix, passing a field=name to uniquely identify the request. - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@"without_suffix"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @"without_suffix"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { [exp2 fulfill]; }]; @@ -553,14 +549,14 @@ - (void)testNonDictionaryInError [FBSDKAccessToken setCurrentAccessToken:nil]; [FBSDKSettings setClientToken:@"clienttoken"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - NSData *data = [@"{\"error\": \"a-non-dictionary\"}" dataUsingEncoding:NSUTF8StringEncoding]; - return [OHHTTPStubsResponse responseWithData:data - statusCode:200 - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + NSData *data = [@"{\"error\": \"a-non-dictionary\"}" dataUsingEncoding:NSUTF8StringEncoding]; + return [OHHTTPStubsResponse responseWithData:data + statusCode:200 + headers:nil]; + }]; // adding fresh token to avoid piggybacking a token refresh FBSDKAccessToken *tokenNoRefresh = [[FBSDKAccessToken alloc] @@ -575,7 +571,7 @@ - (void)testNonDictionaryInError dataAccessExpirationDate:[NSDate distantPast]]; [FBSDKAccessToken setCurrentAccessToken:tokenNoRefresh]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { // should not crash when receiving something other than a dictionary within the response. [exp fulfill]; }]; @@ -593,21 +589,21 @@ - (void)testRetry id mockPiggybackManager = [[self class] mockCachedServerConfiguration]; __block int requestCount = 0; XCTestExpectation *expectation = [self expectationWithDescription:@"completed request"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - XCTAssertLessThanOrEqual(++requestCount, 2); - NSString *responseJSON = (requestCount == 1 ? - @"{\"error\": {\"message\": \"Server is busy\",\"code\": 1,\"error_subcode\": 463}}" - : @"{\"error\": {\"message\": \"Server is busy\",\"code\": 2,\"error_subcode\": 463}}" ); - NSData *data = [responseJSON dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - //verify we get the second error instance. + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + XCTAssertLessThanOrEqual(++requestCount, 2); + NSString *responseJSON = (requestCount == 1 + ? @"{\"error\": {\"message\": \"Server is busy\",\"code\": 1,\"error_subcode\": 463}}" + : @"{\"error\": {\"message\": \"Server is busy\",\"code\": 2,\"error_subcode\": 463}}"); + NSData *data = [responseJSON dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + // verify we get the second error instance. XCTAssertEqual(2, [error.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] integerValue]); [expectation fulfill]; }]; @@ -626,24 +622,24 @@ - (void)_testRetryDisabled __block int requestCount = 0; XCTestExpectation *expectation = [self expectationWithDescription:@"completed request"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - XCTAssertLessThanOrEqual(++requestCount, 1); - NSString *responseJSON = (requestCount == 1 ? - @"{\"error\": {\"message\": \"Server is busy\",\"code\": 1,\"error_subcode\": 463}}" - : @"{\"error\": {\"message\": \"Server is busy\",\"code\": 2,\"error_subcode\": 463}}" ); - NSData *data = [responseJSON dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:400 - headers:nil]; - }]; - - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""}]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + return YES; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + XCTAssertLessThanOrEqual(++requestCount, 1); + NSString *responseJSON = (requestCount == 1 + ? @"{\"error\": {\"message\": \"Server is busy\",\"code\": 1,\"error_subcode\": 463}}" + : @"{\"error\": {\"message\": \"Server is busy\",\"code\": 2,\"error_subcode\": 463}}"); + NSData *data = [responseJSON dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:400 + headers:nil]; + }]; + + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @""}]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - //verify we don't get the second error instance. + // verify we don't get the second error instance. XCTAssertEqual(1, [error.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] integerValue]); [expectation fulfill]; }]; @@ -656,40 +652,4 @@ - (void)_testRetryDisabled [mockPiggybackManager stopMocking]; } -//- (void)testGraphRequestWithIDFATrackingEnabled -//{ -// id mockUtility = [OCMockObject niceMockForClass:[FBSDKBasicUtility class]]; -// [[[mockUtility stub] andReturn:nil] gzip:[OCMArg any]]; -// [OCMStub(ClassMethod([_settingsMock isAdvertiserIDCollectionEnabled])) andReturnValue: OCMOCK_VALUE(YES)]; -// -// XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; -// -// [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// NSString *body = [[NSString alloc] initWithData:request.OHHTTPStubs_HTTPBody encoding:NSUTF8StringEncoding]; -// XCTAssertTrue([body containsString:_mockMobileAppInstallEventName]); -// XCTAssertTrue([body containsString:@"advertiser_tracking_enabled"]); -// XCTAssertTrue([body containsString:@"application_tracking_enabled"]); -// XCTAssertTrue([body containsString:@"advertiser_id"]); -// return NO; -// } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { -// return [OHHTTPStubsResponse responseWithData:[NSData data] -// statusCode:200 -// headers:nil]; -// }]; -// NSMutableDictionary *params = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:_mockMobileAppInstallEventName -// shouldAccessAdvertisingID:YES]; -// [[[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/activities", @"mockAppID"] -// parameters:params -// tokenString:nil -// HTTPMethod:FBSDKHTTPMethodPOST -// flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { -// [exp fulfill]; -// }]; -// -// [self waitForExpectationsWithTimeout:5 handler:^(NSError *error) { -// XCTAssertNil(error); -// }]; -// [mockUtility stopMocking]; -//} - @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m index ef2f052b69..cbd1988da1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m @@ -16,14 +16,13 @@ // 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 "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequest.h" -#import "FBSDKGraphRequestConnection+Internal.h" +#import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequestConnection.h" +#import "FBSDKGraphRequestConnection+Internal.h" #import "FBSDKGraphRequestDataAttachment.h" #import "FBSDKGraphRequestMetadata.h" #import "FBSDKInternalUtility.h" @@ -34,7 +33,7 @@ static NSString *const _mockPrefix = @"graph."; static NSDictionary *const _mockParameters(void) { - return @{@"fields":@""}; + return @{@"fields" : @""}; } static NSDictionary *const _mockEmptyParamter(void) @@ -67,20 +66,15 @@ - (void)testGraphRequestGETWithEmptyParameters FBSDKGraphRequest *request5 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodGET]; [_mockConnection addRequest:request1 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request2 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request3 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request4 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request5 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; for (FBSDKGraphRequestMetadata *metadata in _mockConnection.requests) { [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParamter() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodGET]; @@ -95,17 +89,13 @@ - (void)testGraphRequestGETWithNonEmptyParameters FBSDKGraphRequest *request4 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockParameters() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodGET]; [_mockConnection addRequest:request1 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request2 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request3 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request4 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; for (FBSDKGraphRequestMetadata *metadata in _mockConnection.requests) { [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockParameters() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodGET]; @@ -119,14 +109,11 @@ - (void)testGraphRequestPOSTWithEmptyParameters FBSDKGraphRequest *request3 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodPOST]; [_mockConnection addRequest:request1 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request2 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request3 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; for (FBSDKGraphRequestMetadata *metadata in _mockConnection.requests) { [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParamter() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodPOST]; @@ -139,11 +126,9 @@ - (void)testGraphRequestPOSTWithNonEmptyParameters FBSDKGraphRequest *request2 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockParameters() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodPOST]; [_mockConnection addRequest:request1 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request2 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { - }]; + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; for (FBSDKGraphRequestMetadata *metadata in _mockConnection.requests) { [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockParameters() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodPOST]; @@ -185,15 +170,19 @@ - (void)testIsAttachments XCTAssertTrue([FBSDKGraphRequest isAttachment:mockDataAttachments]); id mockString = [OCMockObject niceMockForClass:[NSString class]]; - XCTAssertTrue(![mockString isKindOfClass:[UIImage class]] && - ![mockString isKindOfClass:[NSData class]] && - ![mockString isKindOfClass:[FBSDKGraphRequestDataAttachment class]]); + XCTAssertTrue( + ![mockString isKindOfClass:[UIImage class]] + && ![mockString isKindOfClass:[NSData class]] + && ![mockString isKindOfClass:[FBSDKGraphRequestDataAttachment class]] + ); XCTAssertFalse([FBSDKGraphRequest isAttachment:mockString]); id mockDate = [OCMockObject niceMockForClass:[NSDate class]]; - XCTAssertTrue(![mockDate isKindOfClass:[UIImage class]] && - ![mockDate isKindOfClass:[NSData class]] && - ![mockDate isKindOfClass:[FBSDKGraphRequestDataAttachment class]]); + XCTAssertTrue( + ![mockDate isKindOfClass:[UIImage class]] + && ![mockDate isKindOfClass:[NSData class]] + && ![mockDate isKindOfClass:[FBSDKGraphRequestDataAttachment class]] + ); XCTAssertFalse([FBSDKGraphRequest isAttachment:mockDate]); } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m new file mode 100644 index 0000000000..5b4a73a7e8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -0,0 +1,342 @@ +// 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 "FBSDKCoreKit.h" +#import "FBSDKProfile.h" +#import "FBSDKProfile+Internal.h" +#import "FBSDKTestCase.h" +#import "SampleAccessToken.h" +#import "SampleUserProfile.h" + +@interface FBSDKSettings () ++ (NSString *)userAgentSuffix; ++ (void)setUserAgentSuffix:(NSString *)suffix; ++ (void)resetLoggingBehaviorsCache; ++ (void)resetFacebookAppIDCache; ++ (void)resetFacebookUrlSchemeSuffixCache; ++ (void)resetFacebookClientTokenCache; ++ (void)resetFacebookDisplayNameCache; ++ (void)resetFacebookDomainPartCache; ++ (void)resetFacebookJpegCompressionQualityCache; ++ (void)resetFacebookAutoInitEnabledCache; ++ (void)resetFacebookInstrumentEnabledCache; ++ (void)resetFacebookAutoLogAppEventsEnabledCache; ++ (void)resetFacebookAdvertiserIDCollectionEnabledCache; ++ (void)resetUserAgentSuffixCache; ++ (void)resetFacebookCodelessDebugLogEnabledCache; ++ (void)resetDataProcessingOptionsCache; +@end + +@interface FBSDKProfile (Testing) ++ (void)resetCurrentProfileCache; +@end + +@interface FBSDKProfileTests : FBSDKTestCase + +@end + +@implementation FBSDKProfileTests +{ + FBSDKProfile *_profile; + NSString *_sdkVersion; + CGSize _validNonSquareSize; + CGSize _validSquareSize; + NSString *_validClientToken; +} + +NSString *const accessTokenKey = @"access_token"; +NSString *const pictureModeKey = @"type"; +NSString *const widthKey = @"width"; +NSString *const heightKey = @"height"; + +- (void)setUp +{ + [super setUp]; + + _sdkVersion = @"100"; + _profile = SampleUserProfile.valid; + _validClientToken = @"Foo"; + _validSquareSize = CGSizeMake(100, 100); + _validNonSquareSize = CGSizeMake(10, 20); + + [self stubGraphAPIVersionWith:_sdkVersion]; + [self resetCaches]; +} + +- (void)tearDown +{ + [super tearDown]; + + [self resetCaches]; +} + +- (void)resetCaches +{ + [FBSDKProfile resetCurrentProfileCache]; + [FBSDKSettings resetFacebookClientTokenCache]; +} + +// MARK: - Creating Image URL + +- (void)testCreatingImageURL +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeNormal size:_validSquareSize]; + + NSString *expectedPath = [NSString stringWithFormat:@"/%@/%@/picture", _sdkVersion, _profile.userID]; + XCTAssertEqualObjects( + url.path, + expectedPath, + "Should add the graph api version and the identifier of the current user when creating a url for for fetching a profile image" + ); +} + +- (void)testCreatingImageURLWithNoAccessTokenNoClientToken +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeNormal size:_validSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"normal"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"100"], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingImageURLWithClientTokenNoAccessToken +{ + [self stubClientTokenWith:_validClientToken]; + + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeNormal size:_validSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"normal"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:accessTokenKey value:_validClientToken], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should use the current client token as the 'access token' when there is no true access token available" + ); +} + +- (void)testCreatingImageURLWithAccessTokenNoClientToken +{ + [self stubCurrentAccessTokenWith:SampleAccessToken.validToken]; + + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeNormal size:_validSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"normal"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:accessTokenKey value:SampleAccessToken.validToken.tokenString], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should use the current client token as the 'access token' when there is no true access token available" + ); +} + +- (void)testCreatingImageURLWithAccessTokenAndClientToken +{ + [self stubCurrentAccessTokenWith:SampleAccessToken.validToken]; + [self stubClientTokenWith:_validClientToken]; + + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeNormal size:_validSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"normal"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:accessTokenKey value:SampleAccessToken.validToken.tokenString], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should use the current access token as the 'access_token' parameter when available" + ); +} + +- (void)testCreatingEnumWithSmallMode +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeSmall size:_validNonSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"small"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"10"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"20"], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingEnumWithAlbumMode +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeAlbum size:_validNonSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"album"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"10"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"20"], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingEnumWithLargeMode +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeLarge size:_validNonSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"large"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"10"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"20"], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingEnumWithSquareMode +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeSquare size:_validNonSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"square"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"10"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"20"], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingImageURLWithUnknownMode +{ + NSURL *url = [_profile imageURLForPictureMode:400 size:_validSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"normal"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"100"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"100"], + ]]; + + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "The picture mode for an invalid enum value should default to 'normal'" + ); +} + +// MARK: - Size Validations + +- (void)testCreatingImageURLWithNoSize +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeNormal size:CGSizeZero]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"normal"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"0"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"0"], + ]]; + + XCTAssertNotNil(url, "Should not create a url for fetching a profile picture with zero size but it will"); + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingSquareImageURLWithNonSquareSize +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeSquare size:_validNonSquareSize]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"square"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"10"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"20"], + ]]; + + XCTAssertNotNil(url, "Should not create a url for a square image with non-square size but it will"); + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +- (void)testCreatingSquareImageURLWithNegativeSize +{ + NSURL *url = [_profile imageURLForPictureMode:FBSDKProfilePictureModeSquare size:CGSizeMake(-10, -10)]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true]; + + NSSet *expectedQueryItems = [NSSet setWithArray:@[ + [[NSURLQueryItem alloc] initWithName:pictureModeKey value:@"square"], + [[NSURLQueryItem alloc] initWithName:widthKey value:@"-10"], + [[NSURLQueryItem alloc] initWithName:heightKey value:@"-10"], + ]]; + + XCTAssertNotNil(url, "Should not create a url for a square image with a negative size but it will"); + XCTAssertEqualObjects( + [NSSet setWithArray:components.queryItems], + expectedQueryItems, + "Should add the expected query items to a url when creating a url for fetching a profile image" + ); +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m index 9df834cc9d..e687f0a589 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m @@ -26,19 +26,22 @@ @interface FBSDKUtilityTests : XCTestCase @implementation FBSDKUtilityTests -- (void)testSHA256Hash { +- (void)testSHA256Hash +{ NSString *hashed = [FBSDKUtility SHA256Hash:@"facebook"]; XCTAssertEqualObjects(hashed, @"3d59f7548e1af2151b64135003ce63c0a484c26b9b8b166a7b1c1805ec34b00a"); } -- (void)testURLDecodeShouldNotModifyUnencodedUrlString { +- (void)testURLDecodeShouldNotModifyUnencodedUrlString +{ NSString *unencoded = @"https://www.facebook.com/index.html?a=b&c=d"; XCTAssertEqualObjects(unencoded, [FBSDKUtility URLDecode:unencoded]); } -- (void)testURLEncode { +- (void)testURLEncode +{ NSString *unencoded = @"https://www.facebook.com/index.html?a=b&c=d"; NSString *encoded = @"https%3A%2F%2Fwww.facebook.com%2Findex.html%3Fa%3Db%26c%3Dd"; @@ -46,7 +49,8 @@ - (void)testURLEncode { XCTAssertEqualObjects(unencoded, [FBSDKUtility URLDecode:encoded]); } -- (void)testURLEncodeWithJSON { +- (void)testURLEncodeWithJSON +{ NSString *url = @"https://m.facebook.com/v3.2/dialog/oauth?auth_type=rerequest&client_id=123456789&default_audience=friends&display=touch&e2e={\"init\":123456.1234567890}&fbapp_pres=0&redirect_uri=fb111111111111111://authorize/&response_type=token,signed_request&return_scopes=true&scope=&sdk=ios&sdk_version=4.39.0&state={\"challenge\":\"aBcDeFghiJKlmnOpQRS%tU\",\"0_auth_logger_id\":\"01234ABC-12AB-34DE-1234-ABCDEFG12345\",\"com.facebook.some_identifier\":true,\"3_method\":\"sfvc_auth\"}"; NSString *encoded = @"https%3A%2F%2Fm.facebook.com%2Fv3.2%2Fdialog%2Foauth%3Fauth_type%3Drerequest%26client_id%3D123456789%26default_audience%3Dfriends%26display%3Dtouch%26e2e%3D%7B%22init%22%3A123456.1234567890%7D%26fbapp_pres%3D0%26redirect_uri%3Dfb111111111111111%3A%2F%2Fauthorize%2F%26response_type%3Dtoken%2Csigned_request%26return_scopes%3Dtrue%26scope%3D%26sdk%3Dios%26sdk_version%3D4.39.0%26state%3D%7B%22challenge%22%3A%22aBcDeFghiJKlmnOpQRS%25tU%22%2C%220_auth_logger_id%22%3A%2201234ABC-12AB-34DE-1234-ABCDEFG12345%22%2C%22com.facebook.some_identifier%22%3Atrue%2C%223_method%22%3A%22sfvc_auth%22%7D"; @@ -54,7 +58,8 @@ - (void)testURLEncodeWithJSON { XCTAssertEqualObjects(url, [FBSDKUtility URLDecode:encoded]); } -- (void)testNewEncodeWorksLikeLegacy { +- (void)testNewEncodeWorksLikeLegacy +{ for (int i = 0; i < 256; i++) { NSString *str = [NSString stringWithFormat:@"%c", (char)i]; if ([str isEqualToString:@"{"] || [str isEqualToString:@"}"]) { @@ -68,12 +73,15 @@ - (void)testNewEncodeWorksLikeLegacy { #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (NSString *)legacyURLEncode:(NSString *)value { - return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, - (CFStringRef)value, - NULL, // characters to leave unescaped - CFSTR(":!*();@/&?+$,='"), - kCFStringEncodingUTF8); + return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes( + NULL, + (CFStringRef)value, + NULL, // characters to leave unescaped + CFSTR(":!*();@/&?+$,='"), + kCFStringEncodingUTF8 + ); } + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Info.plist b/FBSDKCoreKit/FBSDKCoreKitTests/Info.plist index ba72822e87..d508ba9c00 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Info.plist +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Info.plist @@ -2,23 +2,34 @@ + CFBundleURLTypes + + + CFBundleURLSchemes + + example.com + + + CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) + com.facebook.sdk.FBSDKCoreKitTests CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + FBSDKCoreKitTests CFBundlePackageType BNDL CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion 1 + FacebookLoggingBehavior + + informational + diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m index fa29b20078..045f6d57e8 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m @@ -16,9 +16,8 @@ // 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 @@ -42,7 +41,8 @@ + (void)getMetadataWithText:(NSString *)text + (void)checkAndAppendData:(NSString *)data forKey:(NSString *)key; @end -@interface FBSDKMetadataIndexerTests : XCTestCase { +@interface FBSDKMetadataIndexerTests : XCTestCase +{ id _mockMetadataIndexer; UITextField *_emailField; UITextView *_emailView; @@ -60,39 +60,39 @@ - (void)setUp _mockMetadataIndexer = OCMClassMock([FBSDKMetadataIndexer class]); [FBSDKMetadataIndexer initStore]; [FBSDKMetadataIndexer constructRules:@{ - @"r1": @{ - @"k": @"email,e-mail,em,electronicmail", - @"v": @"^([A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})$", - }, - @"r2": @{ - @"k": @"phone,mobile,contact", - @"v": @"^([0-9]{5,15})$", - }, - @"r3": @{ - @"k": @"gender,gen,sex", - @"v": @"^(male|boy|man|female|girl|woman)$", - }, - @"r4": @{ - @"k": @"city", - @"v": @"", - }, - @"r5": @{ - @"k": @"state,province", - @"v": @"", - }, - @"r6": @{ - @"k": @"zip,zcode,pincode,pcode,postalcode,postcode", - @"v": @"(^\\d{5}$)|(^\\d{9}$)|(^\\d{5}-\\d{4}$)", - }, - @"r7": @{ - @"k": @"firstname,first name,fn,fname,givenname,forename", - @"v": @"", - }, - @"r8": @{ - @"k": @"lastname,last name,ln,lname,surname,sname,familyname", - @"v": @"", - }, - }]; + @"r1" : @{ + @"k" : @"email,e-mail,em,electronicmail", + @"v" : @"^([A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,})$", + }, + @"r2" : @{ + @"k" : @"phone,mobile,contact", + @"v" : @"^([0-9]{5,15})$", + }, + @"r3" : @{ + @"k" : @"gender,gen,sex", + @"v" : @"^(male|boy|man|female|girl|woman)$", + }, + @"r4" : @{ + @"k" : @"city", + @"v" : @"", + }, + @"r5" : @{ + @"k" : @"state,province", + @"v" : @"", + }, + @"r6" : @{ + @"k" : @"zip,zcode,pincode,pcode,postalcode,postcode", + @"v" : @"(^\\d{5}$)|(^\\d{9}$)|(^\\d{5}-\\d{4}$)", + }, + @"r7" : @{ + @"k" : @"firstname,first name,fn,fname,givenname,forename", + @"v" : @"", + }, + @"r8" : @{ + @"k" : @"lastname,last name,ln,lname,surname,sname,familyname", + @"v" : @"", + }, + }]; _emailField = [[UITextField alloc] init]; _emailField.placeholder = @"Enter your email"; @@ -122,20 +122,26 @@ - (void)tearDown - (void)testCheckSecureTextEntryOfTextField { // without secure text - XCTAssertFalse([FBSDKMetadataIndexer checkSecureTextEntry:_emailField], - @"test for UITextField without secure text"); + XCTAssertFalse( + [FBSDKMetadataIndexer checkSecureTextEntry:_emailField], + @"test for UITextField without secure text" + ); // with secure text - XCTAssertTrue([FBSDKMetadataIndexer checkSecureTextEntry:_pwdField], - @"test for UITextField with secure text"); + XCTAssertTrue( + [FBSDKMetadataIndexer checkSecureTextEntry:_pwdField], + @"test for UITextField with secure text" + ); } // test for geting secure text entry in UITextView - (void)testCheckSecureTextEntryOfTextView { // without secure text - XCTAssertFalse([FBSDKMetadataIndexer checkSecureTextEntry:_emailView], - @"test for UITextView without secure text"); + XCTAssertFalse( + [FBSDKMetadataIndexer checkSecureTextEntry:_emailView], + @"test for UITextView without secure text" + ); // with secure text XCTAssertTrue([FBSDKMetadataIndexer checkSecureTextEntry:_pwdView], @"test for UITextView with secure text"); @@ -144,17 +150,21 @@ - (void)testCheckSecureTextEntryOfTextView // test for geting keyboard type from UITextField - (void)testGetKeyboardTypeOfTextField { - XCTAssertEqual(_emailField.keyboardType, - [FBSDKMetadataIndexer getKeyboardType:_emailField], - @"test for geting keyboard type from UITextField"); + XCTAssertEqual( + _emailField.keyboardType, + [FBSDKMetadataIndexer getKeyboardType:_emailField], + @"test for geting keyboard type from UITextField" + ); } // test for geting keyboard type from UITextView - (void)testGetKeyboardTypeOfTextView { - XCTAssertEqual(_emailView.keyboardType, - [FBSDKMetadataIndexer getKeyboardType:_emailView], - @"test for geting keyboard type from UITextView"); + XCTAssertEqual( + _emailView.keyboardType, + [FBSDKMetadataIndexer getKeyboardType:_emailView], + @"test for geting keyboard type from UITextView" + ); } // test for geting metadata with valid email @@ -307,7 +317,7 @@ - (void)testGetMetadataWithNoText // test for geting metadata with too long text - (void)testGetMetadataWithTooLongText { - NSString *text = [NSString stringWithFormat:@"%@%@", [@"" stringByPaddingToLength:1000 withString: @"a" startingAtIndex:0], @"@fb.com"]; + NSString *text = [NSString stringWithFormat:@"%@%@", [@"" stringByPaddingToLength:1000 withString:@"a" startingAtIndex:0], @"@fb.com"]; [FBSDKMetadataIndexer getMetadataWithText:text placeholder:@"Enter your Email" labels:nil @@ -321,7 +331,7 @@ - (void)testGetMetadataWithTooLongText - (void)testGetMetadataWithTooLongPlaceholder { NSString *text = @"test@fb.com"; - NSString *indicator = [NSString stringWithFormat:@"%@", [@"" stringByPaddingToLength:1000 withString: @"enter your email " startingAtIndex:0]]; + NSString *indicator = [NSString stringWithFormat:@"%@", [@"" stringByPaddingToLength:1000 withString:@"enter your email " startingAtIndex:0]]; [FBSDKMetadataIndexer getMetadataWithText:text placeholder:indicator labels:nil diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m index fe96e794d7..fac505ad75 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m @@ -19,12 +19,13 @@ #import #import "FBSDKCodelessParameterComponent.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKEventBinding.h" #import "FBSDKEventBindingManager.h" #import "FBSDKSampleEventBinding.h" -#import "FBSDKCoreKitTests-Swift.h" -@interface FBSDKEventBindingTests : XCTestCase { +@interface FBSDKEventBindingTests : XCTestCase +{ UIWindow *window; FBSDKEventBindingManager *eventBindingManager; UIButton *btnBuy; @@ -34,7 +35,7 @@ @interface FBSDKEventBindingTests : XCTestCase { @end -@interface FBSDKEventBinding(Testing) +@interface FBSDKEventBinding (Testing) + (NSString *)findParameterOfPath:(NSArray *)path pathType:(NSString *)pathType @@ -44,7 +45,8 @@ + (NSString *)findParameterOfPath:(NSArray *)path @implementation FBSDKEventBindingTests -- (void)setUp { +- (void)setUp +{ [super setUp]; if (@available(iOS 9.0, *)) { @@ -84,12 +86,14 @@ - (void)setUp { } } -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; +- (void)tearDown +{ + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; } -- (void)testMatching { +- (void)testMatching +{ NSArray *bindings = [FBSDKEventBindingManager parseArray:[FBSDKSampleEventBinding getSampleDictionary][@"event_bindings"]]; FBSDKEventBinding *binding = bindings[0]; XCTAssertTrue([FBSDKEventBinding isViewMatchPath:stepper path:binding.path]); @@ -97,7 +101,7 @@ - (void)testMatching { binding = bindings[1]; FBSDKCodelessParameterComponent *component = binding.parameters[0]; XCTAssertTrue([FBSDKEventBinding isViewMatchPath:btnBuy path:binding.path]); - NSString *price = [FBSDKEventBinding findParameterOfPath:component.path pathType:component.pathType sourceView:btnBuy]; + NSString *price = [FBSDKEventBinding findParameterOfPath:component.path pathType:component.pathType sourceView:btnBuy]; XCTAssertEqual(price, @"$2.0"); binding = bindings[2]; @@ -110,7 +114,8 @@ - (void)testMatching { XCTAssertEqual(action, @"Confirm"); } -- (void)testEventBindingEquation { +- (void)testEventBindingEquation +{ NSArray *bindings = [FBSDKEventBindingManager parseArray:[FBSDKSampleEventBinding getSampleDictionary][@"event_bindings"]]; XCTAssertTrue([bindings[0] isEqualToBinding:bindings[0]]); XCTAssertFalse([bindings[0] isEqualToBinding:bindings[1]]); @@ -120,7 +125,7 @@ - (void)testParsing { for (int i = 0; i < 1000; i++) { NSDictionary *sampleData = [FBSDKSampleEventBinding getSampleDictionary]; - [FBSDKEventBindingManager parseArray: @[[Fuzzer randomizeWithJson:sampleData]]]; + [FBSDKEventBindingManager parseArray:@[[Fuzzer randomizeWithJson:sampleData]]]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h index 8fab3f1cec..9cc8c475b8 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h @@ -19,5 +19,5 @@ #import @interface FBSDKSampleEventBinding : NSObject -+(NSDictionary*)getSampleDictionary; ++ (NSDictionary *)getSampleDictionary; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m index b212a62bf6..87da087c93 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m @@ -19,122 +19,123 @@ #import "FBSDKSampleEventBinding.h" @implementation FBSDKSampleEventBinding -+(NSDictionary*)getSampleDictionary ++ (NSDictionary *)getSampleDictionary { return @{ - @"event_bindings": @[ - @{ - @"event_name": @"Quantity Changed", - @"event_type": @"click", - @"app_version": @"1.2", - @"path": @[ - @{ - @"class_name":@"UIWindow", - }, - @{ - @"class_name":@"UITabBarController", - }, - @{ - @"class_name":@"UINavigationController", - }, - @{ - @"class_name":@"UIViewController", - }, - @{ - @"class_name":@"UIStackView", - }, - @{ - @"class_name":@"UIStackView", - }, - @{ - @"class_name":@"UIStepper", - } - ] - }, - @{ - @"event_name": @"Add To Cart", - @"event_type": @"click", - @"app_version": @"1.2", - @"path": @[ - @{ - @"class_name":@"UIViewController", - }, - @{ - @"class_name":@"UIStackView", - }, - @{ - @"class_name":@"UIButton", - @"text": @"Buy" - } - ], - @"parameters": @[ - @{ - @"parameter_name": @"price", - @"path_type": @"relative", - @"path": @[ - @{ - @"class_name": @"..", - }, - @{ - @"class_name": @"UILabel", - @"index": @2, - }, - ] - } - ] - }, - @{ - @"event_name": @"Purchase", - @"event_type": @"click", - @"app_version": @"1.2", - @"path": @[ - @{ - @"class_name":@"UIWindow", - }, - @{ - @"class_name":@"UITabBarController", - }, - @{ - @"class_name":@"UINavigationController", - }, - @{ - @"class_name":@"UIViewController", - }, - @{ - @"class_name":@"UIStackView", - }, - @{ - @"class_name": @"UIButton", - @"text": @"Confirm" - }, - ], - @"parameters": @[ - @{ - @"parameter_name":@"price", - @"path_type": @"relative", - @"path": @[ - @{ - @"class_name":@"..", - }, - @{ - @"class_name":@"UIStackView", - }, - @{ - @"class_name":@"UILabel", - @"index": @0, - } - ] - }, - @{ - @"parameter_name": @"action", - @"path_type": @"relative", - @"path": @[ - @{@"class_name": @"."} - ], - }, - ] - } - ], - }; + @"event_bindings" : @[ + @{ + @"event_name" : @"Quantity Changed", + @"event_type" : @"click", + @"app_version" : @"1.2", + @"path" : @[ + @{ + @"class_name" : @"UIWindow", + }, + @{ + @"class_name" : @"UITabBarController", + }, + @{ + @"class_name" : @"UINavigationController", + }, + @{ + @"class_name" : @"UIViewController", + }, + @{ + @"class_name" : @"UIStackView", + }, + @{ + @"class_name" : @"UIStackView", + }, + @{ + @"class_name" : @"UIStepper", + } + ] + }, + @{ + @"event_name" : @"Add To Cart", + @"event_type" : @"click", + @"app_version" : @"1.2", + @"path" : @[ + @{ + @"class_name" : @"UIViewController", + }, + @{ + @"class_name" : @"UIStackView", + }, + @{ + @"class_name" : @"UIButton", + @"text" : @"Buy" + } + ], + @"parameters" : @[ + @{ + @"parameter_name" : @"price", + @"path_type" : @"relative", + @"path" : @[ + @{ + @"class_name" : @"..", + }, + @{ + @"class_name" : @"UILabel", + @"index" : @2, + }, + ] + } + ] + }, + @{ + @"event_name" : @"Purchase", + @"event_type" : @"click", + @"app_version" : @"1.2", + @"path" : @[ + @{ + @"class_name" : @"UIWindow", + }, + @{ + @"class_name" : @"UITabBarController", + }, + @{ + @"class_name" : @"UINavigationController", + }, + @{ + @"class_name" : @"UIViewController", + }, + @{ + @"class_name" : @"UIStackView", + }, + @{ + @"class_name" : @"UIButton", + @"text" : @"Confirm" + }, + ], + @"parameters" : @[ + @{ + @"parameter_name" : @"price", + @"path_type" : @"relative", + @"path" : @[ + @{ + @"class_name" : @"..", + }, + @{ + @"class_name" : @"UIStackView", + }, + @{ + @"class_name" : @"UILabel", + @"index" : @0, + } + ] + }, + @{ + @"parameter_name" : @"action", + @"path_type" : @"relative", + @"path" : @[ + @{@"class_name" : @"."} + ], + }, + ] + } + ], + }; } + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m index 7edb8d459f..273c3efc44 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m @@ -16,13 +16,12 @@ // 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 "FBSDKServerConfigurationManager.h" -#import "FBSDKRestrictiveDataFilterManager.h" #import "FBSDKEventDeactivationManager.h" +#import "FBSDKRestrictiveDataFilterManager.h" +#import "FBSDKServerConfigurationManager.h" @interface FBSDKEventDeactivationTests : XCTestCase @end @@ -50,8 +49,7 @@ - (void)testProcessParameters @"_logTime" : @1576109848, @"_session_id" : @"30AF582C-0225-40A4-B3EE-2A571AB926F3", @"fb_mobile_launch_source" : @"Unclassified", - @"deprecated_3" : @"test", - }; + @"deprecated_3" : @"test", }; NSDictionary *result = [FBSDKEventDeactivationManager processParameters:parameters eventName:@"manual_initiated_checkout"]; XCTAssertNil(result[@"deprecated_3"]); XCTAssertNotNil(result[@"_ui"]); @@ -61,4 +59,3 @@ - (void)testProcessParameters } @end - diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.h new file mode 100644 index 0000000000..85d19c5903 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.h @@ -0,0 +1,36 @@ +// 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 "FBSDKAppEventsConfiguration.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKAppEventsConfigurationFixtures : NSObject + +/// A default configuration with valid inputs. This is the same default configuration used in production code ++ (FBSDKAppEventsConfiguration *)defaultConfig; + +/// A default configuration with custom values passed by dictionary. +/// To use: Include a dictionary with the keys and values you want to override on the default configuration ++ (FBSDKAppEventsConfiguration *)configWithDictionary:(NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.m new file mode 100644 index 0000000000..84d12e6576 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationFixtures.m @@ -0,0 +1,61 @@ +// 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 "FBSDKAppEventsConfigurationFixtures.h" + +#import "FBSDKAppEventsConfiguration.h" + +@interface FBSDKAppEventsConfiguration (Testing) + ++ (FBSDKAppEventsConfiguration *)defaultConfiguration; + +- (instancetype)initWithDefaultATEStatus:(FBSDKAdvertisingTrackingStatus)defaultATEStatus + advertiserIDCollectionEnabled:(BOOL)advertiserIDCollectionEnabled + eventCollectionEnabled:(BOOL)eventCollectionEnabled; + +@end + +@implementation FBSDKAppEventsConfigurationFixtures + ++ (FBSDKAppEventsConfiguration *)defaultConfig; +{ + return [FBSDKAppEventsConfiguration defaultConfiguration]; +} + ++ (FBSDKAppEventsConfiguration *)configWithDictionary:(NSDictionary *)dict +{ + FBSDKAppEventsConfiguration *defaultConfig = [FBSDKAppEventsConfiguration defaultConfiguration]; + FBSDKAdvertisingTrackingStatus defaultATEStatus = defaultConfig.defaultATEStatus; + if (dict[@"default_ate_status"]) { + defaultATEStatus = [dict[@"default_ate_status"] intValue]; + } + BOOL advertiserIDCollectionEnabled = defaultConfig.advertiserIDCollectionEnabled; + if (dict[@"advertiser_id_collection_enabled"]) { + advertiserIDCollectionEnabled = [dict[@"advertiser_id_collection_enabled"] boolValue]; + } + BOOL eventCollectionEnabled = defaultConfig.eventCollectionEnabled; + if (dict[@"event_collection_enabled"]) { + eventCollectionEnabled = [dict[@"event_collection_enabled"] boolValue]; + } + return [[FBSDKAppEventsConfiguration alloc] + initWithDefaultATEStatus:defaultATEStatus + advertiserIDCollectionEnabled:advertiserIDCollectionEnabled + eventCollectionEnabled:eventCollectionEnabled]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m new file mode 100644 index 0000000000..e80d79a59e --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m @@ -0,0 +1,47 @@ +// 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 "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitTests-Swift.h" + +@interface FBSDKAppEventsConfigurationManager (Testing) + ++ (void)_processResponse:(id)response + error:(NSError *)error; + +@end + +@interface FBSDKAppEventsConfigurationManagerTests : XCTestCase + +@end + +@implementation FBSDKAppEventsConfigurationManagerTests + +- (void)testParsingResponses +{ + for (int i = 0; i < 1000; i++) { + [FBSDKAppEventsConfigurationManager _processResponse:RawAppEventsConfigurationResponseFixtures.random error:nil]; + } +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m new file mode 100644 index 0000000000..3ae8c05f5f --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m @@ -0,0 +1,95 @@ +// 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 "FBSDKAppEventsConfigurationFixtures.h" +#import "FBSDKCoreKit+Internal.h" + +@interface FBSDKAppEventsConfigurationTests : XCTestCase + +@end + +@implementation FBSDKAppEventsConfigurationTests +{ + FBSDKAppEventsConfiguration *config; +} + +typedef FBSDKAppEventsConfigurationFixtures Fixtures; + +- (void)setUp +{ + [super setUp]; + + config = [Fixtures defaultConfig]; +} + +- (void)tearDown +{ + [super tearDown]; + + config = nil; +} + +- (void)testCreatingWithDefaultATEStatus +{ + XCTAssertEqual(config.defaultATEStatus, FBSDKAdvertisingTrackingUnspecified, "Default ATE Status should be unspecified"); +} + +- (void)testCreatingWithKnownDefaultATEStatus +{ + config = [Fixtures configWithDictionary:@{@"default_ate_status" : @(FBSDKAdvertisingTrackingAllowed)}]; + XCTAssertEqual(config.defaultATEStatus, FBSDKAdvertisingTrackingAllowed, "Default ATE Status should be settable"); +} + +- (void)testCreatingWithDefaultAdvertisingIDCollectionEnabled +{ + XCTAssertTrue( + config.advertiserIDCollectionEnabled, + "Advertising identifier collection enabled should default to true" + ); +} + +- (void)testCreatingWithKnownAdvertisingIDCollectionEnabled +{ + config = [Fixtures configWithDictionary:@{@"advertiser_id_collection_enabled" : @(NO)}]; + XCTAssertFalse( + config.advertiserIDCollectionEnabled, + "Advertising identifier collection enabled should be settable" + ); +} + +- (void)testCreatingWithDefaultEventCollectionEnabled +{ + XCTAssertFalse( + config.eventCollectionEnabled, + "Event collection enabled should default to false" + ); +} + +- (void)testCreatingWithKnownEventCollectionEnabled +{ + config = [Fixtures configWithDictionary:@{@"event_collection_enabled" : @(YES)}]; + XCTAssertTrue( + config.eventCollectionEnabled, + "Event collection enabled should be settable" + ); +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m index 26c99c6898..33cf86b2e3 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m @@ -16,113 +16,446 @@ // 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 "FBSDKAppEventsState.h" -#import "FBSDKBasicUtility.h" +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKInternalUtility.h" +#import "FBSDKTestCase.h" +#import "SampleAppEvents.h" #define FBSDK_APPEVENTSSTATE_MAX_EVENTS 1000 -@interface FBSDKAppEventsStateTests : XCTestCase +@interface FBSDKAppEventsStateTests : FBSDKTestCase @end @implementation FBSDKAppEventsStateTests +{ + FBSDKAppEventsState *_state; + FBSDKAppEventsState *_partiallyFullState; + FBSDKAppEventsState *_fullState; +} -- (void)testAppEventsStateAddSimple +- (void)setUp { - FBSDKAppEventsState *target = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - XCTAssertEqual(0, target.events.count); - XCTAssertEqual(0, target.numSkipped); - XCTAssertTrue([target areAllEventsImplicit]); + [super setUp]; - [target addEvent:@{ @"event1" : @1 } isImplicit:YES]; - XCTAssertEqual(1, target.events.count); - XCTAssertEqual(0, target.numSkipped); - XCTAssertTrue([target areAllEventsImplicit]); + [self.appEventStatesMock stopMocking]; + [self setUpFixtures]; +} - [target addEvent:@{ @"event2" : @2 } isImplicit:NO]; - XCTAssertEqual(2, target.events.count); - XCTAssertEqual(0, target.numSkipped); - XCTAssertFalse([target areAllEventsImplicit]); +- (void)setUpFixtures +{ + _state = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + XCTAssertEqual(0, _state.events.count, "sanity check"); - NSString *expectedJSON = @"[{\"event1\":1},{\"event2\":2}]"; - XCTAssertEqualObjects(expectedJSON, [target JSONStringForEvents:YES]); + _partiallyFullState = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + [_partiallyFullState addEvent:SampleAppEvents.validEvent isImplicit:NO]; + XCTAssertEqual(1, _partiallyFullState.events.count, "sanity check"); - FBSDKAppEventsState *copy = [target copy]; - [copy addEvent:@{ @"copy1" : @3 } isImplicit:YES]; - XCTAssertEqual(2, target.events.count); - XCTAssertEqual(3, copy.events.count); + _fullState = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + for (size_t i = 0; i < FBSDK_APPEVENTSSTATE_MAX_EVENTS; ++i) { + [_fullState addEvent:SampleAppEvents.validEvent isImplicit:NO]; + } + XCTAssertEqual(FBSDK_APPEVENTSSTATE_MAX_EVENTS, _fullState.events.count, "sanity check"); +} - [target addEventsFromAppEventState:copy]; - XCTAssertEqual(5, target.events.count); - XCTAssertFalse([target areAllEventsImplicit]); +- (void)testDefaults +{ + XCTAssertEqual(0, _state.events.count, "Should have no events by default"); + XCTAssertEqual(0, _state.numSkipped, "Should have no skipped events by default"); + XCTAssertTrue( + [_state areAllEventsImplicit], + "Should consider all events to be implicit when there are no events" + ); } -- (void)testisCompatibleWithAppEventsState1 +- (void)testCreatingWithNilTokenNilAppID { - FBSDKAppEventsState *eventState = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - FBSDKAppEventsState *target1 = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - XCTAssertTrue([eventState isCompatibleWithAppEventsState:target1]); + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:nil appID:nil], + "Should not create app events state with missing token and app id but you can" + ); +} - FBSDKAppEventsState *target2 = [[FBSDKAppEventsState alloc] initWithToken:@"token1" appID:@"app"]; - XCTAssertFalse([eventState isCompatibleWithAppEventsState:target2]); +- (void)testCreatingWithNilTokenInvalidAppID +{ + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:nil appID:@""], + "Should not create app events state with missing token and empty app id but you can" + ); + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:nil appID:@" "], + "Should not create app events state with missing token and whitespace only app id but you can" + ); } -- (void)testIsCompatibleWithAppEventsState2 +- (void)testCreatingWithNilTokenValidAppID { - FBSDKAppEventsState *target = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:nil appID:self.appID], + "Should not create app events state with missing token and valid app id but you can" + ); +} - FBSDKAppEventsState *testTarget1 = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:nil]; - FBSDKAppEventsState *testTarget2 = [[FBSDKAppEventsState alloc] initWithToken:nil appID:@"app"]; - FBSDKAppEventsState *testTarget3 = [[FBSDKAppEventsState alloc] initWithToken:nil appID:nil]; - FBSDKAppEventsState *testTarget4 = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; +- (void)testCreatingWithInvalidTokenNilAppID +{ + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:@"" appID:nil], + "Should not create app events state with empty token and missing app id but you can" + ); + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:@" " appID:nil], + "Should not create app events state with whitespace only token and missing app id but you can" + ); +} - XCTAssertFalse([target isCompatibleWithAppEventsState: testTarget1]); - XCTAssertFalse([target isCompatibleWithAppEventsState: testTarget2]); - XCTAssertFalse([target isCompatibleWithAppEventsState: testTarget3]); - XCTAssertTrue([target isCompatibleWithAppEventsState: testTarget4]); +- (void)testCreatingWithInvalidTokenInvalidAppID +{ + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:@"" appID:@""], + "Should not create app events state with invalid token and invalid app id but you can" + ); } -- (void)testAddEvent +- (void)testCreatingWithInvalidTokenValidAppID { - FBSDKAppEventsState *target = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - for(size_t i = 0; i < FBSDK_APPEVENTSSTATE_MAX_EVENTS; ++i) { - [target addEvent:@{} isImplicit:NO]; - } - [target addEvent:@{} isImplicit:NO]; - XCTAssertEqual(1, target.numSkipped); + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:@"" appID:self.appID], + "Should not create app events state with empty token and valid app id but you can" + ); + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:@" " appID:nil], + "Should not create app events state with whitespace only token and valid app id but you can" + ); +} + +- (void)testCreatingWithValidTokenNilAppID +{ + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:self.name appID:nil], + "Should not create app events state with valid token and missing app id but you can" + ); +} + +- (void)testCreatingWithValidTokenInvalidAppID +{ + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:self.name appID:@""], + "Should not create app events state with valid token and empty app id but you can" + ); + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:self.name appID:@" "], + "Should not create app events state with valid token and whitespace only app id but you can" + ); +} + +- (void)testCreatingWithValidTokenValidAppID +{ + XCTAssertNotNil( + [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID], + "Should be able to create app events state with valid token and app id" + ); +} + +// MARK: - Adding Events + +- (void)testAddingDuplicateEvents +{ + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + + XCTAssertEqual(2, _state.events.count, "Should be able to add duplicate events"); + XCTAssertEqual(0, _state.numSkipped, "Should not skip valid events"); +} + +- (void)testAddingSingleImplicitEvent +{ + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + + XCTAssertEqual(1, _state.events.count, "Should be able to add a valid event"); + XCTAssertEqual(0, _state.numSkipped, "Should not skip valid events"); + XCTAssertTrue( + [_state areAllEventsImplicit], + "Should consider all events to be implicit when all events were added as implicit" + ); } -- (void)testAddEventsFromAppEventState +- (void)testAddingMultipleImplicitEvents { - FBSDKAppEventsState *target = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - for(size_t i = 0; i < FBSDK_APPEVENTSSTATE_MAX_EVENTS * 2; ++i) { - [target addEvent:@{} isImplicit:NO]; + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + [_state addEvent:[SampleAppEvents validEventWithName:@"event2"] isImplicit:YES]; + + XCTAssertEqual(2, _state.events.count, "Should be able to add multiple valid events"); + XCTAssertEqual(0, _state.numSkipped, "Should not skip valid events"); + XCTAssertTrue( + [_state areAllEventsImplicit], + "Should consider all events to be implicit when all events were added as implicit" + ); +} + +- (void)testAddingSingleNonImplicitEvents +{ + [_state addEvent:SampleAppEvents.validEvent isImplicit:NO]; + + XCTAssertEqual(1, _state.events.count, "Should be able to add a valid event"); + XCTAssertEqual(0, _state.numSkipped, "Should not skip valid events"); + XCTAssertFalse( + [_state areAllEventsImplicit], + "Should not consider all events to be implicit when no events were added as implicit" + ); +} + +- (void)testAddingMultipleNonImplicitEvents +{ + [_state addEvent:SampleAppEvents.validEvent isImplicit:NO]; + [_state addEvent:[SampleAppEvents validEventWithName:@"event2"] isImplicit:NO]; + + XCTAssertEqual(2, _state.events.count, "Should be able to add multiple valid events"); + XCTAssertEqual(0, _state.numSkipped, "Should not skip valid events"); + XCTAssertFalse( + [_state areAllEventsImplicit], + "Should not consider all events to be implicit when no events were added as implicit" + ); +} + +- (void)testAddingMixtureOfImplicitNonImplicitEvents +{ + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + [_state addEvent:[SampleAppEvents validEventWithName:@"event2"] isImplicit:NO]; + + XCTAssertEqual(2, _state.events.count, "Should be able to mix implicit and explicit events"); + XCTAssertEqual(0, _state.numSkipped, "Should not skip valid events"); + XCTAssertFalse( + [_state areAllEventsImplicit], + "Should not consider all events to be implicit when at least one event is non-implicit" + ); +} + +- (void)testAddingEventAtMaxCapacity +{ + [_fullState addEvent:SampleAppEvents.validEvent isImplicit:NO]; + [_fullState addEvent:SampleAppEvents.validEvent isImplicit:NO]; + + XCTAssertEqual(2, _fullState.numSkipped, "Should skip any events added after the max size is reached"); +} + +// MARK: - Events from AppEventState + +- (void)testAddingEventsToDuplicateEvents +{ + [_partiallyFullState addEventsFromAppEventState:_partiallyFullState]; + + XCTAssertEqual(2, _partiallyFullState.events.count, "Duplicate event states should not be addable but they are"); + XCTAssertEqual(0, _partiallyFullState.numSkipped, "Duplicate event states should not be addable but they are"); +} + +- (void)testAddingEventsFromEmptyStateToEmptyState +{ + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + + [_state addEventsFromAppEventState:state2]; + + XCTAssertEqual(0, _state.events.count, "Adding an empty state to an empty state should have no effect"); + XCTAssertEqual(0, _state.numSkipped, "Adding an empty state to an empty state should have no effect"); +} + +- (void)testAddEventsFromFullStateToEmptyState +{ + [_state addEventsFromAppEventState:_fullState]; + + XCTAssertEqual( + FBSDK_APPEVENTSSTATE_MAX_EVENTS, + _state.events.count, + "Should add all the events from the other state" + ); + XCTAssertEqual( + 0, + _state.numSkipped, + "Should not skip events when there is room in the state to hold them" + ); +} + +- (void)testAddEventsFromEmptyStateToPartiallyFilledState +{ + FBSDKAppEventsState *emptyState = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + + [_state addEventsFromAppEventState:emptyState]; + + XCTAssertEqual(1, _state.events.count, "Adding an empty state to a partially filled state should have no effect"); + XCTAssertEqual(0, _state.numSkipped, "Adding an empty state to a partially filled state should have no effect"); +} + +- (void)testAddEventsFromPartiallyFilledStateToEmptyState +{ + [_state addEventsFromAppEventState:_partiallyFullState]; + + XCTAssertEqual(1, _state.events.count, "Should add all the events in the partially filled state to the empty state"); + XCTAssertEqual(0, _state.numSkipped, "Adding a partially filled state to an empty state should have no effect"); +} + +- (void)testAddEventsFromPartiallyFilledStateToFullState +{ + [_fullState addEventsFromAppEventState:_partiallyFullState]; + + XCTAssertEqual(FBSDK_APPEVENTSSTATE_MAX_EVENTS, _fullState.events.count, "Adding to a full state should have no effect on the event count"); + XCTAssertEqual(1, _fullState.numSkipped, "Should skip events in excess of a state's capacity"); +} + +- (void)testAddEventsFromFullStateToPartiallyFilledState +{ + [_partiallyFullState addEventsFromAppEventState:_fullState]; + + XCTAssertEqual( + FBSDK_APPEVENTSSTATE_MAX_EVENTS, + _partiallyFullState.events.count, + "Adding a full state to a partially filled state should add as many events as possible" + ); + XCTAssertEqual(1, _partiallyFullState.numSkipped, "Should skip events in excess of a state's capacity"); +} + +- (void)testAddEventsFromFullStateToFullState +{ + FBSDKAppEventsState *otherFullState = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + + for (size_t i = 0; i < FBSDK_APPEVENTSSTATE_MAX_EVENTS * 2; ++i) { + [otherFullState addEvent:SampleAppEvents.validEvent isImplicit:NO]; } - FBSDKAppEventsState *event = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - [event addEvent:@{} isImplicit:NO]; - [target addEventsFromAppEventState:event]; - XCTAssertEqual(FBSDK_APPEVENTSSTATE_MAX_EVENTS + 1, target.numSkipped); - XCTAssertEqual(FBSDK_APPEVENTSSTATE_MAX_EVENTS, target.events.count); + [_fullState addEventsFromAppEventState:otherFullState]; + + XCTAssertEqual( + FBSDK_APPEVENTSSTATE_MAX_EVENTS, + _fullState.events.count, + "Should not add additional events to a full state" + ); + XCTAssertEqual(FBSDK_APPEVENTSSTATE_MAX_EVENTS, _fullState.events.count, "Adding to a full state should have no effect on the event count"); +} + +- (void)testAddEventsToPreviouslyOverflownState +{ + // Fills + [_state addEventsFromAppEventState:_fullState]; + // Overflows + [_state addEventsFromAppEventState:_fullState]; + // Double overflows + [_state addEventsFromAppEventState:_fullState]; + + XCTAssertEqual( + FBSDK_APPEVENTSSTATE_MAX_EVENTS * 2, + _state.numSkipped, + "Should keep a running count of skipped states" + ); + XCTAssertEqual( + FBSDK_APPEVENTSSTATE_MAX_EVENTS, + _state.events.count, + "Should not add additional events to a full state" + ); +} + +// MARK: - Compatibility + +- (void)testCompatibilityWithMatchingTokenMatchingAppID +{ + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.appID]; + XCTAssertTrue( + [_state isCompatibleWithAppEventsState:state2], + "States with matching tokens and matching app ids should be compatible" + ); +} + +- (void)testMatchingTokenNonMatchingAppID +{ + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:self.name appID:self.name]; + XCTAssertFalse( + [_state isCompatibleWithAppEventsState:state2], + "States with matching tokens and non-matching app ids should not be compatible" + ); +} + +- (void)testNonMatchingTokenMatchingAppID +{ + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:self.appID appID:self.appID]; + XCTAssertFalse( + [_state isCompatibleWithAppEventsState:state2], + "States with matching non-matching tokens and matching app ids should not be compatible" + ); +} + +- (void)testNonMatchingTokenNonMatchingAppID +{ + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:self.appID appID:self.name]; + XCTAssertFalse( + [_state isCompatibleWithAppEventsState:state2], + "States with matching non-matching tokens and non matching app ids should not be compatible" + ); +} + +- (void)testNilTokensMatchingAppID +{ + FBSDKAppEventsState *state1 = [[FBSDKAppEventsState alloc] initWithToken:nil appID:self.appID]; + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:nil appID:self.appID]; + + XCTAssertTrue( + [state1 isCompatibleWithAppEventsState:state2], + "States with nil tokens and matching app ids should be compatible" + ); +} + +- (void)testNilTokensNonMatchingAppID +{ + FBSDKAppEventsState *state1 = [[FBSDKAppEventsState alloc] initWithToken:nil appID:self.appID]; + FBSDKAppEventsState *state2 = [[FBSDKAppEventsState alloc] initWithToken:nil appID:self.name]; + + XCTAssertFalse( + [state1 isCompatibleWithAppEventsState:state2], + "States with nil tokens and non-matching app ids should not be compatible" + ); } +// MARK: - Extract Receipt Data + - (void)testExtractReceiptData { - FBSDKAppEventsState *target = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - [target addEvent:@{@"receipt_data":@"some_data"} isImplicit:NO]; - NSString* extractString = [target extractReceiptData]; - XCTAssertTrue([extractString isEqualToString: @"receipt_1::some_data;;;"]); + [_state addEvent:@{@"receipt_data" : @"some_data"} isImplicit:NO]; + NSString *extracted = [_state extractReceiptData]; + + XCTAssertTrue([extracted isEqualToString:@"receipt_1::some_data;;;"]); +} + +// MARK: - JSONString For Events + +- (void)testJSONStringForEventsWithNoEvents +{ + NSString *json = [_state JSONStringForEvents:YES]; + NSString *expected = [FBSDKBasicUtility JSONStringForObject:@[] error:nil invalidObjectHandler:nil]; + + XCTAssertEqualObjects(json, expected, "Should represent events as empty json array when there are no events"); } -- (void)testJSONStringForEvents +- (void)testJSONStringForEventsIncludingImplicitEvents { - FBSDKAppEventsState *target = [[FBSDKAppEventsState alloc] initWithToken:@"token" appID:@"app"]; - NSDictionary* someEvent = @{ @"receipt_data":@"some_receipt_data",@"data":@"mock_data"}; - [target addEvent:someEvent isImplicit:YES]; - NSString* jsonString = [target JSONStringForEvents:YES]; - NSString* expectedString = [FBSDKBasicUtility JSONStringForObject:@[@{@"data":@"mock_data"}] error:nil invalidObjectHandler:nil]; - XCTAssertTrue([jsonString isEqualToString:expectedString]); + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + + NSString *json = [_state JSONStringForEvents:YES]; + NSString *expected = [FBSDKBasicUtility JSONStringForObject:@[SampleAppEvents.validEvent, SampleAppEvents.validEvent] error:nil invalidObjectHandler:nil]; + + XCTAssertEqualObjects(json, expected, "Should represent events as empty json array when there are no events"); +} + +- (void)testJSONStringForEventsExcludingImplicitEvents +{ + [_state addEvent:SampleAppEvents.validEvent isImplicit:YES]; + [_state addEvent:SampleAppEvents.validEvent isImplicit:NO]; + + NSString *json = [_state JSONStringForEvents:NO]; + + NSString *expected = [FBSDKBasicUtility JSONStringForObject:@[SampleAppEvents.validEvent] error:nil invalidObjectHandler:nil]; + + XCTAssertEqualObjects(json, expected, "Should represent events as empty json array when there are no events"); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index 5005514268..cf0f609eee 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -16,9 +16,8 @@ // 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 #import @@ -30,12 +29,14 @@ #import "FBSDKApplicationDelegate.h" #import "FBSDKConstants.h" #import "FBSDKGateKeeperManager.h" -#import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequest.h" +#import "FBSDKGraphRequest+Internal.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" +#import "FBSDKTestCase.h" #import "FBSDKUtility.h" +#import "UserDefaultsSpy.h" static NSString *const _mockAppID = @"mockAppID"; static NSString *const _mockUserID = @"mockUserID"; @@ -49,6 +50,7 @@ @interface FBSDKAppEvents () @property (nonatomic, copy) NSString *pushNotificationsDeviceTokenString; - (void)checkPersistedEvents; - (void)publishInstall; +- (void)publishATE; - (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason; - (void)fetchServerConfiguration:(FBSDKCodeBlock)callback; - (void)instanceLogEvent:(FBSDKAppEventName)eventName @@ -93,14 +95,13 @@ + (void)logImplicitEvent:(NSString *)eventName @end -@interface FBSDKAppEventsTests : XCTestCase +@interface FBSDKAppEventsTests : FBSDKTestCase { - id _partialMockAppEvents; - id _mockAppStates; NSString *_mockEventName; - NSDictionary *_mockPayload; + NSDictionary *_mockPayload; double _mockPurchaseAmount; NSString *_mockCurrency; + id _mockAppEventsUtility; } @end @@ -108,59 +109,60 @@ @implementation FBSDKAppEventsTests - (void)setUp { - [FBSDKAppEvents resetSingleton]; - _partialMockAppEvents = OCMPartialMock([FBSDKAppEvents singleton]); - OCMStub([_partialMockAppEvents singleton]).andReturn(_partialMockAppEvents); - _mockAppStates = OCMClassMock([FBSDKAppEventsState class]); - OCMStub([_mockAppStates alloc]).andReturn(_mockAppStates); - OCMStub([_mockAppStates initWithToken:[OCMArg any] appID:[OCMArg any]]).andReturn(_mockAppStates); + [super setUp]; + + [self stubLoadingAdNetworkReporterConfiguration]; + _mockEventName = @"fb_mock_event"; - _mockPayload = @{@"fb_push_payload" : @{@"campaign" : @"testCampaign"}}; + _mockPayload = @{@"fb_push_payload" : @{@"campaign" : @"testCampaign"}}; _mockPurchaseAmount = 1.0; _mockCurrency = @"USD"; [FBSDKAppEvents setLoggingOverrideAppID:_mockAppID]; + + self.appEventsMock = OCMPartialMock([FBSDKAppEvents singleton]); + // Mock FBSDKAppEventsUtility + _mockAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); + OCMStub([_mockAppEventsUtility shouldDropAppEvent]).andReturn(NO); + OCMStub([_mockAppEventsUtility advertisingTrackingStatus]).andReturn(FBSDKAdvertisingTrackingAllowed); } - (void)tearDown { - [FBSDKAppEvents resetSingleton]; - [_partialMockAppEvents stopMocking]; - [_mockAppStates stopMocking]; [OHHTTPStubs removeAllStubs]; } - (void)testLogPurchaseFlush { - OCMExpect([_partialMockAppEvents flushForReason:FBSDKAppEventsFlushReasonEagerlyFlushingEvent]); + OCMExpect([self.appEventsMock flushForReason:FBSDKAppEventsFlushReasonEagerlyFlushingEvent]); - OCMStub([_partialMockAppEvents flushBehavior]).andReturn(FBSDKAppEventsFlushReasonEagerlyFlushingEvent); + OCMStub([self.appEventsMock flushBehavior]).andReturn(FBSDKAppEventsFlushReasonEagerlyFlushingEvent); [FBSDKAppEvents logPurchase:_mockPurchaseAmount currency:_mockCurrency]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testLogPurchase { - OCMExpect([_partialMockAppEvents logPurchase:_mockPurchaseAmount currency:_mockCurrency parameters:[OCMArg any]]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logPurchase:_mockPurchaseAmount currency:_mockCurrency parameters:[OCMArg any] accessToken:[OCMArg any]]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logEvent:FBSDKAppEventNamePurchased valueToSum:@(_mockPurchaseAmount) parameters:[OCMArg any] accessToken:[OCMArg any]]).andForwardToRealObject(); - OCMExpect([_mockAppStates addEvent:[OCMArg any] isImplicit:NO]); + OCMExpect([self.appEventsMock logPurchase:_mockPurchaseAmount currency:_mockCurrency parameters:[OCMArg any]]).andForwardToRealObject(); + OCMExpect([self.appEventsMock logPurchase:_mockPurchaseAmount currency:_mockCurrency parameters:[OCMArg any] accessToken:[OCMArg any]]).andForwardToRealObject(); + OCMExpect([self.appEventsMock logEvent:FBSDKAppEventNamePurchased valueToSum:@(_mockPurchaseAmount) parameters:[OCMArg any] accessToken:[OCMArg any]]).andForwardToRealObject(); + OCMExpect([self.appEventStatesMock addEvent:[OCMArg any] isImplicit:NO]); [FBSDKAppEvents logPurchase:_mockPurchaseAmount currency:_mockCurrency]; - OCMVerifyAll(_partialMockAppEvents); - [_mockAppStates verify]; + OCMVerifyAll(self.appEventsMock); + [self.appEventStatesMock verify]; } - (void)testFlush { - OCMExpect([_partialMockAppEvents flushForReason:FBSDKAppEventsFlushReasonExplicit]); + OCMExpect([self.appEventsMock flushForReason:FBSDKAppEventsFlushReasonExplicit]); [FBSDKAppEvents flush]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } #pragma mark Tests for log product item @@ -168,21 +170,23 @@ - (void)testFlush - (void)testLogProductItemNonNil { NSDictionary *expectedDict = @{ - @"fb_product_availability":@"IN_STOCK", - @"fb_product_brand":@"PHILZ", - @"fb_product_condition":@"NEW", - @"fb_product_description":@"description", - @"fb_product_gtin":@"BLUE MOUNTAIN", - @"fb_product_image_link":@"https://www.sample.com", - @"fb_product_item_id":@"F40CEE4E-471E-45DB-8541-1526043F4B21", - @"fb_product_link":@"https://www.sample.com", - @"fb_product_mpn":@"BLUE MOUNTAIN", - @"fb_product_price_amount":@"1.000", - @"fb_product_price_currency":@"USD", - @"fb_product_title":@"title", + @"fb_product_availability" : @"IN_STOCK", + @"fb_product_brand" : @"PHILZ", + @"fb_product_condition" : @"NEW", + @"fb_product_description" : @"description", + @"fb_product_gtin" : @"BLUE MOUNTAIN", + @"fb_product_image_link" : @"https://www.sample.com", + @"fb_product_item_id" : @"F40CEE4E-471E-45DB-8541-1526043F4B21", + @"fb_product_link" : @"https://www.sample.com", + @"fb_product_mpn" : @"BLUE MOUNTAIN", + @"fb_product_price_amount" : @"1.000", + @"fb_product_price_currency" : @"USD", + @"fb_product_title" : @"title", }; - OCMExpect([_partialMockAppEvents logEvent:@"fb_mobile_catalog_update" - parameters:expectedDict]); + OCMExpect( + [self.appEventsMock logEvent:@"fb_mobile_catalog_update" + parameters:expectedDict] + ); [FBSDKAppEvents logProductItem:@"F40CEE4E-471E-45DB-8541-1526043F4B21" availability:FBSDKProductAvailabilityInStock @@ -198,24 +202,26 @@ - (void)testLogProductItemNonNil brand:@"PHILZ" parameters:@{}]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testLogProductItemNilGtinMpnBrand { NSDictionary *expectedDict = @{ - @"fb_product_availability":@"IN_STOCK", - @"fb_product_condition":@"NEW", - @"fb_product_description":@"description", - @"fb_product_image_link":@"https://www.sample.com", - @"fb_product_item_id":@"F40CEE4E-471E-45DB-8541-1526043F4B21", - @"fb_product_link":@"https://www.sample.com", - @"fb_product_price_amount":@"1.000", - @"fb_product_price_currency":@"USD", - @"fb_product_title":@"title", + @"fb_product_availability" : @"IN_STOCK", + @"fb_product_condition" : @"NEW", + @"fb_product_description" : @"description", + @"fb_product_image_link" : @"https://www.sample.com", + @"fb_product_item_id" : @"F40CEE4E-471E-45DB-8541-1526043F4B21", + @"fb_product_link" : @"https://www.sample.com", + @"fb_product_price_amount" : @"1.000", + @"fb_product_price_currency" : @"USD", + @"fb_product_title" : @"title", }; - OCMReject([_partialMockAppEvents logEvent:@"fb_mobile_catalog_update" - parameters:expectedDict]); + OCMReject( + [self.appEventsMock logEvent:@"fb_mobile_catalog_update" + parameters:expectedDict] + ); [FBSDKAppEvents logProductItem:@"F40CEE4E-471E-45DB-8541-1526043F4B21" availability:FBSDKProductAvailabilityInStock @@ -236,7 +242,7 @@ - (void)testLogProductItemNilGtinMpnBrand - (void)testSetAndClearUserData { - NSString *mockEmail= @"test_em"; + NSString *mockEmail = @"test_em"; NSString *mockFirstName = @"test_fn"; NSString *mockLastName = @"test_ln"; NSString *mockPhone = @"123"; @@ -252,14 +258,13 @@ - (void)testSetAndClearUserData zip:nil country:nil]; - NSDictionary *expectedUserData = @{@"em":[FBSDKUtility SHA256Hash:mockEmail], - @"fn":[FBSDKUtility SHA256Hash:mockFirstName], - @"ln":[FBSDKUtility SHA256Hash:mockLastName], - @"ph":[FBSDKUtility SHA256Hash:mockPhone], - }; + NSDictionary *expectedUserData = @{@"em" : [FBSDKUtility SHA256Hash:mockEmail], + @"fn" : [FBSDKUtility SHA256Hash:mockFirstName], + @"ln" : [FBSDKUtility SHA256Hash:mockLastName], + @"ph" : [FBSDKUtility SHA256Hash:mockPhone], }; NSDictionary *userData = (NSDictionary *)[FBSDKTypeUtility JSONObjectWithData:[[FBSDKAppEvents getUserData] dataUsingEncoding:NSUTF8StringEncoding] - options:NSJSONReadingMutableContainers - error:nil]; + options: NSJSONReadingMutableContainers + error: nil]; XCTAssertEqualObjects(userData, expectedUserData); [FBSDKAppEvents clearUserData]; @@ -303,17 +308,21 @@ - (void)testSetPushNotificationsDeviceTokenString NSString *mockDeviceTokenString = @"testDeviceTokenString"; NSString *eventName = @"fb_mobile_obtain_push_token"; - OCMExpect([_partialMockAppEvents logEvent:eventName]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logEvent:eventName - parameters:@{}]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logEvent:eventName - valueToSum:nil - parameters:@{} - accessToken:nil]).andForwardToRealObject(); + OCMExpect([self.appEventsMock logEvent:eventName]).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logEvent:eventName + parameters:@{}] + ).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logEvent:eventName + valueToSum:nil + parameters:@{} + accessToken:nil] + ).andForwardToRealObject(); [FBSDKAppEvents setPushNotificationsDeviceTokenString:mockDeviceTokenString]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); XCTAssertEqualObjects([FBSDKAppEvents singleton].pushNotificationsDeviceTokenString, mockDeviceTokenString); } @@ -326,23 +335,25 @@ - (void)testLogInitialize NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; id userDefaultsMock = OCMPartialMock(userDefaults); OCMStub([userDefaultsMock integerForKey:[OCMArg any]]).andReturn(1); - OCMExpect([_partialMockAppEvents logInternalEvent:@"fb_sdk_initialize" - parameters:[OCMArg any] - isImplicitlyLogged:NO]); + OCMExpect( + [self.appEventsMock logInternalEvent:@"fb_sdk_initialize" + parameters:[OCMArg any] + isImplicitlyLogged:NO] + ); [delegateMock _logSDKInitialize]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testActivateApp { - OCMExpect([_partialMockAppEvents publishInstall]); - OCMExpect([_partialMockAppEvents fetchServerConfiguration:NULL]); + OCMExpect([self.appEventsMock publishInstall]); + OCMExpect([self.appEventsMock fetchServerConfiguration:NULL]); [FBSDKAppEvents activateApp]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } #pragma mark Test for log push notification @@ -351,29 +362,29 @@ - (void)testLogPushNotificationOpen { NSString *eventName = @"fb_mobile_push_opened"; // with action and campaign - NSDictionary *expectedParams1 = @{ - @"fb_push_action":@"testAction", - @"fb_push_campaign":@"testCampaign", + NSDictionary *expectedParams1 = @{ + @"fb_push_action" : @"testAction", + @"fb_push_campaign" : @"testCampaign", }; - OCMExpect([_partialMockAppEvents logEvent:eventName parameters:expectedParams1]); + OCMExpect([self.appEventsMock logEvent:eventName parameters:expectedParams1]); [FBSDKAppEvents logPushNotificationOpen:_mockPayload action:@"testAction"]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); // empty action - NSDictionary *expectedParams2 = @{ - @"fb_push_campaign":@"testCampaign", + NSDictionary *expectedParams2 = @{ + @"fb_push_campaign" : @"testCampaign", }; - OCMExpect([_partialMockAppEvents logEvent:eventName parameters:expectedParams2]); + OCMExpect([self.appEventsMock logEvent:eventName parameters:expectedParams2]); [FBSDKAppEvents logPushNotificationOpen:_mockPayload]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); // empty payload - OCMReject([_partialMockAppEvents logEvent:eventName parameters:[OCMArg any]]); + OCMReject([self.appEventsMock logEvent:eventName parameters:[OCMArg any]]); [FBSDKAppEvents logPushNotificationOpen:@{}]; // empty campaign - NSDictionary *mockPayload = @{@"fb_push_payload" : @{@"campaign" : @""}}; - OCMReject([_partialMockAppEvents logEvent:eventName parameters:[OCMArg any]]); + NSDictionary *mockPayload = @{@"fb_push_payload" : @{@"campaign" : @""}}; + OCMReject([self.appEventsMock logEvent:eventName parameters:[OCMArg any]]); [FBSDKAppEvents logPushNotificationOpen:mockPayload]; } @@ -388,20 +399,18 @@ - (void)testSetFlushBehavior - (void)testCheckPersistedEventsCalledWhenLogEvent { + OCMExpect([self.appEventsMock checkPersistedEvents]); - OCMExpect([_partialMockAppEvents checkPersistedEvents]); - - OCMStub([_partialMockAppEvents flushBehavior]).andReturn(FBSDKAppEventsFlushReasonEagerlyFlushingEvent); + OCMStub([self.appEventsMock flushBehavior]).andReturn(FBSDKAppEventsFlushReasonEagerlyFlushingEvent); [FBSDKAppEvents logEvent:FBSDKAppEventNamePurchased valueToSum:@(_mockPurchaseAmount) parameters:@{} accessToken:nil]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testRequestForCustomAudienceThirdPartyIDWithAccessToken { id mockAccessToken = [OCMockObject niceMockForClass:[FBSDKAccessToken class]]; - id mockAppEventsUtility = [OCMockObject niceMockForClass:[FBSDKAppEventsUtility class]]; NSString *tokenString = [FBSDKAppEventsUtility tokenStringToUseFor:mockAccessToken]; NSString *graphPath = [NSString stringWithFormat:@"%@/custom_audience_third_party_id", _mockAppID]; FBSDKGraphRequest *expectedRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath @@ -411,16 +420,16 @@ - (void)testRequestForCustomAudienceThirdPartyIDWithAccessToken flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; // without access token - [[mockAppEventsUtility expect] advertiserID]; + [[_mockAppEventsUtility expect] advertiserID]; FBSDKGraphRequest *request = [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:nil]; - [mockAppEventsUtility verify]; + [_mockAppEventsUtility verify]; XCTAssertNil(request); // with access token - [[mockAppEventsUtility reject] advertiserID]; + [[_mockAppEventsUtility reject] advertiserID]; request = [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:mockAccessToken]; @@ -431,11 +440,69 @@ - (void)testRequestForCustomAudienceThirdPartyIDWithAccessToken - (void)testPublishInstall { - OCMExpect([_partialMockAppEvents fetchServerConfiguration:[OCMArg any]]); + [self stubUserDefaultsWith:[UserDefaultsSpy new]]; + [self stubAppID:self.appID]; + OCMExpect([self.appEventsMock fetchServerConfiguration:[OCMArg any]]); + + [self.appEventsMock publishInstall]; + + OCMVerifyAll(self.appEventsMock); +} + +- (void)testPublishATEWithNoPing +{ + [self stubAppID:@"mockAppID"]; + [self stubUserDefaultsWith:[UserDefaultsSpy new]]; + + id graphRequestMock = OCMClassMock([FBSDKGraphRequest class]); + OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); + OCMStub( + [graphRequestMock initWithGraphPath:[OCMArg any] + parameters:[OCMArg any] + tokenString:nil + HTTPMethod:FBSDKHTTPMethodPOST + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery] + ).andReturn(graphRequestMock); + + [self.appEventsMock publishATE]; + + OCMVerify([graphRequestMock startWithCompletionHandler:[OCMArg any]]); +} - [_partialMockAppEvents publishInstall]; +- (void)testPublishATEWithPingLessThan24Hours +{ + [self stubAppID:@"mockAppID"]; + UserDefaultsSpy *userDefault = [UserDefaultsSpy new]; + [userDefault setObject:[NSDate dateWithTimeIntervalSinceNow:-12 * 60 * 60] forKey:[NSString stringWithFormat:@"com.facebook.sdk:lastATEPing%@", @"mockAppID"]]; + [self stubUserDefaultsWith:userDefault]; + + id graphRequestMock = OCMClassMock([FBSDKGraphRequest class]); + OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); + OCMStub( + [graphRequestMock initWithGraphPath:[OCMArg any] + parameters:[OCMArg any] + tokenString:nil + HTTPMethod:FBSDKHTTPMethodPOST + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery] + ).andReturn(graphRequestMock); + + [self.appEventsMock publishATE]; + + OCMReject([graphRequestMock startWithCompletionHandler:[OCMArg any]]); +} + +- (void)testPublishATEWithVerifyingParams +{ + [self stubAppID:@"mockAppID"]; + [self stubUserDefaultsWith:[UserDefaultsSpy new]]; - OCMVerifyAll(_partialMockAppEvents); + id mockFBSDKAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); + [self.appEventsMock publishATE]; + + OCMReject( + [mockFBSDKAppEventsUtility activityParametersDictionaryForEvent:[OCMArg any] + shouldAccessAdvertisingID:[OCMArg any]] + ); } #pragma mark Tests for Kill Switch @@ -443,55 +510,63 @@ - (void)testPublishInstall - (void)testAppEventsKillSwitchDisabled { id mockGateKeeperManager = OCMClassMock([FBSDKGateKeeperManager class]); - OCMStub([mockGateKeeperManager boolForKey:[OCMArg any] - defaultValue:NO]).andReturn(NO); + OCMStub( + [mockGateKeeperManager boolForKey:[OCMArg any] + defaultValue:NO] + ).andReturn(NO); - OCMExpect([_mockAppStates addEvent:[OCMArg any] isImplicit:NO]); + OCMExpect([self.appEventStatesMock addEvent:[OCMArg any] isImplicit:NO]); - [_partialMockAppEvents instanceLogEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:nil - isImplicitlyLogged:NO - accessToken:nil]; + [self.appEventsMock instanceLogEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:nil + isImplicitlyLogged:NO + accessToken:nil]; - [_mockAppStates verify]; + [self.appEventStatesMock verify]; } - (void)testAppEventsKillSwitchEnabled { id mockGateKeeperManager = OCMClassMock([FBSDKGateKeeperManager class]); - OCMStub([mockGateKeeperManager boolForKey:[OCMArg any] - defaultValue:NO]).andReturn(YES); - - OCMReject([_mockAppStates addEvent:[OCMArg any] isImplicit:NO]); - - [_partialMockAppEvents instanceLogEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:nil - isImplicitlyLogged:NO - accessToken:nil]; + OCMStub( + [mockGateKeeperManager boolForKey:[OCMArg any] + defaultValue:NO] + ).andReturn(YES); + + OCMReject([self.appEventStatesMock addEvent:[OCMArg any] isImplicit:NO]); + + [self.appEventsMock instanceLogEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:nil + isImplicitlyLogged:NO + accessToken:nil]; } - (void)testGraphRequestBannedWithAutoInitDisabled { - //test when autoInitEnabled is set to be NO + // test when autoInitEnabled is set to be NO __block int activiesEndpointCalledCountDisabled = 0; NSString *urlString = [NSString stringWithFormat:@"%@/activities", _mockAppID]; XCTestExpectation *expectation = [self expectationWithDescription:@"No Graph Request is sent"]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - XCTAssertNotNil(request); - if ([request.URL.absoluteString rangeOfString:urlString].location != NSNotFound) { - ++activiesEndpointCalledCountDisabled; - } - return NO; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - return [OHHTTPStubsResponse responseWithData:[NSData data] - statusCode:200 - headers:nil]; - }]; - + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + XCTAssertNotNil(request); + if ([request.URL.absoluteString rangeOfString:urlString].location != NSNotFound) { + ++activiesEndpointCalledCountDisabled; + } + return NO; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + return [OHHTTPStubsResponse responseWithData:[NSData data] + statusCode:200 + headers:nil]; + }]; + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" [FBSDKSettings setAutoInitEnabled:NO]; + #pragma clang diagnostic pop + [FBSDKAppEvents logPurchase:_mockPurchaseAmount currency:_mockCurrency]; [expectation fulfill]; [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) { @@ -504,73 +579,89 @@ - (void)testGraphRequestBannedWithAutoInitDisabled - (void)testLogEventWithValueToSum { - OCMExpect([_partialMockAppEvents logEvent:_mockEventName - valueToSum:_mockPurchaseAmount - parameters:@{}]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:@{} - accessToken:nil]).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logEvent:_mockEventName + valueToSum:_mockPurchaseAmount + parameters:@{}] + ).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:@{} + accessToken:nil] + ).andForwardToRealObject(); [FBSDKAppEvents logEvent:_mockEventName valueToSum:_mockPurchaseAmount]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testLogInternalEvents { - OCMExpect([_partialMockAppEvents logInternalEvent:_mockEventName - parameters:@{} - isImplicitlyLogged:NO]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logInternalEvent:_mockEventName - valueToSum:nil - parameters:@{} - isImplicitlyLogged:NO - accessToken:nil]).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logInternalEvent:_mockEventName + parameters:@{} + isImplicitlyLogged:NO] + ).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logInternalEvent:_mockEventName + valueToSum:nil + parameters:@{} + isImplicitlyLogged:NO + accessToken:nil] + ).andForwardToRealObject(); [FBSDKAppEvents logInternalEvent:_mockEventName isImplicitlyLogged:NO]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testLogInternalEventsWithValue { - OCMExpect([_partialMockAppEvents logInternalEvent:_mockEventName - valueToSum:_mockPurchaseAmount - parameters:@{} - isImplicitlyLogged:NO]).andForwardToRealObject(); - OCMExpect([_partialMockAppEvents logInternalEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:@{} - isImplicitlyLogged:NO - accessToken:nil]).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logInternalEvent:_mockEventName + valueToSum:_mockPurchaseAmount + parameters:@{} + isImplicitlyLogged:NO] + ).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logInternalEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:@{} + isImplicitlyLogged:NO + accessToken:nil] + ).andForwardToRealObject(); [FBSDKAppEvents logInternalEvent:_mockEventName valueToSum:_mockPurchaseAmount isImplicitlyLogged:NO]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testLogInternalEventWithAccessToken { id mockAccessToken = [OCMockObject niceMockForClass:[FBSDKAccessToken class]]; - OCMExpect([_partialMockAppEvents logInternalEvent:_mockEventName - valueToSum:nil - parameters:@{} - isImplicitlyLogged:NO - accessToken:mockAccessToken]).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock logInternalEvent:_mockEventName + valueToSum:nil + parameters:@{} + isImplicitlyLogged:NO + accessToken:mockAccessToken] + ).andForwardToRealObject(); [FBSDKAppEvents logInternalEvent:_mockEventName parameters:@{} isImplicitlyLogged:NO accessToken:mockAccessToken]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testInstanceLogEventWhenAutoLogAppEventsDisabled { id mockSetting = OCMClassMock([FBSDKSettings class]); OCMStub([mockSetting isAutoLogAppEventsEnabled]).andReturn(NO); - OCMReject([_partialMockAppEvents instanceLogEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:@{} - isImplicitlyLogged:NO - accessToken:nil]).andForwardToRealObject(); + OCMReject( + [self.appEventsMock instanceLogEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:@{} + isImplicitlyLogged:NO + accessToken:nil] + ).andForwardToRealObject(); [FBSDKAppEvents logInternalEvent:_mockEventName valueToSum:_mockPurchaseAmount isImplicitlyLogged:NO]; } @@ -579,28 +670,32 @@ - (void)testInstanceLogEventWhenAutoLogAppEventsEnabled { id mockSetting = OCMClassMock([FBSDKSettings class]); OCMStub([mockSetting isAutoLogAppEventsEnabled]).andReturn(YES); - OCMExpect([_partialMockAppEvents instanceLogEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:@{} - isImplicitlyLogged:NO - accessToken:nil]).andForwardToRealObject(); + OCMExpect( + [self.appEventsMock instanceLogEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:@{} + isImplicitlyLogged:NO + accessToken:nil] + ).andForwardToRealObject(); [FBSDKAppEvents logInternalEvent:_mockEventName valueToSum:_mockPurchaseAmount isImplicitlyLogged:NO]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } - (void)testLogImplicitEvent { - OCMExpect([_partialMockAppEvents instanceLogEvent:_mockEventName - valueToSum:@(_mockPurchaseAmount) - parameters:@{} - isImplicitlyLogged:YES - accessToken:nil]); + OCMExpect( + [self.appEventsMock instanceLogEvent:_mockEventName + valueToSum:@(_mockPurchaseAmount) + parameters:@{} + isImplicitlyLogged:YES + accessToken:nil] + ); [FBSDKAppEvents logImplicitEvent:_mockEventName valueToSum:@(_mockPurchaseAmount) parameters:@{} accessToken:nil]; - OCMVerifyAll(_partialMockAppEvents); + OCMVerifyAll(self.appEventsMock); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 587c3b6b9d..3fe4c49d61 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -20,12 +20,9 @@ #import #import -#import -#import +#import "FBSDKCoreKit+Internal.h" -#import "FBSDKAppEventsUtility.h" -#import "FBSDKTypeUtility.h" -#import "FBSDKUtility.h" +static NSString *const FBSDKSettingsInstallTimestamp = @"com.facebook.sdk:FBSDKSettingsInstallTimestamp"; @interface FBSDKAppEventsUtilityTests : XCTestCase @@ -41,7 +38,6 @@ - (void)setUp { [super setUp]; _mockAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); - OCMStub([_mockAppEventsUtility advertiserID]).andReturn([NSUUID UUID].UUIDString); [FBSDKAppEvents setUserID:@"test-user-id"]; _mockNSLocale = OCMClassMock([NSLocale class]); } @@ -75,6 +71,11 @@ - (void)testValidation - (void)testParamsDictionary { + OCMStub([_mockAppEventsUtility advertiserID]).andReturn([NSUUID UUID].UUIDString); + id mockFBSDKSettings = OCMClassMock([FBSDKSettings class]); + OCMStub([mockFBSDKSettings isAdvertiserTrackingEnabled]).andReturn(YES); + + OCMStub([_mockAppEventsUtility advertiserID]).andReturn([NSUUID UUID].UUIDString); NSDictionary *dict = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:@"event" shouldAccessAdvertisingID:YES]; XCTAssertEqualObjects(@"event", dict[@"event"]); @@ -186,6 +187,53 @@ - (void)testGetNumberValueWithLocaleIT XCTAssertEqualObjects(str, @"1234.56"); } +- (void)testGetAdvertiserIDOniOS14WithCollectionEnabled +{ + id mockFBSDKSettings = OCMClassMock([FBSDKSettings class]); + OCMStub([mockFBSDKSettings isAdvertiserIDCollectionEnabled]).andReturn(YES); + + id mockAppEventsConfiguration = OCMClassMock([FBSDKAppEventsConfiguration class]); + OCMStub([mockAppEventsConfiguration advertiserIDCollectionEnabled]).andReturn(YES); + id mockAppEventsConfigurationManager = OCMClassMock([FBSDKAppEventsConfigurationManager class]); + OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); + + if (@available(iOS 14.0, *)) { + XCTAssertNotNil([FBSDKAppEventsUtility advertiserID]); + } +} + +- (void)testGetAdvertiserIDOniOS14WithCollectionDisabled +{ + id mockFBSDKSettings = OCMClassMock([FBSDKSettings class]); + OCMStub([mockFBSDKSettings isAdvertiserIDCollectionEnabled]).andReturn(YES); + + id mockAppEventsConfiguration = OCMClassMock([FBSDKAppEventsConfiguration class]); + OCMStub([mockAppEventsConfiguration advertiserIDCollectionEnabled]).andReturn(NO); + id mockAppEventsConfigurationManager = OCMClassMock([FBSDKAppEventsConfigurationManager class]); + OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); + + if (@available(iOS 14.0, *)) { + XCTAssertNil([FBSDKAppEventsUtility advertiserID]); + } +} + +- (void)testShouldDropAppEvent +{ + id mockFBSDKSettings = OCMClassMock([FBSDKSettings class]); + OCMStub([mockFBSDKSettings getAdvertisingTrackingStatus]).andReturn(FBSDKAdvertisingTrackingDisallowed); + + id mockAppEventsConfiguration = OCMClassMock([FBSDKAppEventsConfiguration class]); + OCMStub([mockAppEventsConfiguration eventCollectionEnabled]).andReturn(NO); + id mockAppEventsConfigurationManager = OCMClassMock([FBSDKAppEventsConfigurationManager class]); + OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); + + if (@available(iOS 14.0, *)) { + XCTAssertTrue([FBSDKAppEventsUtility shouldDropAppEvent]); + } else { + XCTAssertFalse([FBSDKAppEventsUtility shouldDropAppEvent]); + } +} + - (void)testIsSensitiveUserData { NSString *text = @"test@sample.com"; @@ -229,4 +277,36 @@ - (void)testFlushReasonToString XCTAssertEqualObjects(@"EagerlyFlushingEvent", result6); } +- (void)testGetStandardEvents +{ + NSArray *standardEvents = @[ + @"fb_mobile_complete_registration", + @"fb_mobile_content_view", + @"fb_mobile_search", + @"fb_mobile_rate", + @"fb_mobile_tutorial_completion", + @"fb_mobile_add_to_cart", + @"fb_mobile_add_to_wishlist", + @"fb_mobile_initiated_checkout", + @"fb_mobile_add_payment_info", + @"fb_mobile_purchase", + @"fb_mobile_level_achieved", + @"fb_mobile_achievement_unlocked", + @"fb_mobile_spent_credits", + @"Contact", + @"CustomizeProduct", + @"Donate", + @"FindLocation", + @"Schedule", + @"StartTrial", + @"SubmitApplication", + @"Subscribe", + @"AdImpression", + @"AdClick", + ]; + for (NSString *event in standardEvents) { + XCTAssertTrue([FBSDKAppEventsUtility isStandardEvent:event]); + } +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKPaymentObserverTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKPaymentObserverTests.m index 49d1dd1928..c17d815ec1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKPaymentObserverTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKPaymentObserverTests.m @@ -16,11 +16,10 @@ // 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 - #import "FBSDKPaymentObserver.h" @interface FBSDKPaymentObserver () @@ -37,7 +36,8 @@ @interface FBSDKPaymentObserverTests : XCTestCase @implementation FBSDKPaymentObserverTests -- (void)testPaymentObserverAddRemove { +- (void)testPaymentObserverAddRemove +{ FBSDKPaymentObserver *observer = [FBSDKPaymentObserver singleton]; BOOL isObserving = [[observer valueForKeyPath:@"_observingTransactions"] boolValue]; @@ -66,5 +66,4 @@ - (void)testPaymenQueueUpdateTransactions [partialMockObserver verify]; } - @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKTimeSpentDataTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKTimeSpentDataTests.m index 930c482624..f4a55ec6fd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKTimeSpentDataTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKTimeSpentDataTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKTimeSpentData.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m index a6c79565e2..3d60917f19 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKIntegrityManager.h" #import "FBSDKModelManager.h" @@ -41,9 +40,10 @@ - (void)setUp - (void)testProcessParameters1 { + // Parameter contains restrictive data NSDictionary *parameters = @{ - @"address" : @"2301 N Highland Ave, Los Angeles, CA 90068", - @"period_starts" : @"2020-02-03", + @"address" : @"2301 N Highland Ave, Los Angeles, CA 90068", // address + @"period_starts" : @"2020-02-03", // health }; OCMStub([_mockModelManager processIntegrity:[OCMArg any]]).andReturn(YES); @@ -52,18 +52,22 @@ - (void)testProcessParameters1 XCTAssertNil(processed[@"address"]); XCTAssertNil(processed[@"period_starts"]); XCTAssertNotNil(processed[@"_onDeviceParams"]); + XCTAssertTrue([processed[@"_onDeviceParams"] containsString:@"address"]); + XCTAssertTrue([processed[@"_onDeviceParams"] containsString:@"period_starts"]); } - (void)testProcessParameters2 { + // Parameter does not contain any restrictive data NSDictionary *parameters = @{ @"_valueToSum" : @1, - @"_session_id" :@"12345", + @"_session_id" : @"12345", }; OCMStub([_mockModelManager processIntegrity:[OCMArg any]]).andReturn(NO); NSDictionary *processed = [FBSDKIntegrityManager processParameters:parameters]; XCTAssertNotNil(processed[@"_valueToSum"]); + XCTAssertNotNil(processed[@"_session_id"]); XCTAssertNil(processed[@"_onDeviceParams"]); } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m index b3c0cae473..2788e21c63 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m @@ -16,22 +16,25 @@ // 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 "FBSDKAppEvents.h" #import "FBSDKAppEventsState.h" #import "FBSDKInternalUtility.h" +#import "FBSDKRestrictiveDataFilterManager.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" -#import "FBSDKRestrictiveDataFilterManager.h" + +typedef void (^FBSDKSKAdNetworkReporterBlock)(void); +@interface FBSDKSKAdNetworkReporter (Testing) ++ (void)_loadConfigurationWithBlock:(FBSDKSKAdNetworkReporterBlock)block; +@end @interface FBSDKRestrictiveDataFilterManager () -+ (void)updateFilters:(nullable NSDictionary *)restrictiveParams; -+ (NSString *)getMatchedDataTypeWithEventName:(NSString *)eventName - paramKey:(NSString *)paramKey; ++ (NSString *)_getMatchedDataTypeWithEventName:(NSString *)eventName + paramKey:(NSString *)paramKey; @end @@ -44,25 +47,28 @@ - (void)setUp { [super setUp]; - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary: @{ - @"test_event_name" : @{ - @"restrictive_param" : @{ - @"first name" : @"6", - @"last name" : @"7" - } - }, - @"restrictive_event_name" : @{ - @"restrictive_param" : @{ - @"dob" : @4 - } - } - }]; + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:@{ + @"test_event_name" : @{ + @"restrictive_param" : @{ + @"first name" : @"6", + @"last name" : @"7" + } + }, + @"restrictive_event_name" : @{ + @"restrictive_param" : @{ + @"dob" : @4 + } + } + }]; id mockServerConfiguration = OCMClassMock([FBSDKServerConfiguration class]); OCMStub([mockServerConfiguration restrictiveParams]).andReturn(params); id mockServerConfigurationManager = OCMClassMock([FBSDKServerConfigurationManager class]); OCMStub([mockServerConfigurationManager cachedServerConfiguration]).andReturn(mockServerConfiguration); + id mockAdNetworkReporter = OCMClassMock(FBSDKSKAdNetworkReporter.class); + OCMStub([mockAdNetworkReporter _loadConfigurationWithBlock:OCMArg.any]); + [FBSDKRestrictiveDataFilterManager enable]; } @@ -72,35 +78,37 @@ - (void)testFilterByParams id mockAppStates = [OCMockObject niceMockForClass:[FBSDKAppEventsState class]]; OCMStub([mockAppStates alloc]).andReturn(mockAppStates); OCMStub([mockAppStates initWithToken:[OCMArg any] appID:[OCMArg any]]).andReturn(mockAppStates); + id mockAppEventsUtility = [OCMockObject niceMockForClass:[FBSDKAppEventsUtility class]]; + OCMStub([mockAppEventsUtility shouldDropAppEvent]).andReturn(NO); // filtered by param key - [[mockAppStates expect] addEvent:[OCMArg checkWithBlock:^(id value){ + [[mockAppStates expect] addEvent:[OCMArg checkWithBlock:^(id value) { XCTAssertEqualObjects(value[@"_eventName"], testEventName); XCTAssertNil(value[@"dob"]); XCTAssertEqualObjects(value[@"_restrictedParams"], @"{\"dob\":\"4\"}"); return YES; }] isImplicit:NO]; - [FBSDKAppEvents logEvent:testEventName parameters:@{@"dob": @"06-29-2019"}]; + [FBSDKAppEvents logEvent:testEventName parameters:@{@"dob" : @"06-29-2019"}]; [mockAppStates verify]; // should not be filtered - [[mockAppStates expect] addEvent:[OCMArg checkWithBlock:^(id value){ + [[mockAppStates expect] addEvent:[OCMArg checkWithBlock:^(id value) { XCTAssertEqualObjects(value[@"_eventName"], testEventName); XCTAssertEqualObjects(value[@"test_key"], @66666); XCTAssertNil(value[@"_restrictedParams"]); return YES; }] isImplicit:NO]; - [FBSDKAppEvents logEvent:testEventName parameters:@{@"test_key": @66666}]; + [FBSDKAppEvents logEvent:testEventName parameters:@{@"test_key" : @66666}]; [mockAppStates verify]; } - (void)testGetMatchedDataTypeByParam { NSString *testEventName = @"test_event_name"; - NSString *type1 = [FBSDKRestrictiveDataFilterManager getMatchedDataTypeWithEventName:testEventName paramKey:@"first name"]; + NSString *type1 = [FBSDKRestrictiveDataFilterManager _getMatchedDataTypeWithEventName:testEventName paramKey:@"first name"]; XCTAssertEqualObjects(type1, @"6"); - NSString *type2= [FBSDKRestrictiveDataFilterManager getMatchedDataTypeWithEventName:testEventName paramKey:@"reservation number"]; + NSString *type2 = [FBSDKRestrictiveDataFilterManager _getMatchedDataTypeWithEventName:testEventName paramKey:@"reservation number"]; XCTAssertNil(type2); } @@ -113,27 +121,32 @@ - (void)testProcessEventCanHandleAnEmptyArray - (void)testProcessEventCanHandleMissingKeys { NSDictionary *> *event = @{ - @"some_event": @{} + @"some_event" : @{} }; NSMutableArray *eventArray = [[NSMutableArray alloc] initWithObjects:event, nil]; - XCTAssertNoThrow([FBSDKRestrictiveDataFilterManager processEvents:eventArray], - "Data filter manager should be able to process events with missing keys"); + XCTAssertNoThrow( + [FBSDKRestrictiveDataFilterManager processEvents:eventArray], + "Data filter manager should be able to process events with missing keys" + ); } - (void)testProcessEventDoesntReplaceEventNameIfNotRestricted { NSDictionary *> *event = @{ - @"event": @{ - @"_eventName": [NSNull null], + @"event" : @{ + @"_eventName" : [NSNull null], } }; NSMutableArray *eventArray = [[NSMutableArray alloc] initWithObjects:event, nil]; [FBSDKRestrictiveDataFilterManager processEvents:eventArray]; - XCTAssertEqual(event[@"event"][@"_eventName"], [NSNull null], - "Non-restricted event names should not be replaced"); + XCTAssertEqual( + event[@"event"][@"_eventName"], + [NSNull null], + "Non-restricted event names should not be replaced" + ); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m index e082a8b114..ba30b37052 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m @@ -18,8 +18,8 @@ #import +#import "FBSDKInternalUtility.h" #import "FBSDKRestrictiveData.h" -#import "FBSDKTypeUtility.h" @interface FBSDKRestrictiveDataTests : XCTestCase diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelParserTests.mm b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelParserTests.mm index c488fcd252..769c477d7e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelParserTests.mm +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelParserTests.mm @@ -38,15 +38,18 @@ @interface FBSDKModelParserTests : XCTestCase @implementation FBSDKModelParserTests -- (void)setUp { +- (void)setUp +{ _mockWeightsInfoDict = [[NSMutableDictionary alloc] init]; } -- (void)tearDown { +- (void)tearDown +{ [_mockWeightsInfoDict removeAllObjects]; } -- (void)testValidWeightsForMTML { +- (void)testValidWeightsForMTML +{ [_mockWeightsInfoDict addEntriesFromDictionary:[FBSDKModelParser getMTMLWeightsInfo]]; bool validatedRes = [FBSDKModelParser validateWeights:[self _mockWeightsWithRefDict:_mockWeightsInfoDict] @@ -55,7 +58,8 @@ - (void)testValidWeightsForMTML { XCTAssertTrue(validatedRes); } -- (void)testWeightsForMissingInfo { +- (void)testWeightsForMissingInfo +{ [_mockWeightsInfoDict removeAllObjects]; bool validatedRes = [FBSDKModelParser validateWeights:[self _mockWeightsWithRefDict:_mockWeightsInfoDict] @@ -64,7 +68,8 @@ - (void)testWeightsForMissingInfo { XCTAssertFalse(validatedRes); } -- (void)testWeightsForWrongInfo { +- (void)testWeightsForWrongInfo +{ [_mockWeightsInfoDict addEntriesFromDictionary:[FBSDKModelParser getMTMLWeightsInfo]]; [_mockWeightsInfoDict addEntriesFromDictionary:@{@"embed.weight" : @[@(1), @(1)]}]; @@ -74,9 +79,10 @@ - (void)testWeightsForWrongInfo { XCTAssertFalse(validatedRes); } -- (unordered_map)_mockWeightsWithRefDict:(NSDictionary *)dict { - unordered_map weights; - for (NSString* key in dict) { +- (unordered_map)_mockWeightsWithRefDict:(NSDictionary *)dict +{ + unordered_map weights; + for (NSString *key in dict) { NSArray *values = dict[key]; vector shape; for (NSNumber *val in values) { diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelRuntimeTests.mm b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelRuntimeTests.mm index f5db6c1322..260b2129d2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelRuntimeTests.mm +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ML/FBSDKModelRuntimeTests.mm @@ -20,9 +20,9 @@ #if !TARGET_OS_TV -#import + #import -#include "FBSDKModelRuntime.hpp" + #include "FBSDKModelRuntime.hpp" @interface FBSDKModelRuntimeTests : XCTestCase @@ -30,7 +30,8 @@ @interface FBSDKModelRuntimeTests : XCTestCase @implementation FBSDKModelRuntimeTests -- (void)testReLU { +- (void)testReLU +{ float input_data[2][4] = { {-1, -2, 1, 2}, {1, -0.2, 3.1, -0.5}, @@ -47,7 +48,8 @@ - (void)testReLU { [self AssertEqual:expected input:input]; } -- (void)testFlatten { +- (void)testFlatten +{ float input_data[2][2][5] = { { {1, 2, 3, 4, 5}, @@ -70,7 +72,8 @@ - (void)testFlatten { [self AssertEqual:expected input:input]; } -- (void)testConcatenate { +- (void)testConcatenate +{ float tensor1_data[2][2] = { {1, 2}, {3, 4}, @@ -99,7 +102,8 @@ - (void)testConcatenate { [self AssertEqual:expected input:fbsdk::concatenate(concat_tensors)]; } -- (void)testSoftMax { +- (void)testSoftMax +{ float input_data[2][2] = { {1, 1}, {1, 3}, @@ -116,7 +120,8 @@ - (void)testSoftMax { [self AssertEqual:expected input:input]; } -- (void)testEmbedding { +- (void)testEmbedding +{ char text[] = {"\1\2"}; float embeddings_data[3][3] = { {1, 0, 0}, @@ -136,9 +141,10 @@ - (void)testEmbedding { [self AssertEqual:expected input:fbsdk::embedding(text, 2, embeddings)]; } -- (void)testDenseExample1 { +- (void)testDenseExample1 +{ float input_data[2][3] = {{1, 2, 3}, {4, 5, 6}}; - float weight_data[3][2] = {{0, 1}, {1, 0},{-1, 1}}; + float weight_data[3][2] = {{0, 1}, {1, 0}, {-1, 1}}; float bias_data[2] = {100, 200}; float expected_data[2][2] = {{99, 204}, {99, 210}}; fbsdk::MTensor input({2, 3}); @@ -152,7 +158,8 @@ - (void)testDenseExample1 { [self AssertEqual:expected input:fbsdk::dense(input, weight, bias)]; } -- (void)testDenseExample2 { +- (void)testDenseExample2 +{ float input_data[1][2] = {{1, 2}}; float weight_data[2][3] = {{0, 3, -1}, {1, 0, -2}}; float bias_data[3] = {100, 200, 5}; @@ -168,7 +175,8 @@ - (void)testDenseExample2 { [self AssertEqual:expected input:fbsdk::dense(input, weight, bias)]; } -- (void)testConv1DExample1 { +- (void)testConv1DExample1 +{ float input_data[4][2][3] = { { {1, 2, 3}, @@ -214,7 +222,8 @@ - (void)testConv1DExample1 { [self AssertEqual:expected input:fbsdk::conv1D(input, conv)]; } -- (void)testConv1DExample2 { +- (void)testConv1DExample2 +{ float input_data[1][5][3] = { { {1, 2, 3}, @@ -257,7 +266,8 @@ - (void)testConv1DExample2 { [self AssertEqual:expected input:fbsdk::conv1D(input, conv)]; } -- (void)testConv1DExample3 { +- (void)testConv1DExample3 +{ float input_data[1][2][3] = { { {-1, -1, -1}, @@ -286,21 +296,24 @@ - (void)testConv1DExample3 { [self AssertEqual:expected input:fbsdk::conv1D(input, conv)]; } -- (void)testTextVectorizationLessThanMaxLen { +- (void)testTextVectorizationLessThanMaxLen +{ char strs[] = {"0123456"}; const std::vector expected{48, 49, 50, 51, 52, 53, 54, 0, 0, 0}; - const std::vector& res = fbsdk::vectorize(strs, 10); + const std::vector &res = fbsdk::vectorize(strs, 10); XCTAssertEqual(expected, res); } -- (void)testTextVectorizationLargerThanMaxLen { +- (void)testTextVectorizationLargerThanMaxLen +{ char strs[] = {"0123456"}; const std::vector expected{48, 49, 50}; - const std::vector& res = fbsdk::vectorize(strs, 3); + const std::vector &res = fbsdk::vectorize(strs, 3); XCTAssertEqual(expected, res); } -- (void)testTranspose3D { +- (void)testTranspose3D +{ float input_data[2][3][4] = { { {0, 1, 2, 3}, @@ -342,8 +355,9 @@ - (void)testTranspose3D { [self AssertEqual:expected input:fbsdk::transpose3D(input)]; } -- (void)testTranspose2D { - float input_data[3][4]= { +- (void)testTranspose2D +{ + float input_data[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}, @@ -361,7 +375,8 @@ - (void)testTranspose2D { [self AssertEqual:expected input:fbsdk::transpose2D(input)]; } -- (void)testAddmv { +- (void)testAddmv +{ float input_data[2][3][2] = { { {0, 12}, @@ -397,7 +412,8 @@ - (void)testAddmv { [self AssertEqual:expected input:input]; } -- (void)testMaxPool1DExample1 { +- (void)testMaxPool1DExample1 +{ float input_data[2][2][3] = { { {-1, 2, 3}, @@ -419,7 +435,8 @@ - (void)testMaxPool1DExample1 { [self AssertEqual:expected input:fbsdk::maxPool1D(input, 2)]; } -- (void)testMaxPool1DExample2 { +- (void)testMaxPool1DExample2 +{ float input_data[2][2][3] = { { {-1, -2, -3}, @@ -441,7 +458,8 @@ - (void)testMaxPool1DExample2 { [self AssertEqual:expected input:fbsdk::maxPool1D(input, 2)]; } -- (void)testMaxPool1DExample3 { +- (void)testMaxPool1DExample3 +{ float input_data[3][3][4] = { { {-1, -2, -3, 3}, @@ -471,11 +489,11 @@ - (void)testMaxPool1DExample3 { [self AssertEqual:expected input:fbsdk::maxPool1D(input, 3)]; } -- (void)AssertEqual:(const fbsdk::MTensor&)expected - input:(const fbsdk::MTensor&)input +- (void)AssertEqual:(const fbsdk::MTensor &)expected + input:(const fbsdk::MTensor &)input { - const std::vector& expected_sizes = expected.sizes(); - const std::vector& input_sizes = input.sizes(); + const std::vector &expected_sizes = expected.sizes(); + const std::vector &input_sizes = input.sizes(); XCTAssertEqual(expected_sizes, input_sizes); const float *expected_data = expected.data(); const float *input_data = input.data(); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/RawAppEventsConfigurationResponseFixtures.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/RawAppEventsConfigurationResponseFixtures.swift new file mode 100644 index 0000000000..e40a184e1c --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/RawAppEventsConfigurationResponseFixtures.swift @@ -0,0 +1,39 @@ +// 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 Foundation + +@objc +public class RawAppEventsConfigurationResponseFixtures: NSObject { + + enum Keys { + static let defaultATEStatus = "default_ate_status" + static let advertiserIDCollectionEnabled = "advertiser_id_collection_enabled" + static let eventCollectionEnabled = "event_collection_enabled" + } + + /// Provides a dictionary with well-known keys and random values for a network provided app events configuration + @objc + public class var random: [AnyHashable: Any] { + return [ + Keys.defaultATEStatus: Fuzzer.random, + Keys.advertiserIDCollectionEnabled: Fuzzer.random, + Keys.eventCollectionEnabled: Fuzzer.random, + ] + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m new file mode 100644 index 0000000000..4afd96586f --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m @@ -0,0 +1,385 @@ +// 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 + +#if !TARGET_OS_TV + + #import "FBSDKSKAdNetworkConversionConfiguration.h" + #import "FBSDKSKAdNetworkRule.h" + #import "FBSDKTestCase.h" + #import "FBSDKTypeUtility.h" + +@interface FBSDKSKAdNetworkConversionConfiguration () + ++ (nullable NSArray *)parseRules:(nullable NSArray *)rules; + +@end + +@interface FBSDKSKAdNetworkConversionConfigurationTests : FBSDKTestCase + +@end + +@implementation FBSDKSKAdNetworkConversionConfigurationTests + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +- (void)testInit +{ + // Init with nil + FBSDKSKAdNetworkConversionConfiguration *config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:nil]; + XCTAssertNil(config); + + // Init with invalid data + id invalidData = @[]; + config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:(NSDictionary *)invalidData]; + XCTAssertNil(config); + + invalidData = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"default_currency" : @"usd", + @"cutoff_time" : @(2), + }] + }; + config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:(NSDictionary *)invalidData]; + XCTAssertNil(config); + + invalidData = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"cutoff_time" : @(2), + @"conversion_value_rules" : @[], + }] + }; + config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:(NSDictionary *)invalidData]; + XCTAssertNil(config); + + // Init with valid data + NSDictionary *validData = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"default_currency" : @"usd", + @"cutoff_time" : @(2), + @"conversion_value_rules" : @[], + }] + }; + config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:validData]; + XCTAssertEqual(1, config.timerBuckets); + XCTAssertEqual(2, config.cutoffTime); + XCTAssertTrue([config.defaultCurrency isEqualToString:@"USD"]); + XCTAssertEqualWithAccuracy(1000, config.timerInterval, 0.001); +} + +- (void)testParseRules +{ + NSArray *> *rules = @[ + @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + } + ], + }, + @{ + @"conversion_value" : @(4), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + } + ], + }, + @{ + @"conversion_value" : @(3), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + }, + @{ + @"currency" : @"JPY", + @"amount" : @(100) + } + ] + } + ], + }, + ]; + + NSArray *conversionBitRules = [FBSDKSKAdNetworkConversionConfiguration parseRules:rules]; + NSMutableArray *expected = [NSMutableArray new]; + [FBSDKTypeUtility array:expected addObject:[[FBSDKSKAdNetworkRule alloc] initWithJSON:@{ + @"conversion_value" : @(4), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + } + ], + }]]; + [FBSDKTypeUtility array:expected addObject:[[FBSDKSKAdNetworkRule alloc] initWithJSON:@{ + @"conversion_value" : @(3), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + }, + @{ + @"currency" : @"JPY", + @"amount" : @(100) + } + ] + } + ], + }]]; + [FBSDKTypeUtility array:expected addObject:[[FBSDKSKAdNetworkRule alloc] initWithJSON:@{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + } + ], + }]]; + for (NSUInteger i = 0; i < expected.count; i++) { + FBSDKSKAdNetworkRule *expectedRule = [FBSDKTypeUtility array:expected objectAtIndex:i]; + FBSDKSKAdNetworkRule *parsedRule = [FBSDKTypeUtility array:conversionBitRules objectAtIndex:i]; + XCTAssertNotNil(parsedRule); + XCTAssertEqual(expectedRule.conversionValue, parsedRule.conversionValue); + XCTAssertEqual(expectedRule.events.count, parsedRule.events.count); + for (NSUInteger j = 0; j < expectedRule.events.count; j++) { + FBSDKSKAdNetworkEvent *expectedEvent = [FBSDKTypeUtility array:expectedRule.events objectAtIndex:j]; + FBSDKSKAdNetworkEvent *parsedEvent = [FBSDKTypeUtility array:parsedRule.events objectAtIndex:j]; + XCTAssertTrue([expectedEvent.eventName isEqualToString:parsedEvent.eventName]); + if (expectedEvent.values) { + XCTAssertTrue([expectedEvent.values isEqualToDictionary:parsedEvent.values]); + } else { + XCTAssertNil(parsedEvent.values); + } + } + } + + // Invalid cases + id invalidData = nil; + XCTAssertNil([FBSDKSKAdNetworkConversionConfiguration parseRules:invalidData]); + invalidData = @{}; + XCTAssertNil([FBSDKSKAdNetworkConversionConfiguration parseRules:invalidData]); + invalidData = @[ + @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"amount" : @(100) + }, + ] + } + ], + }, + @{ + @"conversion_value" : @(3), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + }, + ] + } + ], + }, + ]; + XCTAssertEqual(1, [FBSDKSKAdNetworkConversionConfiguration parseRules:invalidData].count); +} + +- (void)testEventSet +{ + NSDictionary *data = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"cutoff_time" : @(2), + @"default_currency" : @"usd", + @"conversion_value_rules" : @[ + @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + } + ], + }, + @{ + @"conversion_value" : @(4), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + }, + @{ + @"event_name" : @"fb_mobile_complete_registration", + @"values" : @[ + @{ + @"currency" : @"EU", + @"amount" : @(100) + } + ] + }, + ], + }, + @{ + @"conversion_value" : @(3), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + }, + @{ + @"currency" : @"JPY", + @"amount" : @(100) + } + ] + }, + @{ + @"event_name" : @"fb_mobile_search", + } + ], + }, + ] + }] + }; + + FBSDKSKAdNetworkConversionConfiguration *config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:data]; + NSSet *expected = [NSSet setWithArray:@[@"fb_mobile_search", @"fb_mobile_purchase", @"fb_mobile_complete_registration"]]; + XCTAssertTrue([config.eventSet isEqualToSet:expected]); +} + +- (void)testCurrencySet +{ + NSDictionary *data = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"cutoff_time" : @(2), + @"default_currency" : @"usd", + @"conversion_value_rules" : @[ + @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + } + ], + }, + @{ + @"conversion_value" : @(4), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + }, + @{ + @"event_name" : @"fb_mobile_complete_registration", + @"values" : @[ + @{ + @"currency" : @"eu", + @"amount" : @(100) + } + ] + }, + ], + }, + @{ + @"conversion_value" : @(3), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"usd", + @"amount" : @(100) + }, + @{ + @"currency" : @"jpy", + @"amount" : @(100) + } + ] + }, + @{ + @"event_name" : @"fb_mobile_search", + } + ], + }, + ] + }] + }; + + FBSDKSKAdNetworkConversionConfiguration *config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:data]; + NSSet *expected = [NSSet setWithArray:@[@"USD", @"EU", @"JPY"]]; + XCTAssertTrue([config.currencySet isEqualToSet:expected]); +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m new file mode 100644 index 0000000000..9614273898 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m @@ -0,0 +1,103 @@ +// 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 + +#if !TARGET_OS_TV + + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKSKAdNetworkEvent.h" + #import "FBSDKTestCase.h" + +@interface FBSDKSKAdNetworkEventTests : FBSDKTestCase + +@end + +@implementation FBSDKSKAdNetworkEventTests + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +- (void)testInit +{ + // Valid cases + FBSDKSKAdNetworkEvent *event = [[FBSDKSKAdNetworkEvent alloc] initWithJSON:@{@"event_name" : @"fb_mobile_purchase"}]; + XCTAssertTrue([event.eventName isEqualToString:@"fb_mobile_purchase"]); + XCTAssertNil(event.values); + event = [[FBSDKSKAdNetworkEvent alloc] initWithJSON:@{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"usd", + @"amount" : @(100) + }, + @{ + @"currency" : @"JPY", + @"amount" : @(1000) + } + ] + }]; + XCTAssertTrue([event.eventName isEqualToString:@"fb_mobile_purchase"]); + NSDictionary *expectedValues = @{@"USD" : @(100), @"JPY" : @(1000)}; + XCTAssertTrue([event.values isEqualToDictionary:expectedValues]); + + // Invalid cases + id invalidData = nil; + XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); + invalidData = @[]; + XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); + invalidData = @{ + @"values" : @[ + @{ + @"currency" : @"usd", + @"amount" : @(100) + }, + @{ + @"currency" : @"JPY", + @"amount" : @(1000) + } + ] + }; + XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); + invalidData = @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @(100), + @"amount" : @"usd" + }, + @{ + @"currency" : @(1000), + @"amount" : @"jpy" + } + ] + }; + XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkReporterTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkReporterTests.m new file mode 100644 index 0000000000..3082c50d25 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkReporterTests.m @@ -0,0 +1,221 @@ +// 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 + +#if !TARGET_OS_TV + + #import + + #import "FBSDKSKAdNetworkConversionConfiguration.h" + #import "FBSDKSKAdNetworkReporter.h" + #import "FBSDKSettings+Internal.h" + #import "FBSDKTestCase.h" + #import "UserDefaultsSpy.h" + +static NSString *const FBSDKSettingsInstallTimestamp = @"com.facebook.sdk:FBSDKSettingsInstallTimestamp"; +static NSString *const FBSDKSKAdNetworkReporterKey = @"com.facebook.sdk:FBSDKSKAdNetworkReporter"; + +@interface FBSDKSKAdNetworkReporter () + ++ (void)setConfiguration:(FBSDKSKAdNetworkConversionConfiguration *)configuration; ++ (void)_loadReportData; ++ (BOOL)_shouldCutoff; ++ (void)_recordAndUpdateEvent:(NSString *)event + currency:(nullable NSString *)currency + value:(nullable NSNumber *)value; ++ (void)_updateConversionValue:(NSInteger)value; + ++ (void)setSKAdNetworkReportEnabled:(BOOL)enabled; + +@end + +@interface FBSDKSKAdNetworkReporterTests : FBSDKTestCase + +@end + +@implementation FBSDKSKAdNetworkReporterTests +{ + UserDefaultsSpy *userDefaultsSpy; + FBSDKSKAdNetworkConversionConfiguration *defaultConfiguration; +} + +- (void)setUp +{ + [super setUp]; + + userDefaultsSpy = [UserDefaultsSpy new]; + [self stubUserDefaultsWith:userDefaultsSpy]; + + NSDictionary *json = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"cutoff_time" : @(1), + @"default_currency" : @"usd", + @"conversion_value_rules" : @[], + }] + }; + defaultConfiguration = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:json]; + + [FBSDKSKAdNetworkReporter _loadReportData]; + [FBSDKSKAdNetworkReporter setSKAdNetworkReportEnabled:YES]; + + [self stubLoadingAdNetworkReporterConfiguration]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +- (void)testShouldCutoffWithoutTimestampWithoutCutoffTime +{ + XCTAssertTrue([FBSDKSKAdNetworkReporter _shouldCutoff], "Should cut off reporting when there is no install timestamp or cutoff time"); +} + +- (void)testShouldCutoffWithoutTimestampWithCutoffTime +{ + [FBSDKSKAdNetworkReporter setConfiguration:defaultConfiguration]; + + XCTAssertFalse([FBSDKSKAdNetworkReporter _shouldCutoff], "Should not cut off reporting when there is no install timestamp"); +} + +- (void)testShouldCutoffWithTimestampWithoutCutoffTime +{ + [userDefaultsSpy setObject:NSDate.distantPast forKey:FBSDKSettingsInstallTimestamp]; + XCTAssertTrue( + [FBSDKSKAdNetworkReporter _shouldCutoff], + "Should cut off reporting when when the timestamp is earlier than the current date and there's no cutoff date provided" + ); + [userDefaultsSpy setObject:NSDate.distantFuture forKey:FBSDKSettingsInstallTimestamp]; + XCTAssertTrue( + [FBSDKSKAdNetworkReporter _shouldCutoff], + "Should cut off reporting when the timestamp is later than the current date and there's no cutoff date provided" + ); +} + +- (void)testShouldCutoffWhenTimestampEarlierThanCutoffTime +{ + [FBSDKSKAdNetworkReporter setConfiguration:defaultConfiguration]; + [userDefaultsSpy setObject:NSDate.distantPast forKey:FBSDKSettingsInstallTimestamp]; + + XCTAssertTrue( + [FBSDKSKAdNetworkReporter _shouldCutoff], + "Should cut off reporting when the install timestamp is one day before the cutoff date" + ); +} + +- (void)testShouldCutoffWhenTimestampLaterThanCutoffTime +{ + [FBSDKSKAdNetworkReporter setConfiguration:defaultConfiguration]; + [userDefaultsSpy setObject:NSDate.distantFuture forKey:FBSDKSettingsInstallTimestamp]; + + XCTAssertFalse( + [FBSDKSKAdNetworkReporter _shouldCutoff], + "Should not cut off reporting when the install timestamp is more than one day later than the cutoff date" + ); +} + +- (void)testShouldCutoff +{ + [FBSDKSKAdNetworkReporter setConfiguration:defaultConfiguration]; + + // Case 1: refresh install + [FBSDKSettings recordInstall]; + XCTAssertFalse([FBSDKSKAdNetworkReporter _shouldCutoff]); + + // Case 2: timestamp is already expired + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *addComponents = [NSDateComponents new]; + addComponents.day = -2; + NSDate *expiredDate = [calendar dateByAddingComponents:addComponents toDate:[NSDate date] options:0]; + [[NSUserDefaults standardUserDefaults] setObject:expiredDate forKey:FBSDKSettingsInstallTimestamp]; + XCTAssertTrue([FBSDKSKAdNetworkReporter _shouldCutoff]); + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:FBSDKSettingsInstallTimestamp]; +} + +- (void)testCutoffWhenTimeBucketIsAvailable +{ + if (@available(iOS 14, *)) { + id mock = OCMClassMock([SKAdNetwork class]); + [FBSDKSKAdNetworkReporter setConfiguration:defaultConfiguration]; + NSDate *today = [NSDate date]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *addComponents = [NSDateComponents new]; + addComponents.day = -2; + NSDate *expiredDate = [calendar dateByAddingComponents:addComponents toDate:today options:0]; + [userDefaultsSpy setObject:expiredDate forKey:FBSDKSettingsInstallTimestamp]; + + XCTAssertTrue([FBSDKSKAdNetworkReporter _shouldCutoff]); + [FBSDKSKAdNetworkReporter checkAndRevokeTimer]; + XCTAssertNil([userDefaultsSpy objectForKey:FBSDKSKAdNetworkReporterKey]); + + [mock reject]; + + [userDefaultsSpy removeObjectForKey:FBSDKSettingsInstallTimestamp]; + } +} + +- (void)testRecord +{ + if (@available(iOS 14, *)) { + NSDictionary *json = @{ + @"data" : @[@{ + @"timer_buckets" : @(1), + @"timer_interval" : @(1000), + @"cutoff_time" : @(1), + @"default_currency" : @"USD", + @"conversion_value_rules" : @[ + @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_test", + } + ], + }], + }] + }; + FBSDKSKAdNetworkConversionConfiguration *config = [[FBSDKSKAdNetworkConversionConfiguration alloc] initWithJSON:json]; + [FBSDKSKAdNetworkReporter setConfiguration:config]; + [FBSDKSKAdNetworkReporter _recordAndUpdateEvent:@"fb_test" currency:nil value:nil]; + [FBSDKSKAdNetworkReporter _recordAndUpdateEvent:@"fb_mobile_purchase" currency:@"USD" value:@(100)]; + [FBSDKSKAdNetworkReporter _recordAndUpdateEvent:@"fb_mobile_purchase" currency:@"USD" value:@(201)]; + [FBSDKSKAdNetworkReporter _recordAndUpdateEvent:@"test" currency:nil value:nil]; + NSData *cache = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSKAdNetworkReporterKey]; + XCTAssertNotNil(cache); + NSDictionary *data = [FBSDKTypeUtility dictionaryValue:[NSKeyedUnarchiver unarchiveObjectWithData:cache]]; + NSMutableSet *recordedEvents = [FBSDKTypeUtility dictionary:data objectForKey:@"recorded_events" ofType:NSMutableSet.class]; + NSSet *expectedEvents = [NSSet setWithArray:@[@"fb_test", @"fb_mobile_purchase"]]; + XCTAssertTrue([expectedEvents isEqualToSet:recordedEvents]); + NSMutableDictionary *recordedValues = [FBSDKTypeUtility dictionary:data objectForKey:@"recorded_values" ofType:NSMutableDictionary.class]; + NSDictionary *expectedValues = @{ + @"fb_mobile_purchase" : @{ + @"USD" : @(301) + } + }; + XCTAssertTrue([expectedValues isEqualToDictionary:recordedValues]); + } +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m new file mode 100644 index 0000000000..ba5f739aaf --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m @@ -0,0 +1,170 @@ +// 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 + +#if !TARGET_OS_TV + + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKSKAdNetworkEvent.h" + #import "FBSDKSKAdNetworkRule.h" + #import "FBSDKTestCase.h" + +@interface FBSDKSKAdNetworkRuleTests : FBSDKTestCase + +@end + +@implementation FBSDKSKAdNetworkRuleTests + +- (void)testInit +{ + // Valid cases + NSDictionary *validData = @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + }, + @{ + @"event_name" : @"Donate", + } + ], + }; + FBSDKSKAdNetworkRule *rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:validData]; + XCTAssertEqual(2, rule.conversionValue); + XCTAssertEqual(2, rule.events.count); + FBSDKSKAdNetworkEvent *event1 = [FBSDKTypeUtility array:rule.events objectAtIndex:0]; + FBSDKSKAdNetworkEvent *event2 = [FBSDKTypeUtility array:rule.events objectAtIndex:1]; + XCTAssertTrue([event1.eventName isEqualToString:@"fb_mobile_purchase"]); + XCTAssertNil(event1.values); + XCTAssertTrue([event2.eventName isEqualToString:@"Donate"]); + XCTAssertNil(event2.values); + + validData = @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + } + ], + }; + rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:validData]; + XCTAssertEqual(2, rule.conversionValue); + XCTAssertEqual(1, rule.events.count); + XCTAssertEqual(1, rule.events.count); + event1 = [FBSDKTypeUtility array:rule.events objectAtIndex:0]; + XCTAssertTrue([event1.eventName isEqualToString:@"fb_mobile_purchase"]); + XCTAssertTrue([event1.values isEqualToDictionary:@{@"USD" : @(100)}]); + + // Invalid cases + id invalidData = nil; + XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); + invalidData = @[]; + XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); + invalidData = @{ + @"conversion_value" : @(2), + }; + XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); + invalidData = @{ + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + } + ], + }; + XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); + invalidData = @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @(100), + @"amount" : @"USD" + } + ] + } + ], + }; + XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); +} + +- (void)testRuleMatch +{ + NSDictionary *ruleData = @{ + @"conversion_value" : @(2), + @"events" : @[ + @{ + @"event_name" : @"fb_skadnetwork_test1", + }, + @{ + @"event_name" : @"fb_mobile_purchase", + @"values" : @[ + @{ + @"currency" : @"USD", + @"amount" : @(100) + } + ] + } + ], + }; + FBSDKSKAdNetworkRule *rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:ruleData]; + + NSSet *matchedEventSet = [NSSet setWithArray:@[@"fb_mobile_purchase", @"fb_skadnetwork_test1", @"fb_adnetwork_test2"]]; + NSSet *unmatchedEventSet = [NSSet setWithArray:@[@"fb_mobile_purchase", @"fb_skadnetwork_test2"]]; + XCTAssertTrue( + [rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:@{ + @"fb_mobile_purchase" : @{@"USD" : @(1000)} + }] + ); + XCTAssertFalse([rule isMatchedWithRecordedEvents:[NSSet new] recordedValues:[NSDictionary new]]); + XCTAssertFalse([rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:[NSDictionary new]]); + XCTAssertFalse( + [rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:@{ + @"fb_mobile_purchase" : @{@"USD" : @(50)} + }] + ); + XCTAssertFalse( + [rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:@{ + @"fb_mobile_purchase" : @{@"JPY" : @(1000)} + }] + ); + XCTAssertFalse( + [rule isMatchedWithRecordedEvents:unmatchedEventSet recordedValues:@{ + @"fb_mobile_purchase" : @{@"USD" : @(1000)} + }] + ); +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m index 8d9e79dd20..ccb5b0d35c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m @@ -16,15 +16,14 @@ // 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 "FBSDKCoreKitTests-Swift.h" #import "FBSDKFeatureExtractor.h" +#import "FBSDKInternalUtility.h" #import "FBSDKModelManager.h" #import "FBSDKViewHierarchyMacros.h" -#import "FBSDKCoreKitTests-Swift.h" -#import "FBSDKTypeUtility.h" @interface FBSDKFeatureExtractor () + (BOOL)pruneTree:(NSMutableDictionary *)node @@ -51,7 +50,8 @@ + (float)regextMatch:(NSString *)pattern @end -@interface FBSDKFeatureExtractorTests : XCTestCase { +@interface FBSDKFeatureExtractorTests : XCTestCase +{ NSDictionary *_rules; NSDictionary *_viewHierarchy; NSDictionary *_interactedNode; @@ -75,171 +75,171 @@ - (void)setUp [FBSDKFeatureExtractor loadRulesForKey:@"MTML"]; _viewHierarchy = @{ - @"screenname": @"UITabBarController", - @"view": @[ - @{ - @"classname": @"UIWindow", - @"classtypebitmask": @"0", - @"childviews": @[ + @"screenname" : @"UITabBarController", + @"view" : @[ + @{ + @"classname" : @"UIWindow", + @"classtypebitmask" : @"0", + @"childviews" : @[ + @{ + @"classname" : @"UITabBarController", + @"classtypebitmask" : @"131072", + @"childviews" : @[ @{ - @"classname": @"UITabBarController", - @"classtypebitmask": @"131072", - @"childviews": @[ - @{ - @"classname": @"UINavigationController", - @"classtypebitmask": @"131072", - @"childviews": @[ + @"classname" : @"UINavigationController", + @"classtypebitmask" : @"131072", + @"childviews" : @[ + @{ + @"classname" : @"CheckoutViewController", + @"classtypebitmask" : @"131072", + @"childviews" : @[ + @{ + @"classname" : @"UIStackView", + @"classtypebitmask" : @"0", + @"childviews" : @[ @{ - @"classname": @"CheckoutViewController", - @"classtypebitmask": @"131072", - @"childviews": @[ - @{ - @"classname": @"UIStackView", - @"classtypebitmask": @"0", - @"childviews": @[ - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Order Summary", - }, - @{ - @"classname": @"UIStackView", - @"classtypebitmask": @"0", - @"childviews": @[ - @{ - @"classname": @"UIView", - @"classtypebitmask": @"0", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Coffee 5", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"Price: $5.99", - }, - ] - }, - @{ - @"classname": @"UIStackView", - @"classtypebitmask": @"0", - @"childviews": @[ - @{ - @"classname": @"UIView", - @"classtypebitmask": @"0", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Quantity", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1", - }, - ] - }, - @{ - @"classname": @"UITextField", - @"classtypebitmask": @"2056", - @"hint": @"Credit Card Credit Card", - }, - @{ - @"classname": @"UITextField", - @"classtypebitmask": @"2056", - @"hint": @"Shipping Address Shipping Address", - }, - @{ - @"classname": @"UIButton", - @"classtypebitmask": @"24", - @"is_interacted": @1, - @"hint": @"Confirm Order", - }, - ] - } + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Order Summary", + }, + @{ + @"classname" : @"UIStackView", + @"classtypebitmask" : @"0", + @"childviews" : @[ + @{ + @"classname" : @"UIView", + @"classtypebitmask" : @"0", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Coffee 5", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"Price: $5.99", + }, + ] + }, + @{ + @"classname" : @"UIStackView", + @"classtypebitmask" : @"0", + @"childviews" : @[ + @{ + @"classname" : @"UIView", + @"classtypebitmask" : @"0", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Quantity", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1", + }, ] - } - ] - }, - @{ - @"classname": @"UITabBar", - @"classtypebitmask": @"0", - } + }, + @{ + @"classname" : @"UITextField", + @"classtypebitmask" : @"2056", + @"hint" : @"Credit Card Credit Card", + }, + @{ + @"classname" : @"UITextField", + @"classtypebitmask" : @"2056", + @"hint" : @"Shipping Address Shipping Address", + }, + @{ + @"classname" : @"UIButton", + @"classtypebitmask" : @"24", + @"is_interacted" : @1, + @"hint" : @"Confirm Order", + }, + ] + } + ] + } ] + }, + @{ + @"classname" : @"UITabBar", + @"classtypebitmask" : @"0", } - ] - } + ] + } + ] + } ] }; _interactedNode = @{ - @"classname": @"UIButton", - @"classtypebitmask": @"24", - @"is_interacted": @1, - @"hint": @"Confirm Order", + @"classname" : @"UIButton", + @"classtypebitmask" : @"24", + @"is_interacted" : @1, + @"hint" : @"Confirm Order", }; _siblings = @[ - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Order Summary", - }, - @{ - @"classname": @"UIStackView", - @"classtypebitmask": @"0", - @"childviews": @[ - @{ - @"classname": @"UIView", - @"classtypebitmask": @"0", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Coffee 5", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"Price: $5.99", - }, - ] - }, - @{ - @"classname": @"UIStackView", - @"classtypebitmask": @"0", - @"childviews": @[ - @{ - @"classname": @"UIView", - @"classtypebitmask": @"0", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Quantity", - }, - @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1", - }, - ] - }, - @{ - @"classname": @"UITextField", - @"classtypebitmask": @"2056", - @"hint": @"Credit Card Credit Card", - }, - @{ - @"classname": @"UITextField", - @"classtypebitmask": @"2056", - @"hint": @"Shipping Address Shipping Address", - }, - @{ - @"classname": @"UIButton", - @"classtypebitmask": @"24", - @"is_interacted": @1, - @"hint": @"Confirm Order", - }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Order Summary", + }, + @{ + @"classname" : @"UIStackView", + @"classtypebitmask" : @"0", + @"childviews" : @[ + @{ + @"classname" : @"UIView", + @"classtypebitmask" : @"0", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Coffee 5", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"Price: $5.99", + }, + ] + }, + @{ + @"classname" : @"UIStackView", + @"classtypebitmask" : @"0", + @"childviews" : @[ + @{ + @"classname" : @"UIView", + @"classtypebitmask" : @"0", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Quantity", + }, + @{ + @"classname" : @"UILabel", + @"classtypebitmask" : @"1", + }, + ] + }, + @{ + @"classname" : @"UITextField", + @"classtypebitmask" : @"2056", + @"hint" : @"Credit Card Credit Card", + }, + @{ + @"classname" : @"UITextField", + @"classtypebitmask" : @"2056", + @"hint" : @"Shipping Address Shipping Address", + }, + @{ + @"classname" : @"UIButton", + @"classtypebitmask" : @"24", + @"is_interacted" : @1, + @"hint" : @"Confirm Order", + }, ]; } @@ -253,8 +253,8 @@ - (void)testGetDenseFeature // Get dense feature string NSMutableArray *denseFeatureArray = [NSMutableArray array]; - for (int i=0; i < 30; i++) { - [denseFeatureArray addObject:[NSNumber numberWithFloat: denseFeature[i]]]; + for (int i = 0; i < 30; i++) { + [denseFeatureArray addObject:[NSNumber numberWithFloat:denseFeature[i]]]; } XCTAssertEqualObjects([denseFeatureArray componentsJoinedByString:@","], @"0,0,0,5,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); @@ -289,8 +289,8 @@ - (void)testNonparseFeature } NSString *viewTreeString = [[NSString alloc] initWithData:[FBSDKTypeUtility dataWithJSONObject:[_viewHierarchy[VIEW_HIERARCHY_VIEW_KEY] mutableCopy] - options:0 - error:nil] + options:0 + error:nil] encoding:NSUTF8StringEncoding]; float *nonParseFeature = [FBSDKFeatureExtractor nonparseFeatures:[_interactedNode mutableCopy] siblings:[_siblings mutableCopy] @@ -299,8 +299,8 @@ - (void)testNonparseFeature // Get non-parsed feature string NSMutableArray *nonParseFeatureArray = [NSMutableArray array]; - for (int i=0; i < 30; i++) { - [nonParseFeatureArray addObject:[NSNumber numberWithFloat: nonParseFeature[i]]]; + for (int i = 0; i < 30; i++) { + [nonParseFeatureArray addObject:[NSNumber numberWithFloat:nonParseFeature[i]]]; } XCTAssertEqualObjects([nonParseFeatureArray componentsJoinedByString:@","], @"0,0,0,5,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); @@ -316,8 +316,8 @@ - (void)testParseFeature // Get parsed feature string NSMutableArray *parseFeatureArray = [NSMutableArray array]; - for (int i=0; i < 30; i++) { - [parseFeatureArray addObject:[NSNumber numberWithFloat: parseFeature[i]]]; + for (int i = 0; i < 30; i++) { + [parseFeatureArray addObject:[NSNumber numberWithFloat:parseFeature[i]]]; } XCTAssertEqualObjects([parseFeatureArray componentsJoinedByString:@","], @"0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"); @@ -326,9 +326,9 @@ - (void)testParseFeature - (void)testIsButton { NSDictionary *labelNode = @{ - @"classname": @"UILabel", - @"classtypebitmask": @"1024", - @"text": @"Coffee 5", + @"classname" : @"UILabel", + @"classtypebitmask" : @"1024", + @"text" : @"Coffee 5", }; XCTAssertEqual([FBSDKFeatureExtractor isButton:_interactedNode], true); XCTAssertEqual([FBSDKFeatureExtractor isButton:labelNode], false); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m index a0406f4baa..cd95373c5d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m @@ -16,15 +16,15 @@ // 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 #import "FBSDKViewHierarchy.h" -@interface FBSDKViewHierarchyTests : XCTestCase { +@interface FBSDKViewHierarchyTests : XCTestCase +{ UIScrollView *scrollview; UILabel *label; UITextField *textField; @@ -33,6 +33,23 @@ @interface FBSDKViewHierarchyTests : XCTestCase { } @end +id getVariableFromInstance(NSObject *instance, NSString *variableName); + +@interface TestObj : NSObject @end +@implementation TestObj +{ + NSString *_a; +} +- (instancetype)init +{ + if (self = [super init]) { + _a = @"BLAH"; + } + return self; +} + +@end + @implementation FBSDKViewHierarchyTests - (void)setUp @@ -101,4 +118,17 @@ - (void)testGetHint XCTAssertEqualObjects([FBSDKViewHierarchy getHint:NC], @"UIViewController"); } +- (void)testGetInstanceVariable +{ + // empty args should cause no-op. + XCTAssertNil(getVariableFromInstance(nil, @"anything prop")); + XCTAssertNil(getVariableFromInstance([NSObject new], nil)); + + // If there is no ivar, should return nil. + XCTAssertNil(getVariableFromInstance([NSObject new], @"some_made_up_property_123456")); + + // this should work. + XCTAssertEqualObjects(getVariableFromInstance([TestObj new], @"_a"), @"BLAH"); +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m index a4f4df0c8b..4eac74e3a9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m @@ -16,9 +16,8 @@ // 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 #import @@ -84,30 +83,30 @@ - (void)stubMatchingRequestsWithResponses:(NSDictionary *)reques StringURLBlock matchingKey = ^id (NSString *urlString) { for (NSString *substring in requestsAndResponses.allKeys) { // The first @"" always matches - if (substring.length == 0 || - [urlString rangeOfString:substring].location != NSNotFound) { + if (substring.length == 0 + || [urlString rangeOfString:substring].location != NSNotFound) { return substring; } } return nil; }; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - if (callback) { - callback(request); - } - - return matchingKey(request.URL.absoluteString) != nil; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - id result = requestsAndResponses[matchingKey(request.URL.absoluteString)]; - NSData *data = [[FBSDKBasicUtility JSONStringForObject:result - error:NULL - invalidObjectHandler:NULL] dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:statusCode - headers:nil]; - }]; + [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { + if (callback) { + callback(request); + } + + return matchingKey(request.URL.absoluteString) != nil; + } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { + id result = requestsAndResponses[matchingKey(request.URL.absoluteString)]; + NSData *data = [[FBSDKBasicUtility JSONStringForObject:result + error:NULL + invalidObjectHandler:NULL] dataUsingEncoding:NSUTF8StringEncoding]; + + return [OHHTTPStubsResponse responseWithData:data + statusCode:statusCode + headers:nil]; + }]; } #pragma mark - test cases diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m index fe8d3bbbd0..b1881e0b99 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m @@ -17,7 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import - #import #import "FBSDKBase64.h" @@ -39,14 +38,14 @@ - (void)runTests:(NSDictionary *)tests - (void)testRFC4648TestVectors { [self runTests:@{ - @"": @"", - @"f": @"Zg==", - @"fo": @"Zm8=", - @"foo": @"Zm9v", - @"foob": @"Zm9vYg==", - @"fooba": @"Zm9vYmE=", - @"foobar": @"Zm9vYmFy", - }]; + @"" : @"", + @"f" : @"Zg==", + @"fo" : @"Zm8=", + @"foo" : @"Zm9v", + @"foob" : @"Zm9vYg==", + @"fooba" : @"Zm9vYmE=", + @"foobar" : @"Zm9vYmFy", + }]; } - (void)testDecodeVariations @@ -60,10 +59,10 @@ - (void)testDecodeVariations - (void)testEncodeDecode { [self runTests:@{ - @"Hello World": @"SGVsbG8gV29ybGQ=", - @"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!%^&*(){}[]": @"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoxMjM0NTY3ODkwISVeJiooKXt9W10=", - @"\n\t Line with control characters\r\n": @"CgkgTGluZSB3aXRoIGNvbnRyb2wgY2hhcmFjdGVycw0K", - }]; + @"Hello World" : @"SGVsbG8gV29ybGQ=", + @"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!%^&*(){}[]" : @"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoxMjM0NTY3ODkwISVeJiooKXt9W10=", + @"\n\t Line with control characters\r\n" : @"CgkgTGluZSB3aXRoIGNvbnRyb2wgY2hhcmFjdGVycw0K", + }]; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKBasicUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKBasicUtilityTests.m index d92d2f522a..ce11689a53 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKBasicUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKBasicUtilityTests.m @@ -17,8 +17,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import -#import "FBSDKBasicUtility.h" #import "FBSDKCoreKit.h" +#import "FBSDKInternalUtility.h" @interface FBSDKBasicUtilityTests : XCTestCase @end @@ -30,8 +30,8 @@ - (void)testJSONString NSString *URLString = @"https://www.facebook.com"; NSURL *URL = [NSURL URLWithString:URLString]; NSDictionary *dictionary = @{ - @"url": URL, - }; + @"url" : URL, + }; NSError *error; NSString *JSONString = [FBSDKBasicUtility JSONStringForObject:dictionary error:&error invalidObjectHandler:NULL]; XCTAssertNil(error); @@ -49,7 +49,7 @@ - (void)testConvertRequestValue XCTAssertTrue([result1 isKindOfClass:[NSString class]]); XCTAssertEqualObjects(result1, @"1"); - NSURL *value2= [NSURL URLWithString:@"https://test"]; + NSURL *value2 = [NSURL URLWithString:@"https://test"]; id result2 = [FBSDKBasicUtility convertRequestValue:value2]; XCTAssertTrue([result2 isKindOfClass:[NSString class]]); XCTAssertEqualObjects(result2, @"https://test"); @@ -64,10 +64,10 @@ - (void)testQueryString NSURL *URL = [NSURL URLWithString:@"http://example.com/path/to/page.html?key1&key2=value2&key3=value+3%20%3D%20foo#fragment=go"]; NSDictionary *dictionary = [FBSDKBasicUtility dictionaryWithQueryString:URL.query]; NSDictionary *expectedDictionary = @{ - @"key1": @"", - @"key2": @"value2", - @"key3": @"value 3 = foo", - }; + @"key1" : @"", + @"key2" : @"value2", + @"key3" : @"value 3 = foo", + }; XCTAssertEqualObjects(dictionary, expectedDictionary); NSString *queryString = [FBSDKBasicUtility queryStringWithDictionary:dictionary error:NULL invalidObjectHandler:NULL]; NSString *expectedQueryString = @"key1=&key2=value2&key3=value%203%20%3D%20foo"; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m index 75ed8a48d6..a3d961ef8c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m @@ -16,11 +16,13 @@ // 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 +#include -#import "FBSDKCrashHandler.h" +#import "FBSDKCrashObserver.h" +#import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" @interface FBSDKCrashHandler () @@ -33,6 +35,8 @@ + (BOOL)callstack:(NSArray *)callstack containsPrefix:(NSArray *)prefixList; + (NSArray *> *)filterCrashLogs:(NSArray *)prefixList processedCrashLogs:(NSArray *> *)processedCrashLogs; ++ (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack; ++ (void)saveCrashLog:(NSDictionary *)crashLog; @end @@ -43,15 +47,19 @@ @implementation FBSDKCrashHandlerTests - (void)setUp { - [FBSDKCrashHandler initialize]; + [FBSDKCrashObserver enable]; } -- (void)testDisable +- (void)testSaveSignal { - id hanlderMock = [OCMockObject niceMockForClass:[FBSDKCrashHandler class]]; - [[hanlderMock expect] uninstallExceptionsHandler]; - [FBSDKCrashHandler disable]; - [hanlderMock verify]; + NSArray *callStack = @[@"(2 DEV METHODS)", + @"-[FBSDKAccessToken getPermissions]+2321432", + @"-[FBSDKAccessToken getPermissions]+2324084", + @"(14 DEV METHODS)", ]; + id handlerMock = [OCMockObject niceMockForClass:[FBSDKCrashHandler class]]; + [[handlerMock expect] saveCrashLog:[OCMArg any]]; + [FBSDKCrashHandler saveSignal:11 withCallStack:callStack]; // SIGSEGV + [handlerMock verify]; } - (void)testGetFBSDKVersion @@ -87,7 +95,7 @@ - (void)testGetCrashLogFileNames - (void)testGetPathToCrashFile { NSString *timestampMock = @"test_timestamp"; - NSString *crashLogFileName = [NSString stringWithFormat:@"crash_log_%@.json", timestampMock]; + NSString *crashLogFileName = [NSString stringWithFormat:@"crash_log_%@.json", timestampMock]; NSString *pathToCrashFile = [FBSDKCrashHandler getPathToCrashFile:timestampMock]; XCTAssertTrue([pathToCrashFile hasSuffix:crashLogFileName]); @@ -143,13 +151,13 @@ - (void)testFilterCrashLogs - (NSArray *> *)mockProcessedCrashLogs { NSDictionary *crashLog1 = @{ - @"app_version" : @"4.16(4)", - @"callstack" : @[ - @"(2 DEV METHODS)", - @"-[FBSDKWebViewAppLinkResolver appLinkFromALData:destination:]+2110632", - @"-[FBSDKWebViewAppLinkResolver appLinkFromALData:destination:]+10540", - @"(14 DEV METHODS)", - ], + @"app_version" : @"4.16(4)", + @"callstack" : @[ + @"(2 DEV METHODS)", + @"-[FBSDKWebViewAppLinkResolver appLinkFromALData:destination:]+2110632", + @"-[FBSDKWebViewAppLinkResolver appLinkFromALData:destination:]+10540", + @"(14 DEV METHODS)", + ], @"reason" : @"InvalidOperationException", @"timestamp" : @"1585764970", @"device_model" : @"iPhone7,2", @@ -157,12 +165,12 @@ - (void)testFilterCrashLogs }; NSDictionary *crashLog2 = @{ - @"app_version" : @"1.173.0(2)", - @"callstack" : @[ - @"(3 DEV METHODS)", - @"-[SettingsItemViewController imageWithImage:destination:]+2110632", - @"(6 DEV METHODS)", - ], + @"app_version" : @"1.173.0(2)", + @"callstack" : @[ + @"(3 DEV METHODS)", + @"-[SettingsItemViewController imageWithImage:destination:]+2110632", + @"(6 DEV METHODS)", + ], @"reason" : @"NSInvalidArgumentException", @"timestamp" : @"1585764970", @"device_model" : @"iPad4,1", diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m index 2b340ea9a5..7cf3355c5b 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m @@ -16,11 +16,10 @@ // 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 "FBSDKLibAnalyzer.h" +#import "FBSDKCoreKit+Internal.h" @interface FBSDKLibAnalyzer () @@ -65,7 +64,6 @@ - (void)testGetAddress callstackEntry = @"0 CoreFoundation 0000000104cbd02e __exceptionPreprocess + 350"; NSString *result2 = [FBSDKLibAnalyzer getAddress:callstackEntry]; XCTAssertNil(result2); - } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKSafeCastTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKSafeCastTests.m index 023eff6885..183859560e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKSafeCastTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKSafeCastTests.m @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import + #import "FBSDKInternalUtility.h" @protocol ProtocolA @@ -45,45 +46,63 @@ @implementation FBSDKSafeCastTests - (void)testCastingToNonMatchingClass { ClassA *a = [ClassA new]; - XCTAssertNil(FBSDK_CAST_TO_CLASS_OR_NIL(a, ClassB), - "Casting from a known class to a non-matching class should fail and return nil"); + XCTAssertNil( + FBSDK_CAST_TO_CLASS_OR_NIL(a, ClassB), + "Casting from a known class to a non-matching class should fail and return nil" + ); id idA = a; - XCTAssertNil(FBSDK_CAST_TO_CLASS_OR_NIL(idA, ClassB), - "Casting from an unknown class to a non-matching class should fail and return nil"); + XCTAssertNil( + FBSDK_CAST_TO_CLASS_OR_NIL(idA, ClassB), + "Casting from an unknown class to a non-matching class should fail and return nil" + ); } - (void)testCastingToMatchingClass { ClassA *a = [ClassA new]; - XCTAssertEqual(FBSDK_CAST_TO_CLASS_OR_NIL(a, ClassA), a, - "Casting from a known class to a matching class should return the same instance of that class"); + XCTAssertEqual( + FBSDK_CAST_TO_CLASS_OR_NIL(a, ClassA), + a, + "Casting from a known class to a matching class should return the same instance of that class" + ); id idA = a; - XCTAssertEqual(FBSDK_CAST_TO_CLASS_OR_NIL(idA, ClassA), idA, - "Casting from an unknown class to a matching class should return the same instance of that class"); + XCTAssertEqual( + FBSDK_CAST_TO_CLASS_OR_NIL(idA, ClassA), + idA, + "Casting from an unknown class to a matching class should return the same instance of that class" + ); } - (void)testCastingToNonConformingProtocol { id a = [ClassA new]; - XCTAssertNil(FBSDK_CAST_TO_PROTOCOL_OR_NIL(a, ProtocolB), - "Should not return an object if it does not conform to the stated protocol"); + XCTAssertNil( + FBSDK_CAST_TO_PROTOCOL_OR_NIL(a, ProtocolB), + "Should not return an object if it does not conform to the stated protocol" + ); id idA = a; - XCTAssertNil(FBSDK_CAST_TO_PROTOCOL_OR_NIL(idA, ProtocolB), - "Should not return an object if it does not conform to the stated protocol"); + XCTAssertNil( + FBSDK_CAST_TO_PROTOCOL_OR_NIL(idA, ProtocolB), + "Should not return an object if it does not conform to the stated protocol" + ); } - (void)testCastingToConformingMatchingProtocol { ClassA *a = [ClassA new]; - XCTAssertNil(FBSDK_CAST_TO_PROTOCOL_OR_NIL(a, ProtocolB), - "Should return an object if it conforms to the stated protocol"); + XCTAssertNil( + FBSDK_CAST_TO_PROTOCOL_OR_NIL(a, ProtocolB), + "Should return an object if it conforms to the stated protocol" + ); id idA = a; - XCTAssertNil(FBSDK_CAST_TO_PROTOCOL_OR_NIL(idA, ProtocolB), - "Should return an object if it conforms to the stated protocol"); + XCTAssertNil( + FBSDK_CAST_TO_PROTOCOL_OR_NIL(idA, ProtocolB), + "Should return an object if it conforms to the stated protocol" + ); } - (void)testCastingNil diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m index 797f49bfc4..1f22ad9acb 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import + #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTests-Swift.h" @@ -24,7 +25,8 @@ @interface FBSDKTypeUtilityTests : XCTestCase @end -@implementation FBSDKTypeUtilityTests { +@implementation FBSDKTypeUtilityTests +{ NSArray *validJSONObjects; NSArray *invalidJSONObjects; } @@ -34,7 +36,7 @@ - (void)setUp [super setUp]; validJSONObjects = @[ - @{ @"foo": @"bar" }, + @{ @"foo" : @"bar" }, @[@1, @2, @3], @[], @{}, @@ -42,10 +44,9 @@ - (void)setUp invalidJSONObjects = @[ @"SomeString", - @{ @1: @"one" }, + @{ @1 : @"one" }, @"", ]; - } - (void)testIsValidJSONWithValidJSON @@ -73,16 +74,22 @@ - (void)testIsValidJSONWithRandomValues - (void)testDataWithJSONObjectWithValidJSON { for (id object in validJSONObjects) { - XCTAssertNotNil([FBSDKTypeUtility dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil], - "Valid json object %@ should produce data", object); + XCTAssertNotNil( + [FBSDKTypeUtility dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil], + "Valid json object %@ should produce data", + object + ); } } - (void)testDataWithJSONObjectWithInvalidJSON { for (id object in invalidJSONObjects) { - XCTAssertNil([FBSDKTypeUtility dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil], - "Valid json object %@ should produce data", object); + XCTAssertNil( + [FBSDKTypeUtility dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil], + "Valid json object %@ should produce data", + object + ); } } @@ -91,8 +98,11 @@ - (void)testJSONObjectWithDataWithValidData for (id object in validJSONObjects) { NSData *data = [FBSDKTypeUtility dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:nil]; - XCTAssertEqualObjects([FBSDKTypeUtility JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil], object, - "Should be able to create objects from valid serialized JSON data"); + XCTAssertEqualObjects( + [FBSDKTypeUtility JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil], + object, + "Should be able to create objects from valid serialized JSON data" + ); } } @@ -100,15 +110,17 @@ - (void)testJSONObjectWithDataWithInvalidData { NSArray *invalidData = @[ [@"SomeString" dataUsingEncoding:NSUTF8StringEncoding], - [[@{ @1: @"one" } description] dataUsingEncoding:NSUTF8StringEncoding], + [[@{ @1 : @"one" } description] dataUsingEncoding:NSUTF8StringEncoding], [@"" dataUsingEncoding:NSUTF8StringEncoding], [NSData data], [NSDate date], ]; for (NSData *data in invalidData) { - XCTAssertNil([FBSDKTypeUtility JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil], - "Should not be able to create a JSON objrct from invalid data"); + XCTAssertNil( + [FBSDKTypeUtility JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil], + "Should not be able to create a JSON objrct from invalid data" + ); } } @@ -116,32 +128,42 @@ - (void)testArrayAccessEmptyArray { NSArray *array = @[]; - XCTAssertNil([FBSDKTypeUtility array:array objectAtIndex:5], - "Should return nil and not crash when accessing invalid indices"); + XCTAssertNil( + [FBSDKTypeUtility array:array objectAtIndex:5], + "Should return nil and not crash when accessing invalid indices" + ); } - (void)testArrayAccessNonEmptyArrayInvalidIndex { NSArray *array = @[@1, @2, @3]; - XCTAssertNil([FBSDKTypeUtility array:array objectAtIndex:5], - "Should return nil and not crash when accessing invalid indices"); + XCTAssertNil( + [FBSDKTypeUtility array:array objectAtIndex:5], + "Should return nil and not crash when accessing invalid indices" + ); } - (void)testArrayAccessNonEmptyArrayZeroIndex { NSArray *array = @[@1, @2, @3]; - XCTAssertEqualObjects([array objectAtIndex:0], @1, - "Should be able to retrive a valid object at the first index of an array"); + XCTAssertEqualObjects( + [array objectAtIndex:0], + @1, + "Should be able to retrive a valid object at the first index of an array" + ); } - (void)testArrayAccessNonEmptyArrayValidIndex { NSArray *array = @[@1, @2, @3]; - XCTAssertEqualObjects([array objectAtIndex:2], @3, - "Should be able to retrive a valid object at a valid index of an array"); + XCTAssertEqualObjects( + [array objectAtIndex:2], + @3, + "Should be able to retrive a valid object at a valid index of an array" + ); } - (void)testAddingArrayObjectAtIndexEmptyArray @@ -149,8 +171,11 @@ - (void)testAddingArrayObjectAtIndexEmptyArray NSMutableArray *array = [NSMutableArray array]; [FBSDKTypeUtility array:array addObject:@"foo" atIndex:0]; - XCTAssertEqualObjects([array objectAtIndex:0], @"foo", - "Should be able to insert a valid object into an empty array"); + XCTAssertEqualObjects( + [array objectAtIndex:0], + @"foo", + "Should be able to insert a valid object into an empty array" + ); } - (void)testAddingArrayObjectAtIndexNonEmptyArray @@ -159,8 +184,11 @@ - (void)testAddingArrayObjectAtIndexNonEmptyArray [FBSDKTypeUtility array:array addObject:@"foo" atIndex:0]; [FBSDKTypeUtility array:array addObject:@"bar" atIndex:1]; - XCTAssertEqualObjects([array objectAtIndex:1], @"bar", - "Should be able to insert a valid object into an available position in a non empty array"); + XCTAssertEqualObjects( + [array objectAtIndex:1], + @"bar", + "Should be able to insert a valid object into an available position in a non empty array" + ); } - (void)testAddingArrayObjectAtDuplicateIndex @@ -169,8 +197,11 @@ - (void)testAddingArrayObjectAtDuplicateIndex [FBSDKTypeUtility array:array addObject:@"foo" atIndex:0]; [FBSDKTypeUtility array:array addObject:@"bar" atIndex:0]; - XCTAssertEqualObjects([array objectAtIndex:0], @"bar", - "Should be able to insert a valid object at a non-empty index"); + XCTAssertEqualObjects( + [array objectAtIndex:0], + @"bar", + "Should be able to insert a valid object at a non-empty index" + ); } - (void)testAddingArrayObjectAtUnavailableIndex diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1Tests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1Tests.m index 1008ff12e2..bf0a12cc4d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1Tests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1Tests.m @@ -17,13 +17,11 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import - #import +#import #import -#import - #import "FBSDKBridgeAPIProtocolNativeV1.h" #import "FBSDKCoreKit+Internal.h" @@ -52,9 +50,9 @@ - (void)setUp - (void)testRequestURL { NSDictionary *parameters = @{ - @"api_key_1": @"value1", - @"api_key_2": @"value2", - }; + @"api_key_1" : @"value1", + @"api_key_2" : @"value2", + }; NSError *error; NSURL *requestURL = [self.protocol requestURLWithActionID:self.actionID scheme:self.scheme @@ -77,17 +75,21 @@ - (void)testNilResponseParameters BOOL cancelled = YES; NSError *error; - XCTAssertNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:nil - cancelled:&cancelled - error:&error]); + XCTAssertNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:nil + cancelled:&cancelled + error:&error] + ); XCTAssertFalse(cancelled); XCTAssertNil(error); - XCTAssertNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:@{} - cancelled:&cancelled - error:&error]); + XCTAssertNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:@{} + cancelled:&cancelled + error:&error] + ); XCTAssertFalse(cancelled); XCTAssertNil(error); } @@ -98,16 +100,19 @@ - (void)testEmptyResponseParameters NSError *error; NSDictionary *queryParameters = @{ - @"bridge_args": @{ - @"action_id": self.actionID, - }, - @"method_results": @{}, - }; + @"bridge_args" : @{ + @"action_id" : self.actionID, + }, + @"method_results" : @{}, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertEqualObjects([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error], @{}); + XCTAssertEqualObjects( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error], + @{} + ); XCTAssertFalse(cancelled); XCTAssertNil(error); } @@ -118,24 +123,27 @@ - (void)testResponseParameters NSError *error; NSDictionary *responseParameters = @{ - @"result_key_1": @1, - @"result_key_2": @"two", - @"result_key_3": @{ - @"result_key_4": @4, - @"result_key_5": @"five", - }, - }; + @"result_key_1" : @1, + @"result_key_2" : @"two", + @"result_key_3" : @{ + @"result_key_4" : @4, + @"result_key_5" : @"five", + }, + }; NSDictionary *queryParameters = @{ - @"bridge_args": @{ - @"action_id": self.actionID, - }, - @"method_results": responseParameters, - }; + @"bridge_args" : @{ + @"action_id" : self.actionID, + }, + @"method_results" : responseParameters, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertEqualObjects([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error], responseParameters); + XCTAssertEqualObjects( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error], + responseParameters + ); XCTAssertFalse(cancelled); XCTAssertNil(error); } @@ -146,24 +154,26 @@ - (void)testInvalidActionID NSError *error; NSDictionary *responseParameters = @{ - @"result_key_1": @1, - @"result_key_2": @"two", - @"result_key_3": @{ - @"result_key_4": @4, - @"result_key_5": @"five", - }, - }; + @"result_key_1" : @1, + @"result_key_2" : @"two", + @"result_key_3" : @{ + @"result_key_4" : @4, + @"result_key_5" : @"five", + }, + }; NSDictionary *queryParameters = @{ - @"bridge_args": @{ - @"action_id": [NSUUID UUID].UUIDString, - }, - @"method_results": responseParameters, - }; + @"bridge_args" : @{ + @"action_id" : [NSUUID UUID].UUIDString, + }, + @"method_results" : responseParameters, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error]); + XCTAssertNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error] + ); XCTAssertFalse(cancelled); XCTAssertNil(error); } @@ -175,17 +185,19 @@ - (void)testInvalidBridgeArgs NSString *bridgeArgs = @"this is an invalid bridge_args value"; NSDictionary *queryParameters = @{ - @"bridge_args": bridgeArgs, - @"method_results": @{ - @"result_key_1": @1, - @"result_key_2": @"two", - }, - }; + @"bridge_args" : bridgeArgs, + @"method_results" : @{ + @"result_key_1" : @1, + @"result_key_2" : @"two", + }, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error]); + XCTAssertNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error] + ); XCTAssertFalse(cancelled); XCTAssertNotNil(error); XCTAssertEqual(error.code, FBSDKErrorInvalidArgument); @@ -203,16 +215,18 @@ - (void)testInvalidMethodResults NSString *methodResults = @"this is an invalid method_results value"; NSDictionary *queryParameters = @{ - @"bridge_args": @{ - @"action_id": self.actionID, - }, - @"method_results": methodResults, - }; + @"bridge_args" : @{ + @"action_id" : self.actionID, + }, + @"method_results" : methodResults, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error]); + XCTAssertNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error] + ); XCTAssertFalse(cancelled); XCTAssertNotNil(error); XCTAssertEqual(error.code, FBSDKErrorInvalidArgument); @@ -231,28 +245,30 @@ - (void)testResultError NSInteger code = 42; NSString *domain = @"my custom error domain"; NSDictionary *userInfo = @{ - @"key_1": @1, - @"key_2": @"two", - }; + @"key_1" : @1, + @"key_2" : @"two", + }; NSDictionary *queryParameters = @{ - @"bridge_args": @{ - @"action_id": self.actionID, - @"error": @{ - @"code": @(code), - @"domain": domain, - @"user_info": userInfo, - }, - }, - @"method_results": @{ - @"result_key_1": @1, - @"result_key_2": @"two", - }, - }; + @"bridge_args" : @{ + @"action_id" : self.actionID, + @"error" : @{ + @"code" : @(code), + @"domain" : domain, + @"user_info" : userInfo, + }, + }, + @"method_results" : @{ + @"result_key_1" : @1, + @"result_key_2" : @"two", + }, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error]); + XCTAssertNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error] + ); XCTAssertFalse(cancelled); XCTAssertNotNil(error); XCTAssertEqual(error.code, code); @@ -266,18 +282,20 @@ - (void)testResultCancel NSError *error; NSDictionary *queryParameters = @{ - @"bridge_args": @{ - @"action_id": self.actionID, - }, - @"method_results": @{ - @"completionGesture": @"cancel", - }, - }; + @"bridge_args" : @{ + @"action_id" : self.actionID, + }, + @"method_results" : @{ + @"completionGesture" : @"cancel", + }, + }; queryParameters = [self _encodeQueryParameters:queryParameters]; - XCTAssertNotNil([self.protocol responseParametersForActionID:self.actionID - queryParameters:queryParameters - cancelled:&cancelled - error:&error]); + XCTAssertNotNil( + [self.protocol responseParametersForActionID:self.actionID + queryParameters:queryParameters + cancelled:&cancelled + error:&error] + ); XCTAssertTrue(cancelled); XCTAssertNil(error); } @@ -289,10 +307,10 @@ - (void)testRequestParametersWithDataJSON dataLengthThreshold:NSUIntegerMax includeAppIcon:NO]; NSDictionary *parameters = @{ - @"api_key_1": @"value1", - @"api_key_2": @"value2", - @"data": [self _testData], - }; + @"api_key_1" : @"value1", + @"api_key_2" : @"value2", + @"data" : [self _testData], + }; NSError *error; NSURL *requestURL = [protocol requestURLWithActionID:self.actionID scheme:self.scheme @@ -322,10 +340,10 @@ - (void)testRequestParametersWithImageJSON dataLengthThreshold:NSUIntegerMax includeAppIcon:NO]; NSDictionary *parameters = @{ - @"api_key_1": @"value1", - @"api_key_2": @"value2", - @"image": [self _testImage], - }; + @"api_key_1" : @"value1", + @"api_key_2" : @"value2", + @"image" : [self _testImage], + }; NSError *error; NSURL *requestURL = [protocol requestURLWithActionID:self.actionID scheme:self.scheme @@ -360,10 +378,10 @@ - (void)testRequestParametersWithDataPasteboard dataLengthThreshold:0 includeAppIcon:NO]; NSDictionary *parameters = @{ - @"api_key_1": @"value1", - @"api_key_2": @"value2", - @"data": data, - }; + @"api_key_1" : @"value1", + @"api_key_2" : @"value2", + @"data" : data, + }; NSError *error; NSURL *requestURL = [protocol requestURLWithActionID:self.actionID scheme:self.scheme @@ -398,10 +416,10 @@ - (void)testRequestParametersWithImagePasteboard dataLengthThreshold:0 includeAppIcon:NO]; NSDictionary *parameters = @{ - @"api_key_1": @"value1", - @"api_key_2": @"value2", - @"image": image, - }; + @"api_key_1" : @"value1", + @"api_key_2" : @"value2", + @"image" : image, + }; NSError *error; NSURL *requestURL = [protocol requestURLWithActionID:self.actionID scheme:self.scheme @@ -444,10 +462,10 @@ - (NSData *)_testData - (NSDictionary *)_testDataContainerWithPasteboardName:(NSString *)pasteboardName tag:(NSString *)tag { return @{ - @"isPasteboard": @YES, - @"tag": tag, - @"fbAppBridgeType_jsonReadyValue": pasteboardName, - }; + @"isPasteboard" : @YES, + @"tag" : tag, + @"fbAppBridgeType_jsonReadyValue" : pasteboardName, + }; } - (NSDictionary *)_testDataSerialized:(NSData *)data @@ -459,10 +477,10 @@ - (NSDictionary *)_testDataSerialized:(NSData *)data tag:(NSString *)tag { NSString *string = [FBSDKBase64 encodeData:data]; return @{ - @"isBase64": @YES, - @"tag": tag, - @"fbAppBridgeType_jsonReadyValue": string, - }; + @"isBase64" : @YES, + @"tag" : tag, + @"fbAppBridgeType_jsonReadyValue" : string, + }; } - (NSData *)_testDataWithImage:(UIImage *)image diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m index 451c677f97..28719c5086 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m @@ -18,14 +18,15 @@ #import -#import "FBSDKErrorConfiguration.h" #import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKErrorConfiguration.h" @interface FBSDKErrorConfigurationTests : XCTestCase @end -@implementation FBSDKErrorConfigurationTests { +@implementation FBSDKErrorConfigurationTests +{ NSArray *rawErrorCodeConfiguration; } @@ -35,13 +36,11 @@ - (void)setUp rawErrorCodeConfiguration = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], @"recovery_message" : @"somemessage", - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; } @@ -81,16 +80,13 @@ - (void)testErrorConfigurationAdditonalArray - (void)testParsingRandomName { for (int i = 0; i < 1000; i++) { - NSArray *array = @[ @{ @"name" : Fuzzer.random, - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], @"recovery_message" : @"somemessage", - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -103,13 +99,11 @@ - (void)testParsingRandomSubcodes for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ Fuzzer.random ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[Fuzzer.random] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ Fuzzer.random ] } ], + @"items" : @[@{ @"code" : @1, @"subcodes" : @[Fuzzer.random] }], @"recovery_message" : @"somemessage", - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -121,14 +115,12 @@ - (void)testParsingRandomCodes { for (int i = 0; i < 1000; i++) { NSArray *array = @[ - @{ @"name" : @"other", - @"items" : @[ @{ @"code" : Fuzzer.random, @"subcodes": @[ @459 ] } ], - }, - @{ @"name" : @"login", - @"items" : @[ @{ @"code" : Fuzzer.random, @"subcodes": @[ @12312 ] } ], - @"recovery_message" : @"somemessage", - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @{ @"name" : @"other", + @"items" : @[@{ @"code" : Fuzzer.random, @"subcodes" : @[@459] }], }, + @{ @"name" : @"login", + @"items" : @[@{ @"code" : Fuzzer.random, @"subcodes" : @[@12312] }], + @"recovery_message" : @"somemessage", + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -141,13 +133,11 @@ - (void)testParsingRandomItemDictionaries for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ Fuzzer.random ], - }, + @"items" : @[Fuzzer.random], }, @{ @"name" : @"login", - @"items" : @[ Fuzzer.random ], + @"items" : @[Fuzzer.random], @"recovery_message" : @"somemessage", - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -160,13 +150,11 @@ - (void)testParsingRandomItems for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : Fuzzer.random, - }, + @"items" : Fuzzer.random, }, @{ @"name" : @"login", @"items" : Fuzzer.random, @"recovery_message" : @"somemessage", - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -179,13 +167,11 @@ - (void)testParsingRandomRecoveryMessage for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], @"recovery_message" : Fuzzer.random, - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -198,13 +184,11 @@ - (void)testParsingRandomRecoveryOptionsArray for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], @"recovery_message" : @"somemessage", - @"recovery_options" : @[ Fuzzer.random, Fuzzer.random ] - }, + @"recovery_options" : @[Fuzzer.random, Fuzzer.random]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -217,13 +201,11 @@ - (void)testParsingRandomRecoveryOptions for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], @"recovery_message" : @"somemessage", - @"recovery_options" : Fuzzer.random - }, + @"recovery_options" : Fuzzer.random}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -236,12 +218,10 @@ - (void)testParsingRecoveryMessageWithoutOptions for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], - @"recovery_message" : @"somemessage", - }, + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], + @"recovery_message" : @"somemessage", }, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -254,12 +234,10 @@ - (void)testParsingRecoveryOptionsWithoutMessage for (int i = 0; i < 1000; i++) { NSArray *array = @[ @{ @"name" : @"other", - @"items" : @[ @{ @"code" : @190, @"subcodes": @[ @459 ] } ], - }, + @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @{ @"name" : @"login", - @"items" : @[ @{ @"code" : @1, @"subcodes": @[ @12312 ] } ], - @"recovery_options" : @[ @"Yes", @"No thanks" ] - }, + @"items" : @[@{ @"code" : @1, @"subcodes" : @[@12312] }], + @"recovery_options" : @[@"Yes", @"No thanks"]}, ]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; @@ -277,5 +255,4 @@ - (void)testParsingRandomEntries } } - @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m index 3f1b7aca3b..fab9b4108d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m @@ -17,7 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import - #import #import "FBSDKCoreKit.h" @@ -69,10 +68,12 @@ - (void)testFacebookURL URLString = [FBSDKInternalUtility facebookURLWithHostPrefix:@"m" path:@"dialog/share" - queryParameters:@{ @"key": @"value" } + queryParameters:@{ @"key" : @"value" } error:NULL].absoluteString; - XCTAssertEqualObjects(URLString, - @"https://m.facebook.com/" FBSDK_TARGET_PLATFORM_VERSION @"/dialog/share?key=value"); + XCTAssertEqualObjects( + URLString, + @"https://m.facebook.com/" FBSDK_TARGET_PLATFORM_VERSION @"/dialog/share?key=value" + ); URLString = [FBSDKInternalUtility facebookURLWithHostPrefix:@"m" path:@"/v1.0/dialog/share" @@ -129,7 +130,6 @@ - (void)testFacebookURL defaultVersion:@"" error:NULL].absoluteString; XCTAssertEqualObjects(URLString, @"https://m.facebook.com/" FBSDK_TARGET_PLATFORM_VERSION @"/dialog/share"); - } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m new file mode 100644 index 0000000000..d12613e655 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m @@ -0,0 +1,137 @@ +// 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 "FBSDKJSONValue.h" + +@interface FBSDKJSONValueTests : XCTestCase +@end + +@implementation FBSDKJSONValueTests + +- (void)testReturnsNilForBadInputs +{ + NSError *e; + XCTAssertNil(FBSDKCreateJSONFromString(nil, &e)); + XCTAssertNil(FBSDKCreateJSONFromString(@"THIS IS NOT JSON", &e)); + XCTAssertNil(FBSDKCreateJSONFromString(@"null", &e)); + + // NSData should not be a valid entry in the dictionary to become JSON. + XCTAssertNil( + [[FBSDKJSONValue alloc] initWithPotentialJSONObject:@{ + @"id" : [@"BLAH" dataUsingEncoding:NSUTF8StringEncoding] + }] + ); +} + +- (void)testArrayMatcher +{ + NSError *e; + FBSDKJSONValue *const v = FBSDKCreateJSONFromString(@"[1,2,3,4]", &e); + + __block NSArray *actual = nil; + [v matchArray:^(NSArray *a) { + actual = a; + } dictionary:nil]; + + int i = 1; + for (FBSDKJSONField *field in actual) { + XCTAssertEqualObjects(field.rawObject, @(i++)); + } +} + +- (void)testDictMatcher +{ + NSError *e; + FBSDKJSONValue *const v = FBSDKCreateJSONFromString(@"{\"id\":5}", &e); + + __block NSDictionary *actual = nil; + [v matchArray:nil dictionary:^(NSDictionary *d) {actual = d; }]; + + XCTAssertEqualObjects(actual[@"id"].rawObject, @5); +} + +- (void)testDictMatchersThatDontUseBlocks +{ + FBSDKJSONValue *const v = FBSDKCreateJSONFromString(@"{\"id\":5}", nil); + XCTAssertEqualObjects([v matchDictionaryOrNil][@"id"].rawObject, @5); + XCTAssertEqualObjects([v unsafe_matchDictionaryOrNil][@"id"], @5); + + XCTAssertNil([v unsafe_matchArrayOrNil]); + XCTAssertNil([v matchArrayOrNil]); +} + +- (void)testArrayMatchersThatDontUseBlocks +{ + FBSDKJSONValue *const v = FBSDKCreateJSONFromString(@"[5]", nil); + XCTAssertEqualObjects([v matchArrayOrNil][0].rawObject, @5); + XCTAssertEqualObjects([v unsafe_matchArrayOrNil][0], @5); + + XCTAssertNil([v unsafe_matchDictionaryOrNil]); + XCTAssertNil([v matchDictionaryOrNil]); +} + +#pragma mark - FBSDKJSONField + +- (void)testFieldMatchers +{ + NSError *e; + FBSDKJSONValue *const v = FBSDKCreateJSONFromString(@"[1,\"hi\",null,[1,2,3],{\"key\": \"value\"}]", &e); + + __block NSArray *actual = nil; + [v matchArray:^(NSArray *a) { actual = a; } dictionary:nil]; + + NSArray *const a = @[@1, @2, @3]; + NSDictionary *const d = @{@"key" : @"value"}; + XCTAssertEqualObjects(actual[0].rawObject, @(1)); + XCTAssertEqualObjects([actual[0] numberOrNil], @(1)); + XCTAssertNil([actual[0] stringOrNil]); + + XCTAssertEqualObjects(actual[1].rawObject, @"hi"); + XCTAssertEqualObjects([actual[1] stringOrNil], @"hi"); + XCTAssertNil([actual[1] numberOrNil]); + + XCTAssertEqualObjects(actual[2].rawObject, [NSNull null]); + XCTAssertEqualObjects([actual[2] nullOrNil], [NSNull null]); + XCTAssertNil([actual[2] stringOrNil]); + + XCTAssertEqualObjects(actual[3].rawObject, a); + XCTAssertTrue([actual[3] arrayOrNil].count == 3); + XCTAssertNil([actual[3] stringOrNil]); + + XCTAssertEqualObjects(actual[4].rawObject, d); + XCTAssertTrue([actual[4] dictionaryOrNil].count == 1); + XCTAssertNil([actual[4] stringOrNil]); +} + +- (void)testMatchingDictionaryField +{ + NSError *e; + FBSDKJSONValue *const value = FBSDKCreateJSONFromString(@"{\"oh\":\"hi\"}", &e); + + [value matchArray:^(NSArray *match) { + XCTFail("Should not match an array when none exists in the json string"); + } dictionary:^(NSDictionary *match) { + XCTAssertEqualObjects(match.allKeys.firstObject, @"oh", "Should return a parsed dictionary with the expected key"); + XCTAssertEqualObjects(match[@"oh"].rawObject, @"hi", "Should return valid JSON fields for parsed dictionary values"); + }]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m index b1f3fb944b..65df3e37be 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m @@ -16,26 +16,1374 @@ // 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 "FBSDKAppEventsUtility.h" #import "FBSDKCoreKit.h" #import "FBSDKSettings.h" #import "FBSDKSettings+Internal.h" +#import "FBSDKTestCase.h" +#import "FakeBundle.h" +#import "KeychainStoreSpy.h" +#import "UserDefaultsSpy.h" @interface FBSDKSettings () + (NSString *)userAgentSuffix; + (void)setUserAgentSuffix:(NSString *)suffix; ++ (void)resetLoggingBehaviorsCache; ++ (void)resetFacebookAppIDCache; ++ (void)resetFacebookUrlSchemeSuffixCache; ++ (void)resetFacebookClientTokenCache; ++ (void)resetFacebookDisplayNameCache; ++ (void)resetFacebookDomainPartCache; ++ (void)resetFacebookJpegCompressionQualityCache; ++ (void)resetFacebookAutoInitEnabledCache; ++ (void)resetFacebookInstrumentEnabledCache; ++ (void)resetFacebookAutoLogAppEventsEnabledCache; ++ (void)resetFacebookAdvertiserIDCollectionEnabledCache; ++ (void)resetAdvertiserTrackingStatusCache; ++ (void)resetUserAgentSuffixCache; ++ (void)resetFacebookCodelessDebugLogEnabledCache; ++ (void)resetDataProcessingOptionsCache; @end -@interface FBSDKSettingsTests : XCTestCase -{ - id _mockSDKSettings; -} +@interface FBSDKSettingsTests : FBSDKTestCase + @end +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation FBSDKSettingsTests +{ + id _mockAppEventsUtility; + UserDefaultsSpy *userDefaultsSpy; +} + +static NSString *const emptyString = @""; +static NSString *const whiteSpaceToken = @" "; + +- (void)setUp +{ + [super setUp]; + + [self resetSettingsCaches]; + + // Reset user defaults spy + userDefaultsSpy = [UserDefaultsSpy new]; + [self stubUserDefaultsWith:userDefaultsSpy]; + [self stubLoggingIfUserSettingsChanged]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; +} + +- (void)tearDown +{ + [super tearDown]; + + [self resetSettingsCaches]; +} + +- (void)resetSettingsCaches +{ + [FBSDKSettings resetLoggingBehaviorsCache]; + [FBSDKSettings resetFacebookAppIDCache]; + [FBSDKSettings resetFacebookUrlSchemeSuffixCache]; + [FBSDKSettings resetFacebookClientTokenCache]; + [FBSDKSettings resetFacebookDisplayNameCache]; + [FBSDKSettings resetFacebookDomainPartCache]; + [FBSDKSettings resetFacebookJpegCompressionQualityCache]; + [FBSDKSettings resetFacebookAutoInitEnabledCache]; + [FBSDKSettings resetFacebookInstrumentEnabledCache]; + [FBSDKSettings resetFacebookAutoLogAppEventsEnabledCache]; + [FBSDKSettings resetFacebookAdvertiserIDCollectionEnabledCache]; + [FBSDKSettings resetAdvertiserTrackingStatusCache]; + [FBSDKSettings resetUserAgentSuffixCache]; + [FBSDKSettings resetFacebookCodelessDebugLogEnabledCache]; + [FBSDKSettings resetDataProcessingOptionsCache]; +} + +- (void)testDefaultGraphAPIVersion +{ + XCTAssertEqualObjects( + FBSDKSettings.graphAPIVersion, + FBSDK_TARGET_PLATFORM_VERSION, + "Settings should provide a default graph api version" + ); +} + +// MARK: Logging Behaviors + +- (void)testSettingsBehaviorsFromMissingPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + NSSet *expected = [NSSet setWithArray:@[FBSDKLoggingBehaviorDeveloperErrors]]; + XCTAssertEqualObjects( + FBSDKSettings.loggingBehaviors, + expected, + "Logging behaviors should default to developer errors when there is no plist entry" + ); +} + +- (void)testSettingBehaviorsFromEmptyPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + NSSet *expected = [NSSet setWithArray:@[FBSDKLoggingBehaviorDeveloperErrors]]; + + XCTAssertEqualObjects( + FBSDKSettings.loggingBehaviors, + expected, + "Logging behaviors should default to developer errors when settings are created with an empty plist entry" + ); +} + +- (void)testSettingBehaviorsFromPlistWithInvalidEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookLoggingBehavior" : @[@"Foo"]}]; + [self stubMainBundleWith:bundle]; + + NSSet *expected = [NSSet setWithArray:@[@"Foo"]]; + XCTAssertEqualObjects( + FBSDKSettings.loggingBehaviors, + expected, + "Logging behaviors should default to developer errors when settings are created with a plist that only has invalid entries but it does not" + ); +} + +- (void)testSettingBehaviorsFromPlistWithValidEntry +{ + NSBundle *bundle = [NSBundle bundleForClass:FBSDKTestCase.class]; + [self stubMainBundleWith:bundle]; + + NSSet *expected = [NSSet setWithArray:@[FBSDKLoggingBehaviorInformational]]; + XCTAssertEqualObjects( + FBSDKSettings.loggingBehaviors, + expected, + "Settings should pull information from the bundle" + ); +} + +- (void)testLoggingBehaviorsInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.loggingBehaviors = [NSSet setWithArray:@[FBSDKLoggingBehaviorInformational]]; + + XCTAssertNotNil(FBSDKSettings.loggingBehaviors, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Domain Prefix + +- (void)testSettingDomainPrefixFromMissingPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + XCTAssertNil( + FBSDKSettings.facebookDomainPart, + "There should be no default value for a facebook domain prefix" + ); +} + +- (void)testSettingDomainPrefixFromEmptyPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookDomainPart" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.facebookDomainPart, + emptyString, + "Should not use an empty string as a facebook domain prefix but it does" + ); +} + +- (void)testSettingFacebookDomainPrefixFromPlist +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookDomainPart" : @"beta"}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.facebookDomainPart, + @"beta", + "A developer should be able to set any string as the facebook domain prefix to use in building urls" + ); +} + +- (void)testSettingDomainPrefixWithPlistEntry +{ + NSString *domainPrefix = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookDomainPart" : domainPrefix}]; + [self stubMainBundleWith:bundle]; + + [FBSDKSettings setFacebookDomainPart:@"foo"]; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDomainPart"], + "Should not persist the value of a non-cachable property when setting it" + ); + + XCTAssertEqualObjects( + FBSDKSettings.facebookDomainPart, + @"foo", + "Settings should return the explicitly set domain prefix over one gleaned from a plist entry" + ); +} + +- (void)testSettingDomainPrefixWithoutPlistEntry +{ + [FBSDKSettings setFacebookDomainPart:@"foo"]; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDomainPart"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.facebookDomainPart, + @"foo", + "Settings should return the explicitly set domain prefix" + ); +} + +- (void)testSettingEmptyDomainPrefix +{ + [FBSDKSettings setFacebookDomainPart:emptyString]; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDomainPart"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.facebookDomainPart, + emptyString, + "Should not store an invalid domain prefix but it does" + ); +} + +- (void)testSettingWhitespaceOnlyDomainPrefix +{ + [FBSDKSettings setFacebookDomainPart:whiteSpaceToken]; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDomainPart"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.facebookDomainPart, + whiteSpaceToken, + "Should not store a whitespace only domain prefix but it does" + ); +} + +- (void)testDomainPartInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.facebookDomainPart = @"foo"; + + XCTAssertNotNil(FBSDKSettings.facebookDomainPart, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Client Token + +- (void)testClientTokenFromPlist +{ + NSString *clientToken = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookClientToken" : clientToken}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.clientToken, + clientToken, + "A developer should be able to set any string as the client token" + ); +} + +- (void)testClientTokenFromMissingPlistEntry +{ + XCTAssertNil( + FBSDKSettings.clientToken, + "A client token should not have a default value if it is not available in the plist" + ); +} + +- (void)testSettingClientTokenFromEmptyPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookClientToken" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.clientToken, + emptyString, + "Should not use an empty string as a facebook client token but it will" + ); +} + +- (void)testSettingClientTokenWithPlistEntry +{ + NSString *clientToken = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookClientToken" : clientToken}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.clientToken = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookClientToken"], + "Should not persist the value of a non-cachable property when setting it" + ); + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookClientToken"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.clientToken, + @"foo", + "Settings should return the explicitly set client token over one gleaned from a plist entry" + ); +} + +- (void)testSettingClientTokenWithoutPlistEntry +{ + FBSDKSettings.clientToken = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookClientToken"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.clientToken, + @"foo", + "Settings should return the explicitly set client token" + ); +} + +- (void)testSettingEmptyClientToken +{ + FBSDKSettings.clientToken = emptyString; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookClientToken"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.clientToken, + emptyString, + "Should not store an invalid token but it will" + ); +} + +- (void)testSettingWhitespaceOnlyClientToken +{ + FBSDKSettings.clientToken = whiteSpaceToken; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookClientToken"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.clientToken, + whiteSpaceToken, + "Should not store a whitespace only client token but it will" + ); +} + +- (void)testClientTokenInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.clientToken = @"foo"; + + XCTAssertNotNil(FBSDKSettings.clientToken, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: App Identifier + +- (void)testAppIdentifierFromPlist +{ + NSString *appIdentifier = @"abc1234"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAppID" : appIdentifier}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.appID, + appIdentifier, + "A developer should be able to set any string as the app identifier" + ); +} + +- (void)testAppIdentifierFromMissingPlistEntry +{ + XCTAssertNil( + FBSDKSettings.appID, + "An app identifier should not have a default value if it is not available in the plist" + ); +} + +- (void)testSettingAppIdentifierFromEmptyPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAppID" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.appID, + emptyString, + "Should not use an empty string as an app identifier but it will" + ); +} + +- (void)testSettingAppIdentifierWithPlistEntry +{ + NSString *appIdentifier = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAppID" : appIdentifier}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.appID = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookAppID"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.appID, + @"foo", + "Settings should return the explicitly set app identifier over one gleaned from a plist entry" + ); +} + +- (void)testSettingAppIdentifierWithoutPlistEntry +{ + FBSDKSettings.appID = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookAppID"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.appID, + @"foo", + "Settings should return the explicitly set app identifier" + ); +} + +- (void)testSettingEmptyAppIdentifier +{ + FBSDKSettings.appID = emptyString; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookAppID"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.appID, + emptyString, + "Should not store an empty app identifier but it will" + ); +} + +- (void)testSettingWhitespaceOnlyAppIdentifier +{ + FBSDKSettings.appID = whiteSpaceToken; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookAppID"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.appID, + whiteSpaceToken, + "Should not store a whitespace only app identifier but it will" + ); +} + +- (void)testAppIdentifierInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.appID = @"foo"; + + XCTAssertNotNil(FBSDKSettings.appID, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Display Name + +- (void)testDisplayNameFromPlist +{ + NSString *displayName = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookDisplayName" : displayName}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.displayName, + displayName, + "A developer should be able to set any string as the display name" + ); +} + +- (void)testDisplayNameFromMissingPlistEntry +{ + XCTAssertNil( + FBSDKSettings.displayName, + "A display name should not have a default value if it is not available in the plist" + ); +} + +- (void)testSettingDisplayNameFromEmptyPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookDisplayName" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.displayName, + emptyString, + "Should not use an empty string as a display name but it will" + ); +} + +- (void)testSettingDisplayNameWithPlistEntry +{ + NSString *displayName = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookDisplayName" : displayName}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.displayName = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDisplayName"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.displayName, + @"foo", + "Settings should return the explicitly set display name over one gleaned from a plist entry" + ); +} + +- (void)testSettingDisplayNameWithoutPlistEntry +{ + FBSDKSettings.displayName = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDisplayName"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.displayName, + @"foo", + "Settings should return the explicitly set display name" + ); +} + +- (void)testSettingEmptyDisplayName +{ + FBSDKSettings.displayName = emptyString; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDisplayName"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.displayName, + emptyString, + "Should not store an empty display name but it will" + ); +} + +- (void)testSettingWhitespaceOnlyDisplayName +{ + FBSDKSettings.displayName = whiteSpaceToken; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookDisplayName"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.displayName, + whiteSpaceToken, + "Should not store a whitespace only display name but it will" + ); +} + +- (void)testDisplayNameInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.displayName = @"foo"; + + XCTAssertNotNil(FBSDKSettings.displayName, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: JPEG Compression Quality + +- (void)testJPEGCompressionQualityFromPlist +{ + NSNumber *jpegCompressionQuality = @0.1; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookJpegCompressionQuality" : jpegCompressionQuality}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualWithAccuracy( + FBSDKSettings.JPEGCompressionQuality, + jpegCompressionQuality.doubleValue, + 0.01, + "A developer should be able to set a jpeg compression quality via the plist" + ); +} + +- (void)testJPEGCompressionQualityFromMissingPlistEntry +{ + XCTAssertEqualWithAccuracy( + FBSDKSettings.JPEGCompressionQuality, + 0.9, + 0.01, + "There should be a known default value for jpeg compression quality" + ); +} + +- (void)testSettingJPEGCompressionQualityFromInvalidPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookJpegCompressionQuality" : @-2.0}]; + [self stubMainBundleWith:bundle]; + + XCTAssertNotEqual( + FBSDKSettings.JPEGCompressionQuality, + -0.2, + "Should not use a negative value as a jpeg compression quality" + ); +} + +- (void)testSettingJPEGCompressionQualityWithPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookJpegCompressionQuality" : @0.2}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.JPEGCompressionQuality = 0.3; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookJpegCompressionQuality"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualWithAccuracy( + FBSDKSettings.JPEGCompressionQuality, + @(0.3).doubleValue, + 0.01, + "Settings should return the explicitly set jpeg compression quality over one gleaned from a plist entry" + ); +} + +- (void)testSettingJPEGCompressionQualityWithoutPlistEntry +{ + FBSDKSettings.JPEGCompressionQuality = 1.0; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookJpegCompressionQuality"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.JPEGCompressionQuality, + 1.0, + "Settings should return the explicitly set jpeg compression quality" + ); +} + +- (void)testSettingJPEGCompressionQualityTooLow +{ + FBSDKSettings.JPEGCompressionQuality = -0.1; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookJpegCompressionQuality"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertNotEqual( + FBSDKSettings.JPEGCompressionQuality, + -0.1, + "Should not store a negative jpeg compression quality" + ); +} + +- (void)testSettingJPEGCompressionQualityTooHigh +{ + FBSDKSettings.JPEGCompressionQuality = 1.1; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookJpegCompressionQuality"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertNotEqual( + FBSDKSettings.JPEGCompressionQuality, + 1.1, + "Should not store a jpeg compression quality that is larger than 1.0" + ); +} + +- (void)testJPEGCompressionQualityInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.JPEGCompressionQuality = 1; + + XCTAssertEqual(FBSDKSettings.JPEGCompressionQuality, 1, "Sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: URL Scheme Suffix + +- (void)testURLSchemeSuffixFromPlist +{ + NSString *urlSchemeSuffix = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookUrlSchemeSuffix" : urlSchemeSuffix}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqual( + FBSDKSettings.appURLSchemeSuffix, + urlSchemeSuffix, + "A developer should be able to set any string as the url scheme suffix" + ); +} + +- (void)testURLSchemeSuffixFromMissingPlistEntry +{ + XCTAssertNil( + FBSDKSettings.appURLSchemeSuffix, + "A url scheme suffix should not have a default value if it is not available in the plist" + ); +} + +- (void)testSettingURLSchemeSuffixFromEmptyPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookUrlSchemeSuffix" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.appURLSchemeSuffix, + emptyString, + "Should not use an empty string as a url scheme suffix but it will" + ); +} + +- (void)testSettingURLSchemeSuffixWithPlistEntry +{ + NSString *urlSchemeSuffix = @"abc123"; + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookUrlSchemeSuffix" : urlSchemeSuffix}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.appURLSchemeSuffix = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookUrlSchemeSuffix"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.appURLSchemeSuffix, + @"foo", + "Settings should return the explicitly set url scheme suffix over one gleaned from a plist entry" + ); +} + +- (void)testSettingURLSchemeSuffixWithoutPlistEntry +{ + FBSDKSettings.appURLSchemeSuffix = @"foo"; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookUrlSchemeSuffix"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqual( + FBSDKSettings.appURLSchemeSuffix, + @"foo", + "Settings should return the explicitly set url scheme suffix" + ); +} + +- (void)testSettingEmptyURLSchemeSuffix +{ + FBSDKSettings.appURLSchemeSuffix = emptyString; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookUrlSchemeSuffix"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.appURLSchemeSuffix, + emptyString, + "Should not store an empty url scheme suffix but it will" + ); +} + +- (void)testSettingWhitespaceOnlyURLSchemeSuffix +{ + FBSDKSettings.appURLSchemeSuffix = whiteSpaceToken; + + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookUrlSchemeSuffix"], + "Should not persist the value of a non-cachable property when setting it" + ); + XCTAssertEqualObjects( + FBSDKSettings.appURLSchemeSuffix, + whiteSpaceToken, + "Should not store a whitespace only url scheme suffix but it will" + ); +} + +- (void)testURLSchemeSuffixInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.appURLSchemeSuffix = @"foo"; + + XCTAssertNotNil(FBSDKSettings.appURLSchemeSuffix, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Auto Initialization Enabled + +- (void)testAutoInitializationEnabledFromPlist +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAutoInitEnabled, + "A developer should be able to set the value of auto initialization from the plist" + ); +} + +- (void)testAutoInitializationDefaultValue +{ + XCTAssertTrue( + FBSDKSettings.isAutoInitEnabled, + "Auto initialization should default to true when there is no plist value given" + ); +} + +- (void)testAutoInitializationInvalidPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAutoInitEnabled, + "Auto initialization should default to true when there is an invalid plist value given but it does not" + ); +} + +- (void)testSettingAutoInitializationEnabled +{ + FBSDKSettings.autoInitEnabled = false; + + XCTAssertNotNil( + userDefaultsSpy.capturedValues[@"FacebookAutoInitEnabled"], + "Should persist the value of a cachable property when setting it" + ); + XCTAssertFalse( + FBSDKSettings.autoInitEnabled, + "Should use the explicitly set property" + ); +} + +- (void)testOverridingCachedAutoInitialization +{ + [self stubInitializeSDKWith:@{}]; + + FBSDKSettings.autoInitEnabled = true; + XCTAssertTrue(FBSDKSettings.isAutoInitEnabled); + + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue( + FBSDKSettings.autoInitEnabled, + "Should favor cached properties over those set in the plist" + ); +} + +- (void)testAutoInitializationInternalStorage +{ + [self stubInitializeSDKWith:@{}]; + + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.autoInitEnabled = @YES; + + XCTAssertTrue(FBSDKSettings.autoInitEnabled, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Auto Log App Events Enabled + +- (void)testAutoLogAppEventsEnabledFromPlist +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoLogAppEventsEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAutoLogAppEventsEnabled, + "A developer should be able to set the value of auto log app events from the plist" + ); +} + +- (void)testAutoLogAppEventsEnabledDefaultValue +{ + XCTAssertTrue( + FBSDKSettings.isAutoLogAppEventsEnabled, + "Auto logging of app events should default to true when there is no plist value given" + ); +} + +- (void)testAutoLogAppEventsEnabledInvalidPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoLogAppEventsEnabled" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAutoLogAppEventsEnabled, + "Auto logging of app events should default to true when there is an invalid plist value given but it does not" + ); +} + +- (void)testSettingAutoLogAppEventsEnabled +{ + FBSDKSettings.autoLogAppEventsEnabled = false; + + XCTAssertNotNil( + userDefaultsSpy.capturedValues[@"FacebookAutoLogAppEventsEnabled"], + "Should persist the value of a cachable property when setting it" + ); + XCTAssertFalse( + FBSDKSettings.autoLogAppEventsEnabled, + "Should use the explicitly set property" + ); +} + +- (void)testOverridingCachedAutoLogAppEventsEnabled +{ + [self stubInitializeSDKWith:@{}]; + + FBSDKSettings.autoInitEnabled = true; + XCTAssertTrue(FBSDKSettings.isAutoLogAppEventsEnabled); + + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoLogAppEventsEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue( + FBSDKSettings.isAutoLogAppEventsEnabled, + "Should favor cached properties over those set in the plist" + ); +} + +- (void)testAutoLogAppEventsEnabledInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.autoLogAppEventsEnabled = @YES; + + XCTAssertTrue(FBSDKSettings.autoLogAppEventsEnabled, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Advertiser Identifier Collection Enabled + +- (void)testFacebookAdvertiserIDCollectionEnabled +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAdvertiserIDCollectionEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAdvertiserIDCollectionEnabled, + "A developer should be able to set whether advertiser ID collection is enabled from the plist" + ); +} + +- (void)testFacebookAdvertiserIDCollectionEnabledDefaultValue +{ + XCTAssertTrue( + FBSDKSettings.isAdvertiserIDCollectionEnabled, + "Auto collection of advertiser id should default to true when there is no plist value given" + ); +} + +- (void)testFacebookAdvertiserIDCollectionEnabledInvalidPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAdvertiserIDCollectionEnabled" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAdvertiserIDCollectionEnabled, + "Auto collection of advertiser id should default to true when there is an invalid plist value given but it does not" + ); +} + +- (void)testSettingFacebookAdvertiserIDCollectionEnabled +{ + FBSDKSettings.advertiserIDCollectionEnabled = false; + + XCTAssertNotNil( + userDefaultsSpy.capturedValues[@"FacebookAdvertiserIDCollectionEnabled"], + "Should persist the value of a cachable property when setting it" + ); + XCTAssertFalse( + FBSDKSettings.advertiserIDCollectionEnabled, + "Should use the explicitly set property" + ); +} + +- (void)testOverridingCachedFacebookAdvertiserIDCollectionEnabled +{ + [self stubInitializeSDKWith:@{}]; + + FBSDKSettings.advertiserIDCollectionEnabled = true; + XCTAssertTrue(FBSDKSettings.isAdvertiserIDCollectionEnabled); + + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAdvertiserIDCollectionEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue( + FBSDKSettings.isAdvertiserIDCollectionEnabled, + "Should favor cached properties over those set in the plist" + ); +} + +- (void)testAdvertiserIDCollectionEnabledInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.advertiserIDCollectionEnabled = @YES; + + XCTAssertTrue(FBSDKSettings.advertiserIDCollectionEnabled, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Advertiser Tracking Status + +- (void)testFacebookAdvertiserTrackingStatusDefaultValue +{ + if (@available(iOS 14.0, *)) { + XCTAssertTrue( + [FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingUnspecified, + "Advertiser tracking status should default to Unspecified when there is no plist value given" + ); + } +} + +- (void)testSettingFacebookAdvertiserTrackingStatus +{ + [FBSDKSettings setAdvertiserTrackingStatus:FBSDKAdvertisingTrackingAllowed]; + + if (@available(iOS 14.0, *)) { + XCTAssertTrue( + [FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingAllowed, + "Should use the explicitly set property" + ); + } else { + XCTAssertNil( + userDefaultsSpy.capturedValues[@"FacebookAdvertiserTrackingStatus"], + "Should be no-op in iOS13 and below" + ); + } +} + +- (void)testAdvertiserTrackingStatusInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + if (@available(iOS 14.0, *)) { + [FBSDKSettings setAdvertiserTrackingStatus:FBSDKAdvertisingTrackingUnspecified]; + + XCTAssertTrue([FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingUnspecified, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + } +} + +// MARK: Codeless Debug Log Enabled + +- (void)testFacebookCodelessDebugLogEnabled +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookCodelessDebugLogEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isCodelessDebugLogEnabled, + "A developer should be able to set whether codeless debug logging is enabled from the plist" + ); +} + +- (void)testFacebookCodelessDebugLogEnabledDefaultValue +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isCodelessDebugLogEnabled, + "Codeless debug logging enabled should default to false when there is no plist value given" + ); +} + +- (void)testFacebookCodelessDebugLogEnabledInvalidPlistEntry +{ + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookCodelessDebugLogEnabled" : emptyString}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isCodelessDebugLogEnabled, + "Codeless debug logging enabled should default to true when there is an invalid plist value given but it does not" + ); +} + +- (void)testSettingFacebookCodelessDebugLogEnabled +{ + FBSDKSettings.codelessDebugLogEnabled = false; + + XCTAssertNotNil( + userDefaultsSpy.capturedValues[@"FacebookCodelessDebugLogEnabled"], + "Should persist the value of a cachable property when setting it" + ); + XCTAssertFalse( + FBSDKSettings.codelessDebugLogEnabled, + "Should use the explicitly set property" + ); +} + +- (void)testOverridingCachedFacebookCodelessDebugLogEnabled +{ + [self stubInitializeSDKWith:@{}]; + + FBSDKSettings.codelessDebugLogEnabled = true; + XCTAssertTrue(FBSDKSettings.isCodelessDebugLogEnabled); + + NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookCodelessDebugLogEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue( + FBSDKSettings.isCodelessDebugLogEnabled, + "Should favor cached properties over those set in the plist" + ); +} + +- (void)testCachedFacebookCodelessDebugLogEnabledInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.codelessDebugLogEnabled = @YES; + + XCTAssertTrue(FBSDKSettings.codelessDebugLogEnabled, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +// MARK: Caching Properties + +- (void)testInitialAccessForCachablePropertyWithNonEmptyCache +{ + // Using false because it is not the default value for `isAutoInitializationEnabled` + userDefaultsSpy.capturedValues = @{ @"FacebookAutoInitEnabled" : @NO }; + [self stubUserDefaultsWith:userDefaultsSpy]; + + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAutoInitEnabled, + "Should retrieve an initial value for a cachable property when there is a non-empty cache" + ); + + XCTAssertEqualObjects( + userDefaultsSpy.capturedObjectRetrievalKey, + @"FacebookAutoInitEnabled", + "Should attempt to access the cache to retrieve the initial value for a cachable property" + ); + XCTAssertFalse( + [bundle.capturedKeys containsObject:@"FacebookAutoInitEnabled"], + "Should not attempt to access the plist for cachable properties that have a value in the cache" + ); +} + +- (void)testInitialAccessForCachablePropertyWithEmptyCacheNonEmptyPlist +{ + // Using false because it is not the default value for `isAutoInitializationEnabled` + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : @NO}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + FBSDKSettings.isAutoInitEnabled, + "Should retrieve an initial value from the property list" + ); + + XCTAssertEqualObjects( + userDefaultsSpy.capturedObjectRetrievalKey, + @"FacebookAutoInitEnabled", + "Should attempt to access the cache to retrieve the initial value for a cachable property" + ); + XCTAssertEqualObjects( + bundle.capturedKeys.lastObject, + @"FacebookAutoInitEnabled", + "Should attempt to access the plist for cachable properties that have no value in the cache" + ); +} + +- (void)testInitialAccessForCachablePropertyWithEmptyCacheEmptyPlistAndDefaultValue +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue( + FBSDKSettings.isAutoInitEnabled, + "Should use the default value for a property when there are no values in the cache or plist" + ); + + XCTAssertEqualObjects( + userDefaultsSpy.capturedObjectRetrievalKey, + @"FacebookAutoInitEnabled", + "Should attempt to access the cache to retrieve the initial value for a cachable property" + ); + XCTAssertEqualObjects( + bundle.capturedKeys.lastObject, + @"FacebookAutoInitEnabled", + "Should attempt to access the plist for cachable properties that have no value in the cache" + ); +} + +- (void)testInitialAccessForNonCachablePropertyWithEmptyPlist +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + XCTAssertNil( + FBSDKSettings.clientToken, + "A non-cachable property with no default value and no plist entry should not have a value" + ); + + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache for a non-cachable property" + ); + XCTAssertEqualObjects( + bundle.capturedKeys.lastObject, + @"FacebookClientToken", + "Should attempt to access the plist for non-cachable properties" + ); +} + +- (void)testInitialAccessForNonCachablePropertyWithNonEmptyPlist +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookClientToken" : @"abc123"}]; + [self stubMainBundleWith:bundle]; + + XCTAssertEqualObjects( + FBSDKSettings.clientToken, + @"abc123", + "Should retrieve the initial value from the property list" + ); + + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache for a non-cachable property" + ); + XCTAssertEqualObjects( + bundle.capturedKeys.lastObject, + @"FacebookClientToken", + "Should attempt to access the plist for non-cachable properties" + ); +} + +// MARK: Graph Error Recovery Enabled - (void)testSetGraphErrorRecoveryEnabled { @@ -46,55 +1394,247 @@ - (void)testSetGraphErrorRecoveryEnabled XCTAssertFalse([FBSDKSettings isGraphErrorRecoveryEnabled]); } -- (void)testSetCodelessDebugLogEnabled +// MARK: Limit Event and Data Usage + +- (void)testSetLimitEventAndDataUsageDefault +{ + XCTAssertFalse( + FBSDKSettings.shouldLimitEventAndDataUsage, + "Should limit event data usage by default" + ); +} + +- (void)testSetLimitEventAndDataUsageWithEmptyCache { - [FBSDKSettings setCodelessDebugLogEnabled:YES]; - XCTAssertTrue([FBSDKSettings isCodelessDebugLogEnabled]); + FBSDKSettings.limitEventAndDataUsage = YES; - [FBSDKSettings setCodelessDebugLogEnabled:NO]; - XCTAssertFalse([FBSDKSettings isCodelessDebugLogEnabled]); + XCTAssertEqualObjects( + userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage"], + @YES, + "Should store whether or not to limit event and data usage in the user defaults" + ); + XCTAssertTrue( + FBSDKSettings.shouldLimitEventAndDataUsage, + "Should be able to set whether event data usage is limited" + ); } -- (void)testSetAutoLogAppEventsEnabled +- (void)testSetLimitEventAndDataUsageWithNonEmptyCache { - [FBSDKSettings setAutoLogAppEventsEnabled:YES]; - XCTAssertTrue([FBSDKSettings isAutoLogAppEventsEnabled]); + FBSDKSettings.limitEventAndDataUsage = YES; + XCTAssertTrue(FBSDKSettings.shouldLimitEventAndDataUsage, "sanity check"); - [FBSDKSettings setAutoLogAppEventsEnabled:NO]; - XCTAssertFalse([FBSDKSettings isAutoLogAppEventsEnabled]); + FBSDKSettings.limitEventAndDataUsage = NO; + XCTAssertFalse( + FBSDKSettings.shouldLimitEventAndDataUsage, + "Should be able to override the existing value of should limit event data usage" + ); + XCTAssertEqualObjects( + userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage"], + @NO, + "Should store the overridden preference for limiting event data usage in the user defaults" + ); } -- (void)testSetAdvertiserIDCollectionEnabled +// MARK: Data Processing Options + +- (void)testDataProcessingOptionDefaults { - [FBSDKSettings setAdvertiserIDCollectionEnabled:YES]; - XCTAssertTrue([FBSDKSettings isAdvertiserIDCollectionEnabled]); + FBSDKSettings.dataProcessingOptions = @[]; - [FBSDKSettings setAdvertiserIDCollectionEnabled:NO]; - XCTAssertFalse([FBSDKSettings isAdvertiserIDCollectionEnabled]); + XCTAssertEqualObjects( + FBSDKSettings.dataProcessingOptions[DATA_PROCESSING_OPTIONS_COUNTRY], + @0, + "Country should default to zero when not provided" + ); + XCTAssertEqualObjects( + FBSDKSettings.dataProcessingOptions[DATA_PROCESSING_OPTIONS_STATE], + @0, + "State should default to zero when not provided" + ); } -- (void)testSetLimitEventAndDataUsage +- (void)testSettingEmptyDataProcessingOptions { - [FBSDKSettings setLimitEventAndDataUsage:YES]; - XCTAssertTrue([FBSDKSettings shouldLimitEventAndDataUsage]); + FBSDKSettings.dataProcessingOptions = @[]; - [FBSDKSettings setLimitEventAndDataUsage:NO]; - XCTAssertFalse([FBSDKSettings shouldLimitEventAndDataUsage]); + XCTAssertNotNil( + FBSDKSettings.dataProcessingOptions, + "Should not be able to set data processing options to an empty list of options but you can" + ); +} - //test when NSUserDefaults does not contain FBSDKSettingsLimitEventAndDataUsage - id mockUserDefaults = [OCMockObject niceMockForClass:[NSUserDefaults class]]; - OCMStub([[mockUserDefaults standardUserDefaults] objectForKey:[OCMArg any]]).andReturn(nil); - [FBSDKSettings setLimitEventAndDataUsage:YES]; - XCTAssertFalse([FBSDKSettings shouldLimitEventAndDataUsage]); +- (void)testSettingInvalidDataProcessOptions +{ + FBSDKSettings.dataProcessingOptions = @[@"Foo", @"Bar"]; + + XCTAssertNotNil( + FBSDKSettings.dataProcessingOptions, + "Should not be able to set data processing options to invalid list of options but you can" + ); + + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:FBSDKSettings.dataProcessingOptions]; + + XCTAssertEqualObjects( + userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsDataProcessingOptions"], + data, + "Should store the data processing options in the user defaults as data" + ); } -- (void)testSetDataProecssingOptions +- (void)testSettingDataProcessingOptionsWithCountryAndState { - [FBSDKSettings setDataProcessingOptions:@[@"LDU"] country:1 state:1000]; - NSDictionary *dataProcessingOptions = [FBSDKSettings dataProcessingOptions]; - NSSet *actualSet = [NSSet setWithArray:dataProcessingOptions[DATA_PROCESSING_OPTIONS]]; - NSSet *expectedSet = [NSSet setWithArray:@[@"LDU"]]; - XCTAssertTrue([expectedSet isEqualToSet:actualSet]); + int countryCode = -1000000000; + int stateCode = 100000000; + [FBSDKSettings setDataProcessingOptions:@[] country:countryCode state:stateCode]; + + XCTAssertEqualObjects( + FBSDKSettings.dataProcessingOptions[DATA_PROCESSING_OPTIONS], + @[], + "Should use the provided array of processing options" + ); + XCTAssertEqualObjects( + FBSDKSettings.dataProcessingOptions[DATA_PROCESSING_OPTIONS_COUNTRY], + @(countryCode), + "Should use the provided country code" + ); + XCTAssertEqualObjects( + FBSDKSettings.dataProcessingOptions[DATA_PROCESSING_OPTIONS_STATE], + @(stateCode), + "Should use the provided state code" + ); +} + +- (void)testDataProcessingOptionsWithEmptyCache +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + XCTAssertNil( + FBSDKSettings.dataProcessingOptions, + "Should not be able to get data processing options if there is none cached" + ); + XCTAssertEqualObjects( + userDefaultsSpy.capturedObjectRetrievalKey, + @"com.facebook.sdk:FBSDKSettingsDataProcessingOptions", + "Should attempt to access the cache to retrieve the initial value for a cachable property" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist for data processing options" + ); +} + +- (void)testDataProcessingOptionsWithNonEmptyCache +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.dataProcessingOptions = @[]; + + // Reset internal storage + [FBSDKSettings resetDataProcessingOptionsCache]; + + XCTAssertNotNil( + FBSDKSettings.dataProcessingOptions, + "Should be able to retrieve data processing options from the cache" + ); + XCTAssertEqualObjects( + userDefaultsSpy.capturedObjectRetrievalKey, + @"com.facebook.sdk:FBSDKSettingsDataProcessingOptions", + "Should attempt to access the cache to retrieve the initial value for a cachable property" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist for data processing options" + ); +} + +- (void)testDataProcessingOptionsInternalStorage +{ + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + FBSDKSettings.dataProcessingOptions = @[]; + + XCTAssertNotNil(FBSDKSettings.dataProcessingOptions, "sanity check"); + XCTAssertNil( + userDefaultsSpy.capturedObjectRetrievalKey, + "Should not attempt to access the cache to retrieve objects that have a current value" + ); + XCTAssertNil( + bundle.capturedKeys.lastObject, + "Should not attempt to access the plist to retrieve objects that have a current value" + ); +} + +- (void)testRecordInstall +{ + XCTAssertNil( + userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"], + "Should not persist the value of before setting it" + ); + [FBSDKSettings recordInstall]; + XCTAssertNotNil( + userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"], + "Should persist the value after setting it" + ); + NSDate *date = userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + [FBSDKSettings recordInstall]; + XCTAssertEqual(date, userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"], "Should not change the cached install timesstamp"); +} + +- (void)testRecordSetAdvertiserTrackingEnabled +{ + [FBSDKSettings recordSetAdvertiserTrackingEnabled]; + XCTAssertNotNil( + userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"], + "Should persist the value after setting it" + ); + NSDate *date = userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"]; + [FBSDKSettings recordSetAdvertiserTrackingEnabled]; + XCTAssertNotEqual(date, userDefaultsSpy.capturedValues[@"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"], "Should update set advertiser tracking enabled timesstamp"); +} + +- (void)testIsEventDelayTimerExpired +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + [FBSDKSettings recordInstall]; + XCTAssertFalse([FBSDKSettings isEventDelayTimerExpired]); + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + NSDate *today = [NSDate new]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *addComponents = [NSDateComponents new]; + addComponents.month = -1; + NSDate *expiredDate = [calendar dateByAddingComponents:addComponents toDate:today options:0]; + [[NSUserDefaults standardUserDefaults] setObject:expiredDate forKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + XCTAssertTrue([FBSDKSettings isEventDelayTimerExpired]); + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; +} + +- (void)testIsSetATETimeExceedsInstallTime +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"]; + [FBSDKSettings recordInstall]; + [FBSDKSettings recordSetAdvertiserTrackingEnabled]; + XCTAssertFalse([FBSDKSettings isSetATETimeExceedsInstallTime]); + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"]; + [FBSDKSettings recordSetAdvertiserTrackingEnabled]; + NSDate *today = [NSDate new]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *addComponents = [NSDateComponents new]; + addComponents.month = -1; + NSDate *expiredDate = [calendar dateByAddingComponents:addComponents toDate:today options:0]; + [[NSUserDefaults standardUserDefaults] setObject:expiredDate forKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + XCTAssertTrue([FBSDKSettings isSetATETimeExceedsInstallTime]); + + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsInstallTimestamp"]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"com.facebook.sdk:FBSDKSettingsSetAdvertiserTrackingEnabledTimestamp"]; } - (void)testLoggingBehaviors @@ -105,22 +1645,58 @@ - (void)testLoggingBehaviors [FBSDKSettings setLoggingBehaviors:mockLoggingBehaviors]; XCTAssertEqualObjects(mockLoggingBehaviors, [FBSDKSettings loggingBehaviors]); - //test enable logging behavior - [FBSDKSettings enableLoggingBehavior: FBSDKLoggingBehaviorInformational]; + // test enable logging behavior + [FBSDKSettings enableLoggingBehavior:FBSDKLoggingBehaviorInformational]; XCTAssertTrue([[FBSDKSettings loggingBehaviors] containsObject:FBSDKLoggingBehaviorInformational]); - //test disable logging behavior - [FBSDKSettings disableLoggingBehavior: FBSDKLoggingBehaviorInformational]; + // test disable logging behavior + [FBSDKSettings disableLoggingBehavior:FBSDKLoggingBehaviorInformational]; XCTAssertFalse([[FBSDKSettings loggingBehaviors] containsObject:FBSDKLoggingBehaviorInformational]); } #pragma mark - test for internal functions -- (void)testSetUserAgentSuffix +// MARK: User Agent Suffix + +- (void)testUserAgentSuffix +{ + XCTAssertNil( + FBSDKSettings.userAgentSuffix, + "User agent suffix should be nil by default" + ); +} + +- (void)testSettingUserAgentSuffix +{ + FBSDKSettings.userAgentSuffix = @"foo"; + + XCTAssertEqual( + FBSDKSettings.userAgentSuffix, + @"foo", + "Settings should return the explicitly set user agent suffix" + ); +} + +- (void)testSettingEmptyUserAgentSuffix { - NSString *mockUserAgentSuffix = @"mockUserAgentSuffix"; - [FBSDKSettings setUserAgentSuffix:mockUserAgentSuffix]; - XCTAssertEqualObjects(mockUserAgentSuffix, [FBSDKSettings userAgentSuffix]); + FBSDKSettings.userAgentSuffix = emptyString; + + XCTAssertEqualObjects( + FBSDKSettings.userAgentSuffix, + emptyString, + "Should not store an empty user agent suffix but it will" + ); +} + +- (void)testSettingWhitespaceOnlyUserAgentSuffix +{ + FBSDKSettings.userAgentSuffix = whiteSpaceToken; + + XCTAssertEqualObjects( + FBSDKSettings.userAgentSuffix, + whiteSpaceToken, + "Should not store a whitespace only user agent suffix but it will" + ); } - (void)testSetGraphAPIVersion @@ -146,3 +1722,5 @@ - (void)testIsDataProcessingRestricted } @end + +#pragma clang diagnostic pop diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h new file mode 100644 index 0000000000..ac996c5f88 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h @@ -0,0 +1,32 @@ +// 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 "FBSDKApplicationObserving.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ApplicationDelegateObserverFake : NSObject + +@property (readonly, assign) int didFinishLaunchingCallCount; +@property (nullable, readonly, copy) NSDictionary *capturedLaunchOptions; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m new file mode 100644 index 0000000000..dba2a9027d --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m @@ -0,0 +1,40 @@ +// 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 "AppDelegateObserverFake.h" + +@implementation ApplicationDelegateObserverFake + +- (instancetype)init +{ + if (self = [super init]) { + _didFinishLaunchingCallCount = 0; + _capturedLaunchOptions = [NSDictionary dictionary]; + } + return self; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + _didFinishLaunchingCallCount++; + _capturedLaunchOptions = launchOptions; + + return true; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h index 4b19623112..e8dc1f737f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h @@ -25,12 +25,12 @@ NS_ASSUME_NONNULL_BEGIN /// Bundles key value pairs in the same format they're returned from the graph: /// ex: /// { -/// "sample_rates": [ -/// { -/// "key": "foo", -/// "value": 1 -/// } -/// ] +/// "sample_rates": [ +/// { +/// "key": "foo", +/// "value": 1 +/// } +/// ] /// } + (NSDictionary *)sampleRatesWithEntryPairs:(NSDictionary *)pairs; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m index 4130cb94c1..d89a6dc153 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m @@ -25,8 +25,8 @@ + (NSDictionary *)sampleRatesWithEntryPairs:(NSDictionary *)pair NSMutableArray *sampleRateDicts = [NSMutableArray array]; NSMutableDictionary *tmp = [NSMutableDictionary dictionary]; - [pairs enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - [sampleRateDicts addObject: [self sampleRateWithEntryName:key rate:obj]]; + [pairs enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) { + [sampleRateDicts addObject:[self sampleRateWithEntryName:key rate:obj]]; }]; [tmp setObject:sampleRateDicts forKey:@"sample_rates"]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h new file mode 100644 index 0000000000..723cf94b51 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -0,0 +1,186 @@ +// 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 "FBSDKAccessToken.h" +#import "FBSDKAppEvents.h" +#import "FBSDKAppEventsUtility.h" +#import "FBSDKApplicationDelegate.h" +#import "FBSDKGraphRequestConnection.h" +#import "FBSDKKeychainStore.h" +#import "FBSDKMeasurementEventListener.h" +#import "FBSDKProfile+Internal.h" +#import "FBSDKServerConfiguration.h" +#import "FakeAccessTokenCache.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + This shared test case class is intended to provide commonly mocked objects and methods for stubbing out common side effects such as + fetching from the network when objects are missing from a given cache. Additionally this class will handle stopping mocking and invalidating + mock objects to avoid potential shared global state between tests. + + In general there are three broad use cases for mocks. These include: + + 1) stubbing out a method in order to avoid calling it or to provide a known return value. + + 2) stubbing out a method (usually an initializer or a singleton) to replace an object with a test object. + + 3) stubbing out a method on the object you're testing. ie. use the real implementation for method a but stub out the implementation for method b. + + 4) verifying behavior - something was called or something was not called etc... + +Before you write a new class mock. Check to see if there's already an implementation in this class. +Also, to get a better understanding of mocking, please read the documentation at https://ocmock.org/ +*/ +@interface FBSDKTestCase : XCTestCase + +/// Used for sharing an `FBSDKAccessToken` class mock between tests +@property (nullable, assign) id accessTokenClassMock; + +/// Used for sharing a common app identifier between tests. This is not a valid FB App ID +@property (nullable, assign) NSString *appID; + +/// Used for sharing an `FBSDKAppEvents` mock between tests +@property (nullable, assign) id appEventsMock; + +/// Used for mocking `FBSDKAppEventState` between tests +@property (nullable, assign) id appEventStatesMock; + +/// Used for sharing an `FBSDKApplicationDelegate` class mock between tests +@property (nullable, assign) id fbApplicationDelegateClassMock; + +/// Used for sharing an `FBSDKFeatureManager` class mock between tests +@property (nullable, assign) id featureManagerClassMock; + +/// Used for sharing an `FBSDKGatekeeperManager` class mock between tests +@property (nullable, assign) id gatekeeperManagerClassMock; + +/// Used for sharing an `NSBundle` class mock between tests +@property (nullable, assign) id nsBundleClassMock; + +/// Used for sharing an `NSUserDefaults` class mock between tests +@property (nullable, assign) id nsUserDefaultsClassMock; + +/// Used for sharing an `FBSDKProfile` class mock between tests +@property (nullable, assign) id profileClassMock; + +/// Used for sharing an `FBSDKServerConfigurationManager` class mock between tests +@property (nullable, assign) id serverConfigurationManagerClassMock; + +/// Used for sharing an `FBSDKSettings` class mock between tests +@property (nullable, assign) id settingsClassMock; + +/// Used for sharing an `SKAdNetwork` class mock between tests +@property (nullable, nonatomic, assign) id skAdNetworkClassMock; + +/// Used for sharing an `NSNotificationCenter` class mock between tests +@property (nullable, nonatomic, assign) id nsNotificationCenterClassMock; + +/// Used for sharing an `FBSDKMeasurementEventListener` class mock between tests +@property (nullable, nonatomic, assign) id measurementEventListenerClassMock; + +/// Used for sharing a `FBSDKTimeSpentData` class mock between tests +@property (nullable, nonatomic, assign) id timeSpentDataClassMock; + +/// Used for sharing a `FBSDKInternalUtility` class mock between tests +@property (nullable, nonatomic, assign) id internalUtilityClassMock; + +/// Used for sharing a `FBSDKAppEventsUtility` class mock between tests +@property (nullable, nonatomic, assign) id appEventsUtilityClassMock; + +/// Used for sharing a `FBSDKSKAdNetworkReporter` class mock between tests +@property (nullable, nonatomic, assign) id adNetworkReporterClassMock; + +/// Stubs `FBSDKSettings.appID` and return the provided value +- (void)stubAppID:(nullable NSString *)appID; + +/// Stubs `FBSDKSettings.isSDKInitialized` and return the provided value +- (void)stubIsSDKInitialized:(BOOL)initialized; + +/// Stubs `FBSDKSettings.isAutoInitEnabled` and return the provided value +- (void)stubIsAutoInitEnabled:(BOOL)isEnabled; + +/// Stubs `FBSDKSettings.isAutoLogAppEventsEnabled` and return the provided value +- (void)stubIsAutoLogAppEventsEnabled:(BOOL)isEnabled; + +/// Stubs `FBSDKGateKeeperManager.loadGateKeepers:` to avoid the side effect of a network fetch +- (void)stubLoadingGateKeepers; + +/// Stubs `FBSDKFeatureManager.checkFeature:` for any feature requested by FeatureManager. +- (void)stubCheckingFeatures; + +/// Stubs `FBSDKServerConfigurationManager.cachedServerConfiguration` and returns the default server configuration. +/// Use this when you don't care what the actual configuration is and want to avoid a network call. +- (void)stubFetchingCachedServerConfiguration; + +/// Stubs `FBSDKServerConfigurationManager.cachedServerConfiguration` with a specific configuration +- (void)stubCachedServerConfigurationWithServerConfiguration:(FBSDKServerConfiguration *)serverConfiguration; + +/// Stubs `NSBundle.mainBundle` with the provided NSBundle +- (void)stubMainBundleWith:(NSBundle *)bundle; + +/// Stubs `NSUserDefaults.standardUserDefaults` with the provided NSUserDefaults +- (void)stubUserDefaultsWith:(NSUserDefaults *)defaults; + +/// Stubs `FBSDKApplicationDelegate.initializeSDK` with a dictionary of launch options +- (void)stubInitializeSDKWith:(NSDictionary *)launchOptions; + +/// Prevents logging on changes to Settings properties +- (void)stubLoggingIfUserSettingsChanged; + +/// Stubs `FBSDKSettings.accessTokenCache` +- (void)stubAccessTokenCacheWith:(FakeAccessTokenCache *)cache; + +/// Stubs `FBSDKProfile.fetchCachedProfile` +- (void)stubCachedProfileWith:(FBSDKProfile *__nullable)profile; + +/// Stubs `FBSDKApplicationDelegate.sharedInstance` +- (void)stubFBApplicationDelegateSharedInstanceWith:(FBSDKApplicationDelegate *)delegate; + +/// Stubs `SKAdNetwork.registerAppForAdNetworkAttribution` +- (void)stubRegisterAppForAdNetworkAttribution; + +/// Stubs `NSNotificationCenter.defaultCenter` and returns the provided notification center +- (void)stubDefaultNotificationCenterWith:(NSNotificationCenter *)notificationCenter; + +/// Stubs `AppEvents.singleton` and return the provided app events instance +- (void)stubAppEventsSingletonWith:(FBSDKAppEvents *)appEventsInstance; + +/// Stubs `MeasurementEventListener.defaultListener` and returns the provided listener. +- (void)stubDefaultMeasurementEventListenerWith:(FBSDKMeasurementEventListener *)eventListener; + +/// Stubs `FBSDKSettings.graphAPIVersion` with the provided version string +- (void)stubGraphAPIVersionWith:(NSString *)version; + +/// Stubs `FBSDKAccessToken.currentAccessToken` with the provided token +- (void)stubCurrentAccessTokenWith:(nullable FBSDKAccessToken *)token; + +/// Stubs `FBSDKSettings.clientToken` with the provided token string +- (void)stubClientTokenWith:(nullable NSString *)token; + +/// Stubs `FBSDKAppEventsUtility.advertisingTrackingStatus` with the provided value +- (void)stubAdvertisingTrackingStatusWith:(FBSDKAdvertisingTrackingStatus)trackingStatus; + +/// Stubs `FBSDKSKAdNetworkReporter._loadConfigurationWithBlock` +- (void)stubLoadingAdNetworkReporterConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m new file mode 100644 index 0000000000..c5ffaa831f --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -0,0 +1,356 @@ +// 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 ser`vices 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 "FBSDKTestCase.h" + +#import + +// For mocking SKAdNetwork +#import + +#import "FBSDKAppEvents.h" +#import "FBSDKAppEvents+Internal.h" +#import "FBSDKAppEventsState.h" +#import "FBSDKApplicationDelegate+Internal.h" +#import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitTestUtility.h" +#import "FBSDKFeatureManager.h" +#import "FBSDKKeychainStore.h" +#import "FBSDKSKAdNetworkReporter.h" +#import "FBSDKSettings.h" +#import "FBSDKTimeSpentData.h" + +@interface FBSDKAppEvents (Testing) ++ (FBSDKAppEvents *)singleton; +@end + +@interface FBSDKSettings (Testing) ++ (void)_logIfSDKSettingsChanged; +@end + +typedef void (^FBSDKSKAdNetworkReporterBlock)(void); +@interface FBSDKSKAdNetworkReporter (Testing) ++ (void)_loadConfigurationWithBlock:(FBSDKSKAdNetworkReporterBlock)block; +@end + +@implementation FBSDKTestCase + +- (void)setUp +{ + [super setUp]; + + _appID = @"appid"; + + [self setUpNSBundleMock]; + [self setUpSettingsMock]; + [self setUpServerConfigurationManagerMock]; + [self setUpAppEventsMock]; + [self setUpFBApplicationDelegateMock]; + [self setUpGateKeeperManagerMock]; + [self setUpFeatureManagerMock]; + [self setUpNSUserDefaultsMock]; + [self setUpAccessTokenMock]; + [self setUpProfileMock]; + [self setUpSKAdNetworkMock]; + [self setUpNSNotificationCenterMock]; + [self setUpMeasurementEventListenerMock]; + [self setUpTimeSpendDataMock]; + [self setUpInternalUtilityMock]; + [self setUpAppEventsUtilityMock]; + [self setUpAdNetworkReporterMock]; +} + +- (void)tearDown +{ + [super tearDown]; + + [_appEventsMock stopMocking]; + _appEventsMock = nil; + + [_appEventStatesMock stopMocking]; + _appEventStatesMock = nil; + + [_fbApplicationDelegateClassMock stopMocking]; + _fbApplicationDelegateClassMock = nil; + + [_featureManagerClassMock stopMocking]; + _featureManagerClassMock = nil; + + [_gatekeeperManagerClassMock stopMocking]; + _gatekeeperManagerClassMock = nil; + + [_serverConfigurationManagerClassMock stopMocking]; + _serverConfigurationManagerClassMock = nil; + + [_settingsClassMock stopMocking]; + _settingsClassMock = nil; + + [_nsBundleClassMock stopMocking]; + _nsBundleClassMock = nil; + + [_nsUserDefaultsClassMock stopMocking]; + _nsUserDefaultsClassMock = nil; + + [_accessTokenClassMock stopMocking]; + _accessTokenClassMock = nil; + + [_profileClassMock stopMocking]; + _profileClassMock = nil; + + [_skAdNetworkClassMock stopMocking]; + _skAdNetworkClassMock = nil; + + [_nsNotificationCenterClassMock stopMocking]; + _nsNotificationCenterClassMock = nil; + + [_measurementEventListenerClassMock stopMocking]; + _measurementEventListenerClassMock = nil; + + [_timeSpentDataClassMock stopMocking]; + _timeSpentDataClassMock = nil; + + [_internalUtilityClassMock stopMocking]; + _internalUtilityClassMock = nil; + + [_appEventsUtilityClassMock stopMocking]; + _appEventsUtilityClassMock = nil; + + [_adNetworkReporterClassMock stopMocking]; + _adNetworkReporterClassMock = nil; +} + +- (void)setUpSettingsMock +{ + _settingsClassMock = OCMStrictClassMock(FBSDKSettings.class); +} + +- (void)setUpFBApplicationDelegateMock +{ + _fbApplicationDelegateClassMock = OCMStrictClassMock(FBSDKApplicationDelegate.class); +} + +- (void)setUpGateKeeperManagerMock +{ + _gatekeeperManagerClassMock = OCMClassMock(FBSDKGateKeeperManager.class); +} + +- (void)setUpFeatureManagerMock +{ + _featureManagerClassMock = [OCMockObject niceMockForClass:[FBSDKFeatureManager class]]; +} + +- (void)setUpServerConfigurationManagerMock +{ + self.serverConfigurationManagerClassMock = OCMStrictClassMock(FBSDKServerConfigurationManager.class); +} + +- (void)setUpAppEventsMock +{ + _appEventsMock = OCMClassMock(FBSDKAppEvents.class); + + _appEventStatesMock = OCMClassMock([FBSDKAppEventsState class]); + OCMStub([_appEventStatesMock alloc]).andReturn(_appEventStatesMock); + OCMStub([_appEventStatesMock initWithToken:[OCMArg any] appID:[OCMArg any]]).andReturn(_appEventStatesMock); +} + +- (void)setUpNSBundleMock +{ + self.nsBundleClassMock = OCMStrictClassMock(NSBundle.class); +} + +- (void)setUpNSUserDefaultsMock +{ + self.nsUserDefaultsClassMock = OCMStrictClassMock(NSUserDefaults.class); +} + +- (void)setUpAccessTokenMock +{ + self.accessTokenClassMock = OCMStrictClassMock(FBSDKAccessToken.class); +} + +- (void)setUpProfileMock +{ + self.profileClassMock = OCMStrictClassMock(FBSDKProfile.class); +} + +- (void)setUpSKAdNetworkMock +{ + if (@available(iOS 11.3, *)) { + self.skAdNetworkClassMock = OCMStrictClassMock(SKAdNetwork.class); + } +} + +- (void)setUpNSNotificationCenterMock +{ + self.nsNotificationCenterClassMock = OCMStrictClassMock(NSNotificationCenter.class); +} + +- (void)setUpMeasurementEventListenerMock +{ + self.measurementEventListenerClassMock = OCMStrictClassMock(FBSDKMeasurementEventListener.class); +} + +- (void)setUpTimeSpendDataMock +{ + self.timeSpentDataClassMock = OCMStrictClassMock(FBSDKTimeSpentData.class); +} + +- (void)setUpInternalUtilityMock +{ + self.internalUtilityClassMock = OCMStrictClassMock(FBSDKInternalUtility.class); +} + +- (void)setUpAppEventsUtilityMock +{ + self.appEventsUtilityClassMock = OCMClassMock(FBSDKAppEventsUtility.class); +} + +- (void)setUpAdNetworkReporterMock +{ + self.adNetworkReporterClassMock = OCMClassMock(FBSDKSKAdNetworkReporter.class); +} + +#pragma mark - Public Methods + +- (void)stubAppID:(NSString *)appID +{ + [OCMStub(ClassMethod([_settingsClassMock appID])) andReturn:appID]; +} + +- (void)stubIsSDKInitialized:(BOOL)initialized +{ + [OCMStub(ClassMethod([_fbApplicationDelegateClassMock isSDKInitialized])) andReturnValue:OCMOCK_VALUE(initialized)]; +} + +- (void)stubLoadingGateKeepers +{ + OCMStub(ClassMethod([_gatekeeperManagerClassMock loadGateKeepers:OCMArg.any])); +} + +- (void)stubCheckingFeatures +{ + OCMStubIgnoringNonObjectArgs([_featureManagerClassMock checkFeature:FBSDKFeatureInstrument completionBlock:OCMArg.any]); +} + +- (void)stubFetchingCachedServerConfiguration +{ + FBSDKServerConfiguration *configuration = [FBSDKServerConfiguration defaultServerConfigurationForAppID:_appID]; + OCMStub(ClassMethod([_serverConfigurationManagerClassMock cachedServerConfiguration])).andReturn(configuration); +} + +- (void)stubCachedServerConfigurationWithServerConfiguration:(FBSDKServerConfiguration *)serverConfiguration +{ + OCMStub(ClassMethod([_serverConfigurationManagerClassMock cachedServerConfiguration])).andReturn(serverConfiguration); +} + +- (void)stubMainBundleWith:(NSBundle *)bundle +{ + OCMStub(ClassMethod([_nsBundleClassMock mainBundle])).andReturn(bundle); +} + +- (void)stubUserDefaultsWith:(NSUserDefaults *)defaults +{ + OCMStub(ClassMethod([_nsUserDefaultsClassMock standardUserDefaults])).andReturn(defaults); +} + +- (void)stubInitializeSDKWith:(NSDictionary *)launchOptions +{ + OCMStub(ClassMethod([_fbApplicationDelegateClassMock initializeSDK:OCMArg.any])); +} + +- (void)stubLoggingIfUserSettingsChanged +{ + OCMStub(ClassMethod([_settingsClassMock _logIfSDKSettingsChanged])); +} + +- (void)stubAccessTokenCacheWith:(FakeAccessTokenCache *)cache +{ + OCMStub(ClassMethod([_settingsClassMock accessTokenCache])).andReturn(cache); +} + +- (void)stubIsAutoInitEnabled:(BOOL)isEnabled +{ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + OCMStub(ClassMethod([_settingsClassMock isAutoInitEnabled])).andReturn(isEnabled); + #pragma clang diagnostic pop +} + +- (void)stubIsAutoLogAppEventsEnabled:(BOOL)isEnabled +{ + OCMStub(ClassMethod([_settingsClassMock isAutoLogAppEventsEnabled])).andReturn(isEnabled); +} + +- (void)stubCachedProfileWith:(FBSDKProfile *__nullable)profile +{ + OCMStub(ClassMethod([_profileClassMock fetchCachedProfile])).andReturn(profile); +} + +- (void)stubFBApplicationDelegateSharedInstanceWith:(FBSDKApplicationDelegate *)delegate +{ + OCMStub(ClassMethod([_fbApplicationDelegateClassMock sharedInstance])).andReturn(delegate); +} + +- (void)stubRegisterAppForAdNetworkAttribution +{ + if (@available(iOS 11.3, *)) { + OCMStub(ClassMethod([_skAdNetworkClassMock registerAppForAdNetworkAttribution])); + } +} + +- (void)stubDefaultNotificationCenterWith:(NSNotificationCenter *)notificationCenter +{ + OCMStub(ClassMethod([_nsNotificationCenterClassMock defaultCenter])).andReturn(notificationCenter); +} + +- (void)stubAppEventsSingletonWith:(FBSDKAppEvents *)appEventsInstance +{ + OCMStub([_appEventsMock singleton]).andReturn(appEventsInstance); +} + +- (void)stubDefaultMeasurementEventListenerWith:(FBSDKMeasurementEventListener *)eventListener +{ + OCMStub([_measurementEventListenerClassMock defaultListener]).andReturn(eventListener); +} + +- (void)stubCurrentAccessTokenWith:(FBSDKAccessToken *)token +{ + OCMStub(ClassMethod([_accessTokenClassMock currentAccessToken])).andReturn(token); +} + +- (void)stubGraphAPIVersionWith:(NSString *)version +{ + OCMStub(ClassMethod([_settingsClassMock graphAPIVersion])).andReturn(version); +} + +- (void)stubClientTokenWith:(nullable NSString *)token +{ + OCMStub(ClassMethod([_settingsClassMock clientToken])).andReturn(token); +} + +- (void)stubAdvertisingTrackingStatusWith:(FBSDKAdvertisingTrackingStatus)trackingStatus +{ + OCMStub(ClassMethod([_appEventsUtilityClassMock advertisingTrackingStatus])).andReturn(trackingStatus); +} + +- (void)stubLoadingAdNetworkReporterConfiguration +{ + OCMStub(ClassMethod([_adNetworkReporterClassMock _loadConfigurationWithBlock:OCMArg.any])); +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h new file mode 100644 index 0000000000..996cf6f25e --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h @@ -0,0 +1,31 @@ +// 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 "FBSDKAccessTokenCaching.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FakeAccessTokenCache : NSObject + +- (instancetype)initWithToken:(FBSDKAccessToken *__nullable)token; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m new file mode 100644 index 0000000000..5722a06261 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m @@ -0,0 +1,49 @@ +// 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 "FakeAccessTokenCache.h" + +@implementation FakeAccessTokenCache +{ + FBSDKAccessToken *_accessToken; +} + +- (instancetype)initWithToken:(FBSDKAccessToken *__nullable)token +{ + if ((self = [super init])) { + _accessToken = token; + } + return self; +} + +- (FBSDKAccessToken *)accessToken +{ + return _accessToken; +} + +- (void)setAccessToken:(FBSDKAccessToken *)token +{ + _accessToken = token; +} + +- (void)clearCache +{ + // noop for now +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h new file mode 100644 index 0000000000..6282247bd2 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h @@ -0,0 +1,31 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface FakeBundle : NSBundle + +@property (nonatomic, copy) NSArray *capturedKeys; + ++ (instancetype)bundleWithDictionary:(NSDictionary *)dictionary; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m new file mode 100644 index 0000000000..ae214110df --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m @@ -0,0 +1,52 @@ +// 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 "FakeBundle.h" + +#import "FBSDKCoreKit+Internal.h" + +@implementation FakeBundle +{ + NSDictionary *_dictionary; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary +{ + if (self = [super init]) { + _dictionary = dictionary; + } + + return self; +} + ++ (instancetype)bundleWithDictionary:(NSDictionary *)dictionary +{ + return [[FakeBundle alloc] initWithDictionary:dictionary]; +} + +- (id)objectForInfoDictionaryKey:(NSString *)key +{ + if (!_capturedKeys) { + _capturedKeys = [NSMutableArray array]; + } + _capturedKeys = [_capturedKeys arrayByAddingObject:key]; + + return [_dictionary objectForKey:key]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/ExampleSwiftTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h similarity index 84% rename from FBSDKCoreKit/FBSDKCoreKitTests/ExampleSwiftTests.swift rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h index 788b765f3d..5a221e6502 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/ExampleSwiftTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h @@ -16,14 +16,12 @@ // 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 FBSDKCoreKit -import XCTest +#import "FBSDKKeychainStore.h" -class ExampleSwiftTests: XCTestCase { - func testCanAccessCoreKit() { - XCTAssertNil( - Settings.appID, - "Should not have default app ID" - ) - } -} +NS_ASSUME_NONNULL_BEGIN + +@interface KeychainStoreSpy : FBSDKKeychainStore + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m new file mode 100644 index 0000000000..a490ec0ad2 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m @@ -0,0 +1,41 @@ +// 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 "KeychainStoreSpy.h" + +@implementation KeychainStoreSpy + +- (BOOL)setData:(NSData *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility +{ + // Right now just return true. Later will add actual spying + return true; +} + +- (BOOL)setDictionary:(NSDictionary *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility +{ + // Right now just return true. Later will add actual spying + return true; +} + +- (BOOL)setString:(NSString *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility +{ + // Right now just return true. Later will add actual spying + return true; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h new file mode 100644 index 0000000000..dd293456bc --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h @@ -0,0 +1,27 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface NotificationCenterSpy : NSNotificationCenter + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m new file mode 100644 index 0000000000..b94ffea12e --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m @@ -0,0 +1,28 @@ +// 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 "NotificationCenterSpy.h" + +@implementation NotificationCenterSpy + +- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject +{ + // TODO: capture values +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h new file mode 100644 index 0000000000..210a815d12 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h @@ -0,0 +1,31 @@ +// 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 "FBSDKAccessToken.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SampleAccessToken : NSObject + ++ (FBSDKAccessToken *)validToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m new file mode 100644 index 0000000000..30af95890a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m @@ -0,0 +1,36 @@ +// 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 "SampleAccessToken.h" + +@implementation SampleAccessToken + ++ (FBSDKAccessToken *)validToken +{ + return [[FBSDKAccessToken alloc] initWithTokenString:@"123" + permissions:@[] + declinedPermissions:@[] + expiredPermissions:@[] + appID:@"123" + userID:@"user123" + expirationDate:nil + refreshDate:nil + dataAccessExpirationDate:nil]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h new file mode 100644 index 0000000000..260816864a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h @@ -0,0 +1,32 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface SampleAppEvents : NSObject + +@property (class, readonly, copy) NSDictionary *invalidEvent; +@property (class, readonly, copy) NSDictionary *validEvent; + ++ (NSDictionary *)validEventWithName:(NSString *)name; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m new file mode 100644 index 0000000000..324bd98553 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m @@ -0,0 +1,38 @@ +// 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 "SampleAppEvents.h" + +@implementation SampleAppEvents + ++ (id)invalidEvent +{ + return @1; +} + ++ (NSDictionary *)validEvent +{ + return @{ @"_eventName" : @"event1" }; +} + ++ (NSDictionary *)validEventWithName:(NSString *)name +{ + return @{ @"_eventName" : name }; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h new file mode 100644 index 0000000000..12889c46f9 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h @@ -0,0 +1,31 @@ +// 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 "FBSDKProfile.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SampleUserProfile : NSObject + ++ (FBSDKProfile *)valid; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m new file mode 100644 index 0000000000..1893bfea45 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m @@ -0,0 +1,34 @@ +// 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 "SampleUserProfile.h" + +@implementation SampleUserProfile + ++ (FBSDKProfile *)valid +{ + return [[FBSDKProfile alloc] initWithUserID:@"123" + firstName:@"John" + middleName:@"K" + lastName:@"Smith" + name:@"John Smith" + linkURL:[NSURL URLWithString:@"http://www.example.com"] + refreshDate:NSDate.distantFuture]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.h new file mode 100644 index 0000000000..e711ec7405 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.h @@ -0,0 +1,30 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface UserDefaultsSpy : NSUserDefaults + +@property (nonatomic, copy) NSString *capturedObjectRetrievalKey; +@property (nonatomic, copy) NSDictionary *capturedValues; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m new file mode 100644 index 0000000000..dafcfd2098 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m @@ -0,0 +1,59 @@ +// 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 "UserDefaultsSpy.h" + +#import "FBSDKTypeUtility.h" + +@implementation UserDefaultsSpy + ++ (instancetype)new +{ + return [[UserDefaultsSpy alloc] init]; +} + +- (instancetype)init +{ + self = [super init]; + if (self) { + _capturedValues = [NSDictionary dictionary]; + } + + return self; +} + +- (id)objectForKey:(NSString *)defaultName +{ + _capturedObjectRetrievalKey = defaultName; + return [_capturedValues objectForKey:defaultName]; +} + +- (void)setObject:(id)value forKey:(NSString *)defaultName +{ + NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithDictionary:_capturedValues]; + + if (value) { + [FBSDKTypeUtility dictionary:tmp setObject:value forKey:defaultName]; + } else { + [tmp removeObjectForKey:defaultName]; + } + + _capturedValues = tmp; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m index 366c383f9e..2b2515d467 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m @@ -16,11 +16,9 @@ // 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 "FBSDKCrashHandler.h" #import "FBSDKCrashObserver.h" #import "FBSDKFeatureManager.h" @@ -61,7 +59,7 @@ - (void)testDidReceiveCrashLogs { NSArray *callstack = @[@"(4 DEV METHODS)", @"+[FBSDKCodelessIndexer crash]+84", - @"(22 DEV METHODS)"] ; + @"(22 DEV METHODS)"]; NSArray *> *crashLogs = @[@{ @"callstack" : callstack, @"reason" : @"NSInternalInconsistencyException", @@ -71,9 +69,8 @@ - (void)testDidReceiveCrashLogs @"device_model" : @"iPad5,3", @"device_os" : @"ios", @"device_os_version" : @"13.1.3", - }]; + }]; return crashLogs; } @end - diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m index 232894cc9d..a0172b13c7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKCrashShield.h" #import "FBSDKFeatureManager.h" @@ -137,7 +136,7 @@ - (void)testAnalyzeCrashCausedByNonCoreKitFeature @"device_model" : @"iPad5,3", @"device_os" : @"ios", @"device_os_version" : @"13.1.3", - }]; + }]; return crashLogs; } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorEntryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorEntryTests.m index 4851a0c9d4..dc35a6a060 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorEntryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorEntryTests.m @@ -24,7 +24,8 @@ @interface FBSDKMethodUsageMonitorEntryTests : XCTestCase @end -@implementation FBSDKMethodUsageMonitorEntryTests { +@implementation FBSDKMethodUsageMonitorEntryTests +{ FBSDKMethodUsageMonitorEntry *entry; } @@ -34,8 +35,11 @@ - (void)testCreatingEntryWithMethodName entry = [FBSDKMethodUsageMonitorEntry entryFromClass:self.class withMethod:_cmd]; - XCTAssertEqualObjects(entry.name, expectedName, - @"Should use the name of the class and method as the entry name"); + XCTAssertEqualObjects( + entry.name, + expectedName, + @"Should use the name of the class and method as the entry name" + ); } - (void)testEncodingEntryWithMethodName @@ -46,10 +50,16 @@ - (void)testEncodingEntryWithMethodName [entry encodeWithCoder:coder]; - XCTAssertEqualObjects(coder.encodedObject[@"event_name"], NSStringFromSelector(_cmd), - @"Should use the name of the method as the event name for encoding"); - XCTAssertEqualObjects(coder.encodedObject[@"method_usage_class"], NSStringFromClass(self.class), - @"Should use the name of the class as the class name for encoding"); + XCTAssertEqualObjects( + coder.encodedObject[@"event_name"], + NSStringFromSelector(_cmd), + @"Should use the name of the method as the event name for encoding" + ); + XCTAssertEqualObjects( + coder.encodedObject[@"method_usage_class"], + NSStringFromClass(self.class), + @"Should use the name of the class as the class name for encoding" + ); } - (void)testDecodingEntryWithMethodName @@ -58,10 +68,16 @@ - (void)testDecodingEntryWithMethodName entry = [[FBSDKMethodUsageMonitorEntry alloc] initWithCoder:coder]; - XCTAssertEqualObjects(coder.decodedObject[@"event_name"], [NSString class], - @"Initializing from a decoder should attempt to decode a String for the event name key"); - XCTAssertEqualObjects(coder.decodedObject[@"method_usage_class"], [NSString class], - @"Initializing from a decoder should attempt to decode a String for the defining class key"); + XCTAssertEqualObjects( + coder.decodedObject[@"event_name"], + [NSString class], + @"Initializing from a decoder should attempt to decode a String for the event name key" + ); + XCTAssertEqualObjects( + coder.decodedObject[@"method_usage_class"], + [NSString class], + @"Initializing from a decoder should attempt to decode a String for the defining class key" + ); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m index dc1d2617e5..911284acb3 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKCoreKit+Internal.h" @@ -59,8 +58,11 @@ - (void)testRecordingMethodUsage FBSDKMethodUsageMonitorEntry *entry = (FBSDKMethodUsageMonitorEntry *) FBSDKMonitor.entries.firstObject; - XCTAssertEqualObjects(entry.dictionaryRepresentation[@"event_name"], expectedName, - @"Entry should contain the captured method name"); + XCTAssertEqualObjects( + entry.dictionaryRepresentation[@"event_name"], + expectedName, + @"Entry should contain the captured method name" + ); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m index 04bbe30505..6686f58c16 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m @@ -19,10 +19,9 @@ #import #import "FBSDKMonitoringConfiguration.h" - +#import "FBSDKMonitoringConfigurationTestHelper.h" #import "FBSDKTestCoder.h" #import "TestMonitorEntry.h" -#import "FBSDKMonitoringConfigurationTestHelper.h" @interface FBSDKMonitoringConfiguration (Testing) @@ -44,20 +43,32 @@ - (void)testDefaultMonitoringConfiguration { self.config = FBSDKMonitoringConfiguration.defaultConfiguration; - XCTAssertEqual(self.config.defaultSamplingRate, 0, - @"Default sampling rate should be zero if unspecified"); - XCTAssertEqual(self.config.sampleRates.count, 0, - @"A config should not have any sample rates by default"); + XCTAssertEqual( + self.config.defaultSamplingRate, + 0, + @"Default sampling rate should be zero if unspecified" + ); + XCTAssertEqual( + self.config.sampleRates.count, + 0, + @"A config should not have any sample rates by default" + ); } - (void)testCreatingWithMissingSamplingRates { self.config = [FBSDKMonitoringConfiguration fromDictionary:@{}]; - XCTAssertEqual(self.config.defaultSamplingRate, 0, - @"Default sampling rate should be zero if unspecified"); - XCTAssertEqual(self.config.sampleRates.count, 0, - @"A config should not have any sample rates by default"); + XCTAssertEqual( + self.config.defaultSamplingRate, + 0, + @"Default sampling rate should be zero if unspecified" + ); + XCTAssertEqual( + self.config.sampleRates.count, + 0, + @"A config should not have any sample rates by default" + ); } - (void)testCreatingWithEmptySamplingRates @@ -66,104 +77,133 @@ - (void)testCreatingWithEmptySamplingRates self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; - XCTAssertEqual(self.config.defaultSamplingRate, 0, - @"Default sampling rate should be zero if missing from the sampling rates"); - XCTAssertEqual(self.config.sampleRates.count, 0, - @"A config should not have any sample rates by default"); + XCTAssertEqual( + self.config.defaultSamplingRate, + 0, + @"Default sampling rate should be zero if missing from the sampling rates" + ); + XCTAssertEqual( + self.config.sampleRates.count, + 0, + @"A config should not have any sample rates by default" + ); } - - (void)testCreatingWithMissingDefaultSamplingRate { NSDictionary *expectedSampleRates = @{ - @"foo": @1 + @"foo" : @1 }; - NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo": @1 }]; + NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo" : @1 }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; - XCTAssertEqual(self.config.defaultSamplingRate, 0, - @"Default sampling rate should be zero if missing from the sampling rates"); - XCTAssertTrue([self.config.sampleRates isEqualToDictionary:expectedSampleRates], - @"A config should set sample rates correctly based on the input rates"); + XCTAssertEqual( + self.config.defaultSamplingRate, + 0, + @"Default sampling rate should be zero if missing from the sampling rates" + ); + XCTAssertTrue( + [self.config.sampleRates isEqualToDictionary:expectedSampleRates], + @"A config should set sample rates correctly based on the input rates" + ); } - (void)testCreatingWithValidDefaultSamplingRate { - NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"default": @100 }]; + NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"default" : @100 }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; - XCTAssertEqual(self.config.defaultSamplingRate, 100, - @"Default sampling rate should be gleaned from the initializing dictionary"); + XCTAssertEqual( + self.config.defaultSamplingRate, + 100, + @"Default sampling rate should be gleaned from the initializing dictionary" + ); } - (void)testCreatingWithOnlyInvalidSamplingRates { NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ - @"default": @-1, - @"foo": @"bar" - }]; + @"default" : @-1, + @"foo" : @"bar" + }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; - XCTAssertEqual(self.config.defaultSamplingRate, 0, - @"Default sampling rate should be zero if no valid default is given"); - XCTAssertTrue([self.config.sampleRates isEqualToDictionary:@{}], - @"Should not store invalid sample rates"); + XCTAssertEqual( + self.config.defaultSamplingRate, + 0, + @"Default sampling rate should be zero if no valid default is given" + ); + XCTAssertTrue( + [self.config.sampleRates isEqualToDictionary:@{}], + @"Should not store invalid sample rates" + ); } - (void)testCreatingWihSomeInvalidSampleRates { NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ - @"default": @-1, - @"foo": @50 - }]; + @"default" : @-1, + @"foo" : @50 + }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; - XCTAssertEqual(self.config.defaultSamplingRate, 0, - @"Default sampling rate should be gleaned from the initializing dictionary"); - + XCTAssertEqual( + self.config.defaultSamplingRate, + 0, + @"Default sampling rate should be gleaned from the initializing dictionary" + ); } - (void)testGettingSampleRate { - NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo": @50 }]; + NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo" : @50 }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; - XCTAssertEqual([self.config sampleRateForEntry: [TestMonitorEntry testEntryWithName:@"foo"]], 50, - @"Should retrieve the sample rate for the entry with the matching name"); + XCTAssertEqual( + [self.config sampleRateForEntry:[TestMonitorEntry testEntryWithName:@"foo"]], + 50, + @"Should retrieve the sample rate for the entry with the matching name" + ); } - (void)testEncoding { FBSDKTestCoder *coder = [FBSDKTestCoder new]; - NSDictionary *expectedSampleRates = @{@"foo": @50}; - NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo": @50 }]; + NSDictionary *expectedSampleRates = @{@"foo" : @50}; + NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo" : @50 }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; [self.config encodeWithCoder:coder]; - XCTAssertEqualObjects(coder.encodedObject[@"sample_rates"], expectedSampleRates, - @"Should encode the sample rates"); + XCTAssertEqualObjects( + coder.encodedObject[@"sample_rates"], + expectedSampleRates, + @"Should encode the sample rates" + ); } - (void)testDecoding { FBSDKTestCoder *decoder = [FBSDKTestCoder new]; - NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo": @50 }]; + NSDictionary *dict = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo" : @50 }]; self.config = [FBSDKMonitoringConfiguration fromDictionary:dict]; self.config = [self.config initWithCoder:decoder]; - XCTAssertEqualObjects(decoder.decodedObject[@"sample_rates"], [NSDictionary class], - @"Should attempt to decode a dictionary of sample rates when initializing from a decoder"); + XCTAssertEqualObjects( + decoder.decodedObject[@"sample_rates"], + [NSDictionary class], + @"Should attempt to decode a dictionary of sample rates when initializing from a decoder" + ); } #pragma mark Helpers diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m index 8ff1160637..8e703af991 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m @@ -16,11 +16,10 @@ // 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 +#import #import "FBSDKCoreKit+Internal.h" #import "TestMonitorEntry.h" @@ -31,7 +30,8 @@ @interface FBSDKMonitorNetworkerTests : XCTestCase @end -@implementation FBSDKMonitorNetworkerTests { +@implementation FBSDKMonitorNetworkerTests +{ id graphRequestMock; } @@ -59,11 +59,13 @@ - (void)testSendingEntryWithMissingAppID OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); - OCMReject([graphRequestMock initWithGraphPath:[OCMArg any] - parameters:[OCMArg any] - tokenString:nil - HTTPMethod:[OCMArg any] - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]); + OCMReject( + [graphRequestMock initWithGraphPath:[OCMArg any] + parameters:[OCMArg any] + tokenString:nil + HTTPMethod:[OCMArg any] + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery] + ); [FBSDKMonitorNetworker sendEntries:@[self.entry]]; } @@ -75,13 +77,16 @@ - (void)testSendingEntriesCreatesGraphRequest OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); - BOOL (^verifyPath)(id) = ^BOOL(id path) { - XCTAssertEqualObjects(path, @"/monitorings", - @"Graph path should be a known string well known"); + BOOL (^verifyPath)(id) = ^BOOL (id path) { + XCTAssertEqualObjects( + path, + @"/monitorings", + @"Graph path should be a known string well known" + ); return YES; }; - BOOL (^verifyParameters)(id) = ^BOOL(id parameters) { + BOOL (^verifyParameters)(id) = ^BOOL (id parameters) { [self assertAppIdInParameters:parameters]; [self assertDeviceModelInParameters:parameters]; [self assertOSVersionInParameters:parameters]; @@ -90,29 +95,36 @@ - (void)testSendingEntriesCreatesGraphRequest return YES; }; - BOOL (^verifyHTTPMethod)(id) = ^BOOL(id method) { - XCTAssertEqualObjects(method, FBSDKHTTPMethodPOST, - @"Networker should use POST when sending entries"); + BOOL (^verifyHTTPMethod)(id) = ^BOOL (id method) { + XCTAssertEqualObjects( + method, + FBSDKHTTPMethodPOST, + @"Networker should use POST when sending entries" + ); return YES; }; [FBSDKMonitorNetworker sendEntries:entries]; - OCMVerify([graphRequestMock initWithGraphPath:[OCMArg checkWithBlock:verifyPath] - parameters:[OCMArg checkWithBlock:verifyParameters] - tokenString:[OCMArg isNil] - HTTPMethod:[OCMArg checkWithBlock:verifyHTTPMethod] - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]); + OCMVerify( + [graphRequestMock initWithGraphPath:[OCMArg checkWithBlock:verifyPath] + parameters:[OCMArg checkWithBlock:verifyParameters] + tokenString:[OCMArg isNil] + HTTPMethod:[OCMArg checkWithBlock:verifyHTTPMethod] + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery] + ); } - (void)testSendingEntriesStartsGraphRequest { OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); - OCMStub([graphRequestMock initWithGraphPath:[OCMArg any] - parameters:[OCMArg any] - tokenString:nil - HTTPMethod:[OCMArg any] - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]).andReturn(graphRequestMock); + OCMStub( + [graphRequestMock initWithGraphPath:[OCMArg any] + parameters:[OCMArg any] + tokenString:nil + HTTPMethod:[OCMArg any] + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery] + ).andReturn(graphRequestMock); [FBSDKMonitorNetworker sendEntries:@[[TestMonitorEntry testEntry]]]; @@ -123,33 +135,45 @@ - (void)testSendingEntriesStartsGraphRequest - (void)assertBundleIdInParameters:(NSDictionary *)parameters { - XCTAssertEqualObjects(parameters[@"unique_application_identifier"], NSBundle.mainBundle.bundleIdentifier, - @"A monitor POST body should include the main bundle identifier."); + XCTAssertEqualObjects( + parameters[@"unique_application_identifier"], + NSBundle.mainBundle.bundleIdentifier, + @"A monitor POST body should include the main bundle identifier." + ); } - (void)assertOSVersionInParameters:(NSDictionary *)parameters { - XCTAssertEqualObjects(parameters[@"device_os_version"], UIDevice.currentDevice.systemVersion, - @"A monitor POST body should include the current device's os version."); + XCTAssertEqualObjects( + parameters[@"device_os_version"], + UIDevice.currentDevice.systemVersion, + @"A monitor POST body should include the current device's os version." + ); } - (void)assertAppIdInParameters:(NSDictionary *)parameters { - XCTAssertEqualObjects(parameters[@"id"], [FBSDKSettings appID], - @"A monitor POST body should include the current facebook app identifier."); + XCTAssertEqualObjects( + parameters[@"id"], + [FBSDKSettings appID], + @"A monitor POST body should include the current facebook app identifier." + ); } - (void)assertDeviceModelInParameters:(NSDictionary *)parameters { - XCTAssertEqualObjects(parameters[@"device_model"], [self.class deviceModel], - @"A monitor POST body should include the current device model."); + XCTAssertEqualObjects( + parameters[@"device_model"], + [self.class deviceModel], + @"A monitor POST body should include the current device model." + ); } - (void)assertParameters:(NSDictionary *)parameters includeEntries:(NSArray> *)entries { // Networker should send the array of provided entries as a UTF8 encoded JSON string keyed under 'monitorings' NSString *capturedEntriesJSON = parameters[@"monitorings"]; - NSArray *capturedEntryDictionaries = [FBSDKBasicUtility objectForJSONString:capturedEntriesJSON error:nil]; + NSArray *capturedEntryDictionaries = [FBSDKBasicUtility objectForJSONString:capturedEntriesJSON error:nil]; for (int i = 0; i < capturedEntryDictionaries.count; i++) { XCTAssertTrue([capturedEntryDictionaries[i] isEqualToDictionary:entries[i].dictionaryRepresentation]); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorStoreTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorStoreTests.m index 067583e901..a392a8d78b 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorStoreTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorStoreTests.m @@ -16,8 +16,8 @@ // 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 "FBSDKCoreKit+Internal.h" #import "TestMonitorEntry.h" @@ -57,16 +57,22 @@ - (void)testCreatingWithFilePath NSURL *temporaryDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; NSURL *file = [temporaryDirectory URLByAppendingPathComponent:self.filename]; - XCTAssertEqualObjects(self.store.filePath, file, - @"Should store entries in the temporary directory"); + XCTAssertEqualObjects( + self.store.filePath, + file, + @"Should store entries in the temporary directory" + ); } - (void)testPersistingEmptyEntries { [self.store persist:@[]]; - XCTAssertEqualObjects([self.store retrieveEntries], @[], - @"Should persist an empty list of entries"); + XCTAssertEqualObjects( + [self.store retrieveEntries], + @[], + @"Should persist an empty list of entries" + ); } - (void)testPersistingEntries @@ -75,18 +81,25 @@ - (void)testPersistingEntries [self.store persist:@[self.entry]]; - XCTAssertEqualObjects([self entriesFromDisk], expectedEntries, - @"Should persist entries correctly"); + XCTAssertEqualObjects( + [self entriesFromDisk], + expectedEntries, + @"Should persist entries correctly" + ); } -- (void)testPersistingDuplicateEntriesWithEmptyStore { +- (void)testPersistingDuplicateEntriesWithEmptyStore +{ TestMonitorEntry *entry2 = [TestMonitorEntry testEntry]; NSArray *entries = @[self.entry, entry2]; [self.store persist:entries]; - XCTAssertEqualObjects([self entriesFromDisk], entries, - @"Should allow persisting duplicate entries"); + XCTAssertEqualObjects( + [self entriesFromDisk], + entries, + @"Should allow persisting duplicate entries" + ); } - (void)testPersistingDuplicateEntriesWithNonEmptyStore @@ -97,8 +110,11 @@ - (void)testPersistingDuplicateEntriesWithNonEmptyStore [self.store persist:@[self.entry]]; [self.store persist:entries]; - XCTAssertEqualObjects([self entriesFromDisk], entries, - @"Should overwrite any existing stored entries when persisting"); + XCTAssertEqualObjects( + [self entriesFromDisk], + entries, + @"Should overwrite any existing stored entries when persisting" + ); } - (void)testPersistingUniqueEntriesWithEmptyStore @@ -108,8 +124,11 @@ - (void)testPersistingUniqueEntriesWithEmptyStore [self.store persist:entries]; - XCTAssertEqualObjects([self entriesFromDisk], entries, - @"Should allow persisting unique entries"); + XCTAssertEqualObjects( + [self entriesFromDisk], + entries, + @"Should allow persisting unique entries" + ); } - (void)testPersistingUniqueEntriesWithNonEmptyStore @@ -120,16 +139,22 @@ - (void)testPersistingUniqueEntriesWithNonEmptyStore [self.store persist:@[self.entry]]; [self.store persist:entries]; - XCTAssertEqualObjects([self entriesFromDisk], entries, - @"Should allow persisting unique entries"); + XCTAssertEqualObjects( + [self entriesFromDisk], + entries, + @"Should allow persisting unique entries" + ); } - (void)testRetrievingWithoutPersistedEntries { NSArray> *retrievedEntries = [self.store retrieveEntries]; - XCTAssertEqualObjects(retrievedEntries, @[], - @"Retrieving entries should return an empty array when no items are persisted"); + XCTAssertEqualObjects( + retrievedEntries, + @[], + @"Retrieving entries should return an empty array when no items are persisted" + ); } - (void)testRetrievingClearsStore @@ -139,19 +164,24 @@ - (void)testRetrievingClearsStore NSArray> *retrieved = [self entriesFromDisk]; - XCTAssertNil(retrieved, - @"Retrieving should clear existing entries"); + XCTAssertNil( + retrieved, + @"Retrieving should clear existing entries" + ); } -- (void)testClearingStore { +- (void)testClearingStore +{ [self.store persist:@[self.entry]]; [self.store clear]; NSArray> *retrieved = [self entriesFromDisk]; - XCTAssertNil(retrieved, - @"A cleared store should be empty"); + XCTAssertNil( + retrieved, + @"A cleared store should be empty" + ); } // MARK: - Helpers diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m index 39ec843d77..34d0b749d1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKCoreKit+Internal.h" #import "FakeMonitorStore.h" @@ -41,7 +40,8 @@ @interface FBSDKMonitorTests : XCTestCase @end -@implementation FBSDKMonitorTests { +@implementation FBSDKMonitorTests +{ int flushLimit; double flushInterval; id networkerMock; @@ -76,11 +76,15 @@ - (void)tearDown [FBSDKMonitor setStore:nil]; } -- (void)testRecordingWhenDisabled { +- (void)testRecordingWhenDisabled +{ [FBSDKMonitor record:self.entry]; - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should not record entries before monitor is enabled"); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should not record entries before monitor is enabled" + ); } - (void)testEnabling @@ -89,8 +93,11 @@ - (void)testEnabling [FBSDKMonitor record:self.entry]; - XCTAssertEqualObjects(FBSDKMonitor.entries, @[self.entry], - @"Should record entries when monitor is enabled"); + XCTAssertEqualObjects( + FBSDKMonitor.entries, + @[self.entry], + @"Should record entries when monitor is enabled" + ); } - (void)testEnablingWhenEnabled @@ -100,16 +107,20 @@ - (void)testEnablingWhenEnabled [FBSDKMonitor enable]; // Should register for notifications - OCMVerify([notificationCenterMock addObserver:[FBSDKMonitor class] - selector:@selector(applicationMovingFromActiveStateOrTerminating) - name:[OCMArg any] - object:NULL]); + OCMVerify( + [notificationCenterMock addObserver:[FBSDKMonitor class] + selector:@selector(applicationMovingFromActiveStateOrTerminating) + name:[OCMArg any] + object:NULL] + ); // Should not re-register for notifications if still enabled - OCMReject([notificationCenterMock addObserver:[FBSDKMonitor class] - selector:@selector(applicationMovingFromActiveStateOrTerminating) - name:[OCMArg any] - object:NULL]); + OCMReject( + [notificationCenterMock addObserver:[FBSDKMonitor class] + selector:@selector(applicationMovingFromActiveStateOrTerminating) + name:[OCMArg any] + object:NULL] + ); [FBSDKMonitor enable]; } @@ -129,10 +140,15 @@ - (void)testDisabling [FBSDKMonitor disable]; - XCTAssertTrue(self.store.clearWasCalled, - @"Disabling monitoring should clear the persistent store"); - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Disabling monitoring should clear the locally stored entries"); + XCTAssertTrue( + self.store.clearWasCalled, + @"Disabling monitoring should clear the persistent store" + ); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Disabling monitoring should clear the locally stored entries" + ); OCMVerify([notificationCenterMock removeObserver:[FBSDKMonitor class]]); } @@ -147,7 +163,7 @@ - (void)testDisablingUnregistersNotifications [FBSDKMonitor disable]; // Should unregister for notifications when disabling - OCMVerify([notificationCenterMock removeObserver: [FBSDKMonitor class]]); + OCMVerify([notificationCenterMock removeObserver:[FBSDKMonitor class]]); } - (void)testDisablingWhenDisabled @@ -156,7 +172,7 @@ - (void)testDisablingWhenDisabled OCMStub([notificationCenterMock defaultCenter]).andReturn(notificationCenterMock); // Should not unregister for notifications if already disabled - OCMReject([notificationCenterMock removeObserver: [FBSDKMonitor class]]); + OCMReject([notificationCenterMock removeObserver:[FBSDKMonitor class]]); [FBSDKMonitor disable]; } @@ -171,10 +187,10 @@ - (void)testReDisabling [FBSDKMonitor disable]; // Should unregister for notifications when disabling - OCMVerify([notificationCenterMock removeObserver: [FBSDKMonitor class]]); + OCMVerify([notificationCenterMock removeObserver:[FBSDKMonitor class]]); // Should not unregister for notifications if already disabled - OCMReject([notificationCenterMock removeObserver: [FBSDKMonitor class]]); + OCMReject([notificationCenterMock removeObserver:[FBSDKMonitor class]]); [FBSDKMonitor disable]; } @@ -188,8 +204,11 @@ - (void)testFlushing [FBSDKMonitor flush]; - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Flushing should clear all entries"); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Flushing should clear all entries" + ); } - (void)testFlushingWithoutEntries @@ -209,10 +228,14 @@ - (void)testFlushingWithEntries [FBSDKMonitor record:entry2]; [FBSDKMonitor flush]; - OCMVerify(ClassMethod([networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL(id obj) { - XCTAssertEqualObjects(obj, expectedEntries); - return YES; - }]])); + OCMVerify( + ClassMethod( + [networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL (id obj) { + XCTAssertEqualObjects(obj, expectedEntries); + return YES; + }]] + ) + ); } - (void)testRecordingAtOneBelowFlushLimit @@ -228,8 +251,11 @@ - (void)testRecordingAtOneBelowFlushLimit [FBSDKMonitor record:[TestMonitorEntry testEntry]]; } - XCTAssertEqual(expectedEntries.count, flushLimit - 1, - @"Sanity check failed"); + XCTAssertEqual( + expectedEntries.count, + flushLimit - 1, + @"Sanity check failed" + ); } - (void)testRecordingAtFlushLimit @@ -242,14 +268,24 @@ - (void)testRecordingAtFlushLimit [FBSDKMonitor record:[TestMonitorEntry testEntry]]; } - XCTAssertEqual(expectedEntries.count, flushLimit, - @"Sanity check failed"); - - OCMVerify(ClassMethod([networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL(id obj) { - XCTAssertEqual([obj count], expectedEntries.count, - @"Should send the correct number of entries when the flush limit is reached"); - return YES; - }]])); + XCTAssertEqual( + expectedEntries.count, + flushLimit, + @"Sanity check failed" + ); + + OCMVerify( + ClassMethod( + [networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL (id obj) { + XCTAssertEqual( + [obj count], + expectedEntries.count, + @"Should send the correct number of entries when the flush limit is reached" + ); + return YES; + }]] + ) + ); } - (void)testRecordingPastFlushLimit @@ -260,13 +296,19 @@ - (void)testRecordingPastFlushLimit [FBSDKMonitor record:[TestMonitorEntry testEntry]]; } - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should flush entries after reaching threshold"); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should flush entries after reaching threshold" + ); [FBSDKMonitor record:self.entry]; - XCTAssertEqual(FBSDKMonitor.entries.count, 1, - @"Should continue to record entries after surpassing the flush limit"); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 1, + @"Should continue to record entries after surpassing the flush limit" + ); } - (void)testEnablingStartsFlushTimer @@ -274,21 +316,29 @@ - (void)testEnablingStartsFlushTimer [FBSDKMonitor enable]; [FBSDKMonitor record:self.entry]; - OCMVerify(ClassMethod([timerMock scheduledTimerWithTimeInterval:flushInterval - target:[FBSDKMonitor class] - selector:@selector(flush) - userInfo:nil - repeats:YES])); + OCMVerify( + ClassMethod( + [timerMock scheduledTimerWithTimeInterval:flushInterval + target:[FBSDKMonitor class] + selector:@selector(flush) + userInfo:nil + repeats:YES] + ) + ); [timerMock stopMocking]; } - (void)testDisablingInvalidatesFlushTimer { - OCMStub(ClassMethod([timerMock scheduledTimerWithTimeInterval:flushInterval - target:[FBSDKMonitor class] - selector:@selector(flush) - userInfo:nil - repeats:YES])).andReturn(timerMock); + OCMStub( + ClassMethod( + [timerMock scheduledTimerWithTimeInterval:flushInterval + target:[FBSDKMonitor class] + selector:@selector(flush) + userInfo:nil + repeats:YES] + ) + ).andReturn(timerMock); [FBSDKMonitor enable]; [FBSDKMonitor disable]; @@ -303,10 +353,12 @@ - (void)testBackgroundingWhenEnabledWithNoLocalEntries [FBSDKMonitor enable]; [NSNotificationCenter.defaultCenter - postNotificationName:UIApplicationWillResignActiveNotification object: nil]; + postNotificationName:UIApplicationWillResignActiveNotification object:nil]; - XCTAssertFalse(self.store.persistWasCalled, - @"Should not attempt to persist empty list of entries on backgrounding"); + XCTAssertFalse( + self.store.persistWasCalled, + @"Should not attempt to persist empty list of entries on backgrounding" + ); } - (void)testBackgroundingWhenEnabledWithLocalEntries @@ -315,10 +367,12 @@ - (void)testBackgroundingWhenEnabledWithLocalEntries [FBSDKMonitor record:self.entry]; [NSNotificationCenter.defaultCenter - postNotificationName:UIApplicationWillResignActiveNotification object: nil]; + postNotificationName:UIApplicationWillResignActiveNotification object:nil]; - XCTAssertTrue(self.store.persistWasCalled, - @"Should persist entries on backgrounding"); + XCTAssertTrue( + self.store.persistWasCalled, + @"Should persist entries on backgrounding" + ); } - (void)testBackgroundingWhenDisabled @@ -326,10 +380,12 @@ - (void)testBackgroundingWhenDisabled [FBSDKMonitor record:self.entry]; [NSNotificationCenter.defaultCenter - postNotificationName:UIApplicationWillResignActiveNotification object: nil]; + postNotificationName:UIApplicationWillResignActiveNotification object:nil]; - XCTAssertFalse(self.store.persistWasCalled, - @"Should not persist entries on backgrounding if the monitor is disabled"); + XCTAssertFalse( + self.store.persistWasCalled, + @"Should not persist entries on backgrounding if the monitor is disabled" + ); } - (void)testTerminatingWhenEnabledWithNoLocalEntries @@ -337,10 +393,12 @@ - (void)testTerminatingWhenEnabledWithNoLocalEntries [FBSDKMonitor enable]; [NSNotificationCenter.defaultCenter - postNotificationName:UIApplicationWillTerminateNotification object: nil]; + postNotificationName:UIApplicationWillTerminateNotification object:nil]; - XCTAssertFalse(self.store.persistWasCalled, - @"Should not attempt to persist empty list of entries on termination"); + XCTAssertFalse( + self.store.persistWasCalled, + @"Should not attempt to persist empty list of entries on termination" + ); } - (void)testTerminatingWhenEnabledWithLocalEntries @@ -349,10 +407,12 @@ - (void)testTerminatingWhenEnabledWithLocalEntries [FBSDKMonitor record:self.entry]; [NSNotificationCenter.defaultCenter - postNotificationName:UIApplicationWillTerminateNotification object: nil]; + postNotificationName:UIApplicationWillTerminateNotification object:nil]; - XCTAssertTrue(self.store.persistWasCalled, - @"Should persist entries on termination"); + XCTAssertTrue( + self.store.persistWasCalled, + @"Should persist entries on termination" + ); } - (void)testTerminatingWhenDisabled @@ -362,10 +422,12 @@ - (void)testTerminatingWhenDisabled [FBSDKMonitor record:self.entry]; [NSNotificationCenter.defaultCenter - postNotificationName:UIApplicationWillTerminateNotification object: nil]; + postNotificationName:UIApplicationWillTerminateNotification object:nil]; - XCTAssertFalse(self.store.persistWasCalled, - @"Should not persist entries on backgrounding if the monitor is disabled"); + XCTAssertFalse( + self.store.persistWasCalled, + @"Should not persist entries on backgrounding if the monitor is disabled" + ); } - (void)testForegroundingWhenEnabledWithNoLocalEntriesNoPersistedEntries @@ -378,10 +440,15 @@ - (void)testForegroundingWhenEnabledWithNoLocalEntriesNoPersistedEntries [NSNotificationCenter.defaultCenter postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; - XCTAssertTrue(self.store.retrieveEntriesWasCalled, - @"Should attempt to retrieve entries on foregrounding"); - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should set entries to the retrieved empty array"); + XCTAssertTrue( + self.store.retrieveEntriesWasCalled, + @"Should attempt to retrieve entries on foregrounding" + ); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should set entries to the retrieved empty array" + ); } - (void)testForegroundingWhenEnabledWithLocalEntriesNoPersistedEntries @@ -394,13 +461,23 @@ - (void)testForegroundingWhenEnabledWithLocalEntriesNoPersistedEntries postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; // Should invoke networker for locally persisted entry - OCMVerify(ClassMethod([networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL(id obj) { - XCTAssertEqualObjects(obj, entries, - @"Should send the local entries upon foregrounding"); - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should clear local entries after sending them"); - return YES; - }]])); + OCMVerify( + ClassMethod( + [networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL (id obj) { + XCTAssertEqualObjects( + obj, + entries, + @"Should send the local entries upon foregrounding" + ); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should clear local entries after sending them" + ); + return YES; + }]] + ) + ); } - (void)testForegroundingWhenEnabledWithNoLocalEntriesAndPersistedEntries @@ -415,13 +492,23 @@ - (void)testForegroundingWhenEnabledWithNoLocalEntriesAndPersistedEntries postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; // Should invoke networker if entries are retrieved - OCMVerify(ClassMethod([networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL(id obj) { - XCTAssertEqualObjects(obj, entries, - @"Should send the retrieved entries upon foregrounding"); - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should not persist retrieved entries on foregrounding"); - return YES; - }]])); + OCMVerify( + ClassMethod( + [networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL (id obj) { + XCTAssertEqualObjects( + obj, + entries, + @"Should send the retrieved entries upon foregrounding" + ); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should not persist retrieved entries on foregrounding" + ); + return YES; + }]] + ) + ); } - (void)testForegroundingWhenEnabledWithLocalEntriesAndPersistedEntries @@ -437,13 +524,23 @@ - (void)testForegroundingWhenEnabledWithLocalEntriesAndPersistedEntries postNotificationName:UIApplicationDidBecomeActiveNotification object:nil]; // Should invoke networker if entries are retrieved - OCMVerify(ClassMethod([networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL(id obj) { - XCTAssertEqualObjects(obj, expectedEntries, - @"Should send the local and retrieved entries upon foregrounding"); - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should not persist retrieved entries on foregrounding"); - return YES; - }]])); + OCMVerify( + ClassMethod( + [networkerMock sendEntries:[OCMArg checkWithBlock:^BOOL (id obj) { + XCTAssertEqualObjects( + obj, + expectedEntries, + @"Should send the local and retrieved entries upon foregrounding" + ); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should not persist retrieved entries on foregrounding" + ); + return YES; + }]] + ) + ); } - (void)testForegroundingWhenDisabledWithNoEntries diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorEntryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorEntryTests.m index 21b05477a8..cdcd074ad6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorEntryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorEntryTests.m @@ -25,7 +25,8 @@ @interface FBSDKPerformanceMonitorEntryTests : XCTestCase @end -@implementation FBSDKPerformanceMonitorEntryTests { +@implementation FBSDKPerformanceMonitorEntryTests +{ FBSDKPerformanceMonitorEntry *entry; } @@ -60,12 +61,21 @@ - (void)testCreatingEntryWithValidRange NSDictionary *actual = [entry dictionaryRepresentation]; - XCTAssertEqualObjects(actual[@"event_name"], @"Foo", - @"Should use the entry name as the event name"); - XCTAssertEqualObjects(actual[@"time_start"], expectedStartTime, - @"Should use unix time for the start time of the metric"); - XCTAssertEqualObjects(actual[@"time_spent"], @1, - @"Should capture the difference between the start and end-time of the metric"); + XCTAssertEqualObjects( + actual[@"event_name"], + @"Foo", + @"Should use the entry name as the event name" + ); + XCTAssertEqualObjects( + actual[@"time_start"], + expectedStartTime, + @"Should use unix time for the start time of the metric" + ); + XCTAssertEqualObjects( + actual[@"time_spent"], + @1, + @"Should capture the difference between the start and end-time of the metric" + ); } - (void)testEntryName @@ -74,8 +84,11 @@ - (void)testEntryName startTime:[NSDate date] endTime:[[NSDate date] dateByAddingTimeInterval:1]]; - XCTAssertEqualObjects(entry.name, @"Foo", - @"The entry name should be easily accessible"); + XCTAssertEqualObjects( + entry.name, + @"Foo", + @"The entry name should be easily accessible" + ); } - (void)testEncodingEntry @@ -89,12 +102,21 @@ - (void)testEncodingEntry [entry encodeWithCoder:coder]; - XCTAssertEqualObjects(coder.encodedObject[@"event_name"], @"Foo", - @"Should use the entry name as the event name for encoding"); - XCTAssertEqualObjects(coder.encodedObject[@"time_start"], startTime, - @"Should use unix time for encoding the start time of the metric"); - XCTAssertEqualObjects(coder.encodedObject[@"time_end"], [startTime dateByAddingTimeInterval:1], - @"Should encode the difference between the start and end-time of the metric"); + XCTAssertEqualObjects( + coder.encodedObject[@"event_name"], + @"Foo", + @"Should use the entry name as the event name for encoding" + ); + XCTAssertEqualObjects( + coder.encodedObject[@"time_start"], + startTime, + @"Should use unix time for encoding the start time of the metric" + ); + XCTAssertEqualObjects( + coder.encodedObject[@"time_end"], + [startTime dateByAddingTimeInterval:1], + @"Should encode the difference between the start and end-time of the metric" + ); } - (void)testDecodingEntry @@ -103,12 +125,21 @@ - (void)testDecodingEntry entry = [[FBSDKPerformanceMonitorEntry alloc] initWithCoder:coder]; - XCTAssertEqualObjects(coder.decodedObject[@"event_name"], [NSString class], - @"Initializing from a decoder should attempt to decode a String for the event name key"); - XCTAssertEqualObjects(coder.decodedObject[@"time_start"], [NSDate class], - @"Initializing from a decoder should attempt to decode a number for the time start key"); - XCTAssertEqualObjects(coder.decodedObject[@"time_end"], [NSDate class], - @"Initializing from a decoder should attempt to decode a number for the time spent key"); + XCTAssertEqualObjects( + coder.decodedObject[@"event_name"], + [NSString class], + @"Initializing from a decoder should attempt to decode a String for the event name key" + ); + XCTAssertEqualObjects( + coder.decodedObject[@"time_start"], + [NSDate class], + @"Initializing from a decoder should attempt to decode a number for the time start key" + ); + XCTAssertEqualObjects( + coder.decodedObject[@"time_end"], + [NSDate class], + @"Initializing from a decoder should attempt to decode a number for the time spent key" + ); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m index e2af7ec732..221d2ce2f4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m @@ -16,9 +16,8 @@ // 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 "FBSDKCoreKit+Internal.h" @@ -64,12 +63,22 @@ - (void)testRecordingPerformance FBSDKPerformanceMonitorEntry *entry = (FBSDKPerformanceMonitorEntry *) FBSDKMonitor.entries.firstObject; - XCTAssertEqualObjects(entry.dictionaryRepresentation[@"event_name"], @"Foo", - @"Entry should contain the event name"); - XCTAssertEqualObjects(entry.dictionaryRepresentation[@"time_start"], expectedStartTime, - @"Entry should contain the start time of the metric"); - XCTAssertEqualWithAccuracy([entry.dictionaryRepresentation[@"time_spent"] doubleValue], [@1 doubleValue], 0.1, - @"Entry should contain the difference between the start and end-time of the metric"); + XCTAssertEqualObjects( + entry.dictionaryRepresentation[@"event_name"], + @"Foo", + @"Entry should contain the event name" + ); + XCTAssertEqualObjects( + entry.dictionaryRepresentation[@"time_start"], + expectedStartTime, + @"Entry should contain the start time of the metric" + ); + XCTAssertEqualWithAccuracy( + [entry.dictionaryRepresentation[@"time_spent"] doubleValue], + [@1 doubleValue], + 0.1, + @"Entry should contain the difference between the start and end-time of the metric" + ); } - (void)testRecordingPerformanceWithInvalidInterval @@ -79,8 +88,11 @@ - (void)testRecordingPerformanceWithInvalidInterval [FBSDKPerformanceMonitor record:@"Foo" startTime:date]; - XCTAssertEqual(FBSDKMonitor.entries.count, 0, - @"Should not add invalid entries to the monitor"); + XCTAssertEqual( + FBSDKMonitor.entries.count, + 0, + @"Should not add invalid entries to the monitor" + ); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.h index ce8ba77512..8a659ec0b2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface TestMonitorEntry : NSObject +@interface TestMonitorEntry : NSObject @property (nonatomic, copy) NSString *name; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.m index e609cca807..3eca7df108 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/TestMonitorEntry.m @@ -84,5 +84,4 @@ - (NSUInteger)hash return [self.name hash]; } - @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m index 43d770ff59..615f04bafc 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m @@ -16,9 +16,9 @@ // 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 #import "FBSDKCoreKit+Internal.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m index 023990f944..6e83823990 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m @@ -16,14 +16,14 @@ // 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 "FBSDKCoreKit+Internal.h" -#import "FBSDKServerConfigurationFixtures.h" #import "FBSDKEventBinding.h" -#import "FBSDKTestCoder.h" #import "FBSDKMonitoringConfigurationTestHelper.h" +#import "FBSDKServerConfigurationFixtures.h" +#import "FBSDKTestCoder.h" @interface FBSDKServerConfiguration (Testing) @@ -41,7 +41,8 @@ @interface FBSDKMonitoringConfiguration (Testing) @interface FBSDKServerConfigurationTests : XCTestCase @end -@implementation FBSDKServerConfigurationTests { +@implementation FBSDKServerConfigurationTests +{ FBSDKServerConfiguration *config; } @@ -66,7 +67,7 @@ - (void)testUsingDefaults { XCTAssertTrue(config.defaults, "Should assume defaults are being used unless otherwise expressed"); - config = [Fixtures configWithDictionary:@{@"defaults": @NO}]; + config = [Fixtures configWithDictionary:@{@"defaults" : @NO}]; XCTAssertFalse(config.defaults, "Should store whether or not defaults are being used"); } @@ -77,74 +78,97 @@ - (void)testCreatingWithoutAppID - (void)testCreatingWithEmptyAppID { - config = [Fixtures configWithDictionary:@{@"appID": @""}]; - XCTAssertEqualObjects(config.appID, @"", - "Should use the given app identifier regardless of value"); + config = [Fixtures configWithDictionary:@{@"appID" : @""}]; + XCTAssertEqualObjects( + config.appID, + @"", + "Should use the given app identifier regardless of value" + ); } - (void)testCreatingWithDefaultAdvertisingIdEnabled { - XCTAssertFalse(config.isAdvertisingIDEnabled, - "Advertising identifier enabled should default to false"); + XCTAssertFalse( + config.isAdvertisingIDEnabled, + "Advertising identifier enabled should default to false" + ); } - (void)testCreatingWithKnownAdvertisingIdEnabled { - config = [Fixtures configWithDictionary:@{@"advertisingIDEnabled": @YES}]; - XCTAssertTrue(config.isAdvertisingIDEnabled, - "Advertising identifier enabled should be settable"); + config = [Fixtures configWithDictionary:@{@"advertisingIDEnabled" : @YES}]; + XCTAssertTrue( + config.isAdvertisingIDEnabled, + "Advertising identifier enabled should be settable" + ); } - (void)testCreatingWithDefaultImplicitPurchaseLoggingEnabled { - XCTAssertFalse(config.implicitPurchaseLoggingEnabled, - "Implicit purchase logging enabled should default to false"); + XCTAssertFalse( + config.implicitPurchaseLoggingEnabled, + "Implicit purchase logging enabled should default to false" + ); } - (void)testCreatingWithKnownImplicitPurchaseLoggingEnabled { - config = [Fixtures configWithDictionary:@{@"implicitPurchaseLoggingEnabled": @YES}]; - XCTAssertTrue(config.implicitPurchaseLoggingEnabled, - "Implicit purchase logging enabled should be settable"); + config = [Fixtures configWithDictionary:@{@"implicitPurchaseLoggingEnabled" : @YES}]; + XCTAssertTrue( + config.implicitPurchaseLoggingEnabled, + "Implicit purchase logging enabled should be settable" + ); } - (void)testCreatingWithDefaultImplicitLoggingEnabled { - XCTAssertFalse(config.implicitLoggingEnabled, - "Implicit logging enabled should default to false"); + XCTAssertFalse( + config.implicitLoggingEnabled, + "Implicit logging enabled should default to false" + ); } - (void)testCreatingWithKnownImplicitLoggingEnabled { - config = [Fixtures configWithDictionary:@{@"implicitLoggingEnabled": @YES}]; - XCTAssertTrue(config.implicitLoggingEnabled, - "Implicit logging enabled should be settable"); + config = [Fixtures configWithDictionary:@{@"implicitLoggingEnabled" : @YES}]; + XCTAssertTrue( + config.implicitLoggingEnabled, + "Implicit logging enabled should be settable" + ); } - (void)testCreatingWithDefaultCodelessEventsEnabled { - XCTAssertFalse(config.codelessEventsEnabled, - "Codeless events enabled should default to false"); + XCTAssertFalse( + config.codelessEventsEnabled, + "Codeless events enabled should default to false" + ); } - (void)testCreatingWithKnownCodelessEventsEnabled { - config = [Fixtures configWithDictionary:@{@"codelessEventsEnabled": @YES}]; - XCTAssertTrue(config.codelessEventsEnabled, - "Codeless events enabled should be settable"); + config = [Fixtures configWithDictionary:@{@"codelessEventsEnabled" : @YES}]; + XCTAssertTrue( + config.codelessEventsEnabled, + "Codeless events enabled should be settable" + ); } - (void)testCreatingWithDefaultUninstallTrackingEnabled { - XCTAssertFalse(config.uninstallTrackingEnabled, - "Uninstall tracking enabled should default to false"); + XCTAssertFalse( + config.uninstallTrackingEnabled, + "Uninstall tracking enabled should default to false" + ); } - (void)testCreatingWithKnownUninstallTrackingEnabled { - config = [Fixtures configWithDictionary:@{@"uninstallTrackingEnabled": @YES}]; - XCTAssertTrue(config.uninstallTrackingEnabled, - "Uninstall tracking enabled should be settable"); + config = [Fixtures configWithDictionary:@{@"uninstallTrackingEnabled" : @YES}]; + XCTAssertTrue( + config.uninstallTrackingEnabled, + "Uninstall tracking enabled should be settable" + ); } - (void)testCreatingWithoutAppName @@ -154,49 +178,67 @@ - (void)testCreatingWithoutAppName - (void)testCreatingWithEmptyAppName { - config = [Fixtures configWithDictionary:@{@"appName": @""}]; - XCTAssertEqualObjects(config.appName, @"", - "Should use the given app name regardless of value"); + config = [Fixtures configWithDictionary:@{@"appName" : @""}]; + XCTAssertEqualObjects( + config.appName, + @"", + "Should use the given app name regardless of value" + ); } - (void)testCreatingWithKnownAppName { - config = [Fixtures configWithDictionary:@{@"appName": @"foo"}]; - XCTAssertEqual(config.appName, @"foo", - "App name should be settable"); + config = [Fixtures configWithDictionary:@{@"appName" : @"foo"}]; + XCTAssertEqual( + config.appName, + @"foo", + "App name should be settable" + ); } - (void)testCreatingWithoutDefaultShareMode { - XCTAssertNil(config.defaultShareMode, - "Should not provide a default for the default share mode"); + XCTAssertNil( + config.defaultShareMode, + "Should not provide a default for the default share mode" + ); } - (void)testCreatingWithKnownDefaultShareMode { - config = [Fixtures configWithDictionary:@{@"defaultShareMode": @"native"}]; - XCTAssertEqual(config.defaultShareMode, @"native", - "Default share mode should be settable"); + config = [Fixtures configWithDictionary:@{@"defaultShareMode" : @"native"}]; + XCTAssertEqual( + config.defaultShareMode, + @"native", + "Default share mode should be settable" + ); } - (void)testCreatingWithEmptyDefaultShareMode { - config = [Fixtures configWithDictionary:@{@"defaultShareMode": @""}]; - XCTAssertEqual(config.defaultShareMode, @"", - "Should use the given share mode regardless of value"); + config = [Fixtures configWithDictionary:@{@"defaultShareMode" : @""}]; + XCTAssertEqual( + config.defaultShareMode, + @"", + "Should use the given share mode regardless of value" + ); } - (void)testCreatingWithDefaultLoginTooltipEnabled { - XCTAssertFalse(config.loginTooltipEnabled, - "Login tooltip enabled should default to false"); + XCTAssertFalse( + config.loginTooltipEnabled, + "Login tooltip enabled should default to false" + ); } - (void)testCreatingWithKnownLoginTooltipEnabled { - config = [Fixtures configWithDictionary:@{@"loginTooltipEnabled": @YES}]; - XCTAssertTrue(config.loginTooltipEnabled, - "Login tooltip enabled should be settable"); + config = [Fixtures configWithDictionary:@{@"loginTooltipEnabled" : @YES}]; + XCTAssertTrue( + config.loginTooltipEnabled, + "Login tooltip enabled should be settable" + ); } - (void)testCreatingWithoutLoginTooltipText @@ -206,16 +248,22 @@ - (void)testCreatingWithoutLoginTooltipText - (void)testCreatingWithEmptyLoginTooltipText { - config = [Fixtures configWithDictionary:@{@"loginTooltipText": @""}]; - XCTAssertEqualObjects(config.loginTooltipText, @"", - "Should use the given login tooltip text regardless of value"); + config = [Fixtures configWithDictionary:@{@"loginTooltipText" : @""}]; + XCTAssertEqualObjects( + config.loginTooltipText, + @"", + "Should use the given login tooltip text regardless of value" + ); } - (void)testCreatingWithKnownLoginTooltipText { - config = [Fixtures configWithDictionary:@{@"loginTooltipText": @"foo"}]; - XCTAssertEqual(config.loginTooltipText, @"foo", - "Login tooltip text should be settable"); + config = [Fixtures configWithDictionary:@{@"loginTooltipText" : @"foo"}]; + XCTAssertEqual( + config.loginTooltipText, + @"foo", + "Login tooltip text should be settable" + ); } - (void)testCreatingWithoutTimestamp @@ -226,73 +274,106 @@ - (void)testCreatingWithoutTimestamp - (void)testCreatingWithTimestamp { NSDate *date = [NSDate date]; - config = [Fixtures configWithDictionary:@{@"timestamp": date}]; - XCTAssertEqualObjects(config.timestamp, date, - "Should use the timestamp given during creation"); + config = [Fixtures configWithDictionary:@{@"timestamp" : date}]; + XCTAssertEqualObjects( + config.timestamp, + date, + "Should use the timestamp given during creation" + ); } - (void)testCreatingWithDefaultSessionTimeoutInterval { - XCTAssertEqual(config.sessionTimoutInterval, 60, - "Should set the correct default timeout interval"); + XCTAssertEqual( + config.sessionTimoutInterval, + 60, + "Should set the correct default timeout interval" + ); } - (void)testCreatingWithSessionTimeoutInterval { - config = [Fixtures configWithDictionary:@{@"sessionTimeoutInterval": @200}]; - XCTAssertEqual(config.sessionTimoutInterval, 200, - "Should set the session timeout interval from the remote"); + config = [Fixtures configWithDictionary:@{@"sessionTimeoutInterval" : @200}]; + XCTAssertEqual( + config.sessionTimoutInterval, + 200, + "Should set the session timeout interval from the remote" + ); } -- (void)testCreatingWithoutLoggingToken { - XCTAssertNil(config.loggingToken, - "Should not provide a default for the logging token"); +- (void)testCreatingWithoutLoggingToken +{ + XCTAssertNil( + config.loggingToken, + "Should not provide a default for the logging token" + ); } -- (void)testCreatingWithEmptyLoggingToken { - config = [Fixtures configWithDictionary:@{@"loggingToken": @""}]; - XCTAssertEqualObjects(config.loggingToken, @"", - "Should use the logging token given during creation"); +- (void)testCreatingWithEmptyLoggingToken +{ + config = [Fixtures configWithDictionary:@{@"loggingToken" : @""}]; + XCTAssertEqualObjects( + config.loggingToken, + @"", + "Should use the logging token given during creation" + ); } -- (void)testCreatingWithKnownLoggingToken { - config = [Fixtures configWithDictionary:@{@"loggingToken": @"foo"}]; - XCTAssertEqualObjects(config.loggingToken, @"foo", - "Should use the logging token given during creation"); +- (void)testCreatingWithKnownLoggingToken +{ + config = [Fixtures configWithDictionary:@{@"loggingToken" : @"foo"}]; + XCTAssertEqualObjects( + config.loggingToken, + @"foo", + "Should use the logging token given during creation" + ); } - (void)testCreatingWithoutSmartLoginBookmarkUrl { - XCTAssertNil(config.smartLoginBookmarkIconURL, - "Should not provide a default url for the smart login bookmark icon"); + XCTAssertNil( + config.smartLoginBookmarkIconURL, + "Should not provide a default url for the smart login bookmark icon" + ); } - (void)testCreatingWithInvalidSmartLoginBookmarkUrl { - config = [Fixtures configWithDictionary:@{@"smartLoginBookmarkIconURL": [NSURL URLWithString:@""]}]; - XCTAssertEqualObjects(config.smartLoginBookmarkIconURL, [NSURL URLWithString:@""], - "Should use the url given during creation"); + config = [Fixtures configWithDictionary:@{@"smartLoginBookmarkIconURL" : [NSURL URLWithString:@""]}]; + XCTAssertEqualObjects( + config.smartLoginBookmarkIconURL, + [NSURL URLWithString:@""], + "Should use the url given during creation" + ); } - (void)testCreatingWithValidSmartBookmarkUrl { - config = [Fixtures configWithDictionary:@{@"smartLoginBookmarkIconURL": [NSURL URLWithString:@"http://www.example.com"]}]; - XCTAssertEqualObjects(config.smartLoginBookmarkIconURL, [NSURL URLWithString:@"http://www.example.com"], - "Should use the url given during creation"); + config = [Fixtures configWithDictionary:@{@"smartLoginBookmarkIconURL" : [NSURL URLWithString:@"http://www.example.com"]}]; + XCTAssertEqualObjects( + config.smartLoginBookmarkIconURL, + [NSURL URLWithString:@"http://www.example.com"], + "Should use the url given during creation" + ); } - - (void)testCreatingWithSmartLoginOptionsDefault { - XCTAssertEqual(config.smartLoginOptions, FBSDKServerConfigurationSmartLoginOptionsUnknown, - "Should default smart login options to unknown"); + XCTAssertEqual( + config.smartLoginOptions, + FBSDKServerConfigurationSmartLoginOptionsUnknown, + "Should default smart login options to unknown" + ); } - (void)testCreatingWithSmartLoginOptionsEnabled { - config = [Fixtures configWithDictionary:@{@"smartLoginOptions": [NSNumber numberWithInt:FBSDKServerConfigurationSmartLoginOptionsEnabled]}]; - XCTAssertEqual(config.smartLoginOptions, FBSDKServerConfigurationSmartLoginOptionsEnabled, - "Should use the smartLoginOptions given during creation"); + config = [Fixtures configWithDictionary:@{@"smartLoginOptions" : [NSNumber numberWithInt:FBSDKServerConfigurationSmartLoginOptionsEnabled]}]; + XCTAssertEqual( + config.smartLoginOptions, + FBSDKServerConfigurationSmartLoginOptionsEnabled, + "Should use the smartLoginOptions given during creation" + ); } - (void)testCreatingWithoutErrorConfiguration @@ -303,91 +384,123 @@ - (void)testCreatingWithoutErrorConfiguration - (void)testCreatingWithErrorConfiguration { FBSDKErrorConfiguration *errorConfig = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; - config = [Fixtures configWithDictionary:@{@"errorConfiguration": errorConfig}]; + config = [Fixtures configWithDictionary:@{@"errorConfiguration" : errorConfig}]; - XCTAssertEqualObjects(config.errorConfiguration, errorConfig, - @"Error configuration should be settable"); + XCTAssertEqualObjects( + config.errorConfiguration, + errorConfig, + @"Error configuration should be settable" + ); } - (void)testCreatingWithoutSmartLoginMenuUrl { - XCTAssertNil(config.smartLoginMenuIconURL, - "Should not provide a default url for the smart login menu icon"); + XCTAssertNil( + config.smartLoginMenuIconURL, + "Should not provide a default url for the smart login menu icon" + ); } - (void)testCreatingWithInvalidSmartLoginMenuUrl { - config = [Fixtures configWithDictionary:@{@"smartLoginMenuIconURL": [NSURL URLWithString:@""]}]; - XCTAssertEqualObjects(config.smartLoginMenuIconURL, [NSURL URLWithString:@""], - "Should use the url given during creation"); + config = [Fixtures configWithDictionary:@{@"smartLoginMenuIconURL" : [NSURL URLWithString:@""]}]; + XCTAssertEqualObjects( + config.smartLoginMenuIconURL, + [NSURL URLWithString:@""], + "Should use the url given during creation" + ); } - (void)testCreatingWithValidSmartLoginMenuUrl { - config = [Fixtures configWithDictionary:@{@"smartLoginMenuIconURL": [NSURL URLWithString:@"http://www.example.com"]}]; - XCTAssertEqualObjects(config.smartLoginMenuIconURL, [NSURL URLWithString:@"http://www.example.com"], - "Should use the url given during creation"); + config = [Fixtures configWithDictionary:@{@"smartLoginMenuIconURL" : [NSURL URLWithString:@"http://www.example.com"]}]; + XCTAssertEqualObjects( + config.smartLoginMenuIconURL, + [NSURL URLWithString:@"http://www.example.com"], + "Should use the url given during creation" + ); } - (void)testCreatingWithoutUpdateMessage { - XCTAssertNil(config.updateMessage, - "Should not provide a default for the update message"); + XCTAssertNil( + config.updateMessage, + "Should not provide a default for the update message" + ); } - (void)testCreatingWithEmptyUpdateMessage { - config = [Fixtures configWithDictionary:@{@"updateMessage": @""}]; - XCTAssertEqualObjects(config.updateMessage, @"", - "Should use the update message given during creation"); + config = [Fixtures configWithDictionary:@{@"updateMessage" : @""}]; + XCTAssertEqualObjects( + config.updateMessage, + @"", + "Should use the update message given during creation" + ); } - (void)testCreatingWithKnownUpdateMessage { - config = [Fixtures configWithDictionary:@{@"updateMessage": @"foo"}]; - XCTAssertEqualObjects(config.updateMessage, @"foo", - "Should use the update message given during creation"); + config = [Fixtures configWithDictionary:@{@"updateMessage" : @"foo"}]; + XCTAssertEqualObjects( + config.updateMessage, + @"foo", + "Should use the update message given during creation" + ); } - (void)testCreatingWithoutEventBindings { - XCTAssertNil(config.eventBindings, - "Should not provide default event bindings"); + XCTAssertNil( + config.eventBindings, + "Should not provide default event bindings" + ); } - (void)testCreatingWithEmptyEventBindings { - config = [Fixtures configWithDictionary:@{@"eventBindings": @[]}]; + config = [Fixtures configWithDictionary:@{@"eventBindings" : @[]}]; XCTAssertNotNil(config.eventBindings, "Should use the empty list of event bindings it was created with"); - XCTAssertEqual(config.eventBindings.count, 0, - "Should use the empty list of event bindings it was created with"); + XCTAssertEqual( + config.eventBindings.count, + 0, + "Should use the empty list of event bindings it was created with" + ); } - (void)testCreatingWithEventBindings { NSArray *bindings = @[[FBSDKEventBinding new]]; - config = [Fixtures configWithDictionary:@{@"eventBindings": bindings}]; + config = [Fixtures configWithDictionary:@{@"eventBindings" : bindings}]; - XCTAssertEqualObjects(config.eventBindings, bindings, - @"Event binding should be settable"); + XCTAssertEqualObjects( + config.eventBindings, + bindings, + @"Event binding should be settable" + ); } - (void)testCreatingWithoutDialogConfigurations { - XCTAssertNil(config.dialogConfigurations, - @"Should not have dialog configurations by default"); + XCTAssertNil( + config.dialogConfigurations, + @"Should not have dialog configurations by default" + ); } - (void)testCreatingWithDialogConfigurations { NSDictionary *dialogConfigurations = @{ - @"dialog": @"Hello", - @"dialog2": @"World" + @"dialog" : @"Hello", + @"dialog2" : @"World" }; - config = [Fixtures configWithDictionary:@{@"dialogConfigurations": dialogConfigurations}]; - XCTAssertEqualObjects(config.dialogConfigurations, dialogConfigurations, - "Should set the exact dialog configurations it was created with"); + config = [Fixtures configWithDictionary:@{@"dialogConfigurations" : dialogConfigurations}]; + XCTAssertEqualObjects( + config.dialogConfigurations, + dialogConfigurations, + "Should set the exact dialog configurations it was created with" + ); } - (void)testCreatingWithoutDialogFlowsBelowIosVersion9 @@ -401,12 +514,12 @@ - (void)testCreatingWithoutDialogFlowsBelowIosVersion9 config = [FBSDKServerConfiguration defaultServerConfigurationForAppID:self.name]; NSDictionary *expectedDefaultDialogFlows = @{ - FBSDKDialogConfigurationNameDefault: @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @NO, - FBSDKDialogConfigurationFeatureUseSafariViewController: @YES, + FBSDKDialogConfigurationNameDefault : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @NO, + FBSDKDialogConfigurationFeatureUseSafariViewController : @YES, }, - FBSDKDialogConfigurationNameMessage: @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @YES, + FBSDKDialogConfigurationNameMessage : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, }, }; @@ -424,137 +537,159 @@ - (void)testCreatingWithoutDialogFlowsAboveIosVersion9 config = [FBSDKServerConfiguration defaultServerConfigurationForAppID:self.name]; NSDictionary *expectedDefaultDialogFlows = @{ - FBSDKDialogConfigurationNameDefault: @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @YES, - FBSDKDialogConfigurationFeatureUseSafariViewController: @YES, + FBSDKDialogConfigurationNameDefault : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, + FBSDKDialogConfigurationFeatureUseSafariViewController : @YES, }, - FBSDKDialogConfigurationNameMessage: @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @YES, + FBSDKDialogConfigurationNameMessage : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, }, }; XCTAssertEqualObjects(config.dialogFlows, expectedDefaultDialogFlows); } - - (void)testCreatingWithDialogFlows { - NSDictionary *dialogFlows = @{ - @"foo": @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @YES, - FBSDKDialogConfigurationFeatureUseSafariViewController: @YES, + NSDictionary *dialogFlows = @{ + @"foo" : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, + FBSDKDialogConfigurationFeatureUseSafariViewController : @YES, }, - @"bar": @{ - FBSDKDialogConfigurationFeatureUseNativeFlow: @NO, + @"bar" : @{ + FBSDKDialogConfigurationFeatureUseNativeFlow : @NO, } }; - config = [Fixtures configWithDictionary:@{@"dialogFlows": dialogFlows}]; + config = [Fixtures configWithDictionary:@{@"dialogFlows" : dialogFlows}]; - XCTAssertEqualObjects(config.dialogFlows, dialogFlows, - "Should set the exact dialog flows it was created with"); + XCTAssertEqualObjects( + config.dialogFlows, + dialogFlows, + "Should set the exact dialog flows it was created with" + ); } - (void)testCreatingWithoutAAMRules { - XCTAssertNil(config.AAMRules, - @"Should not have aam rules by default"); + XCTAssertNil( + config.AAMRules, + @"Should not have aam rules by default" + ); } - (void)testCreatingWithAAMRules { - NSDictionary *rules = @{ @"foo": @"bar" }; + NSDictionary *rules = @{ @"foo" : @"bar" }; - config = [Fixtures configWithDictionary:@{@"aamRules": rules}]; + config = [Fixtures configWithDictionary:@{@"aamRules" : rules}]; - XCTAssertEqualObjects(config.AAMRules, rules, - "Should set the exact aam rules it was created with"); + XCTAssertEqualObjects( + config.AAMRules, + rules, + "Should set the exact aam rules it was created with" + ); } - (void)testCreatingWithoutRestrictiveParams { - XCTAssertNil(config.restrictiveParams, - @"Should not have restrictive params by default"); + XCTAssertNil( + config.restrictiveParams, + @"Should not have restrictive params by default" + ); } - (void)testCreatingWithRestrictiveParams { - NSDictionary *params = @{ @"foo": @"bar" }; + NSDictionary *params = @{ @"foo" : @"bar" }; - config = [Fixtures configWithDictionary:@{@"restrictiveParams": params}]; + config = [Fixtures configWithDictionary:@{@"restrictiveParams" : params}]; - XCTAssertEqualObjects(config.restrictiveParams, params, - "Should set the exact restrictive params it was created with"); + XCTAssertEqualObjects( + config.restrictiveParams, + params, + "Should set the exact restrictive params it was created with" + ); } - (void)testCreatingWithoutSuggestedEventSetting { - XCTAssertNil(config.suggestedEventsSetting, - @"Should not have a suggested events setting by default"); + XCTAssertNil( + config.suggestedEventsSetting, + @"Should not have a suggested events setting by default" + ); } - (void)testCreatingWithSuggestedEventSetting { - NSDictionary *setting = @{ @"foo": @"bar" }; + NSDictionary *setting = @{ @"foo" : @"bar" }; - config = [Fixtures configWithDictionary:@{@"suggestedEventsSetting": setting}]; + config = [Fixtures configWithDictionary:@{@"suggestedEventsSetting" : setting}]; - XCTAssertEqualObjects(config.suggestedEventsSetting, setting, - "Should set the exact suggested events setting it was created with"); + XCTAssertEqualObjects( + config.suggestedEventsSetting, + setting, + "Should set the exact suggested events setting it was created with" + ); } - (void)testCreatingWithoutMonitoringConfiguration { - XCTAssertEqualObjects(config.monitoringConfiguration.sampleRates, - FBSDKMonitoringConfiguration.defaultConfiguration.sampleRates, - @"Should use the default monitoring configuration if none is provided"); + XCTAssertEqualObjects( + config.monitoringConfiguration.sampleRates, + FBSDKMonitoringConfiguration.defaultConfiguration.sampleRates, + @"Should use the default monitoring configuration if none is provided" + ); } - (void)testCreatingWithMonitoringConfiguration { - NSDictionary *sampleRates = [MonitoringConfiguration sampleRatesWithEntryPairs: @{ @"foo": @1 }]; + NSDictionary *sampleRates = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo" : @1 }]; FBSDKMonitoringConfiguration *monitoringConfiguration = [FBSDKMonitoringConfiguration fromDictionary:sampleRates]; - config = [Fixtures configWithDictionary:@{@"monitoringConfiguration": monitoringConfiguration}]; + config = [Fixtures configWithDictionary:@{@"monitoringConfiguration" : monitoringConfiguration}]; - XCTAssertEqualObjects(config.monitoringConfiguration, monitoringConfiguration, - "Should set the exact monitoring configuration it was created with"); + XCTAssertEqualObjects( + config.monitoringConfiguration, + monitoringConfiguration, + "Should set the exact monitoring configuration it was created with" + ); } - (void)testEncoding { FBSDKTestCoder *coder = [FBSDKTestCoder new]; FBSDKErrorConfiguration *errorConfig = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; - NSDictionary *sampleRates = [MonitoringConfiguration sampleRatesWithEntryPairs: @{ @"foo": @1 }]; + NSDictionary *sampleRates = [MonitoringConfiguration sampleRatesWithEntryPairs:@{ @"foo" : @1 }]; FBSDKMonitoringConfiguration *monitoringConfiguration = [FBSDKMonitoringConfiguration fromDictionary:sampleRates]; config = [Fixtures configWithDictionary:@{ - @"appID": @"appID", - @"appName": @"appName", - @"loginTooltipEnabled": @YES, - @"loginTooltipText": @"loginTooltipText", - @"defaultShareMode": @"defaultShareMode", - @"advertisingIDEnabled": @YES, - @"implicitLoggingEnabled": @YES, - @"implicitPurchaseLoggingEnabled": @YES, - @"codelessEventsEnabled" : @YES, - @"uninstallTrackingEnabled" : @YES, - @"dialogFlows": @{@"Foo": @"Bar"}, - @"timestamp": [NSDate date], - @"errorConfiguration": errorConfig, - @"sessionTimeoutInterval": @100, - @"defaults": @NO, - @"loggingToken": @"loggingToken", - @"smartLoginOptions": [NSNumber numberWithInt: FBSDKServerConfigurationSmartLoginOptionsEnabled], - @"smartLoginBookmarkIconURL": [NSURL URLWithString:@"https://example.com"], - @"smartLoginMenuIconURL": [NSURL URLWithString:@"https://example.com"], - @"updateMessage": @"updateMessage", - @"eventBindings": @{ @"foo": @"bar" }, - @"restrictiveParams": @{ @"restrictiveParams": @"foo" }, - @"AAMRules": @{ @"AAMRules": @"foo" }, - @"suggestedEventsSetting": @{ @"suggestedEventsSetting": @"foo" }, - @"monitoringConfiguration": monitoringConfiguration - }]; + @"appID" : @"appID", + @"appName" : @"appName", + @"loginTooltipEnabled" : @YES, + @"loginTooltipText" : @"loginTooltipText", + @"defaultShareMode" : @"defaultShareMode", + @"advertisingIDEnabled" : @YES, + @"implicitLoggingEnabled" : @YES, + @"implicitPurchaseLoggingEnabled" : @YES, + @"codelessEventsEnabled" : @YES, + @"uninstallTrackingEnabled" : @YES, + @"dialogFlows" : @{@"Foo" : @"Bar"}, + @"timestamp" : [NSDate date], + @"errorConfiguration" : errorConfig, + @"sessionTimeoutInterval" : @100, + @"defaults" : @NO, + @"loggingToken" : @"loggingToken", + @"smartLoginOptions" : [NSNumber numberWithInt:FBSDKServerConfigurationSmartLoginOptionsEnabled], + @"smartLoginBookmarkIconURL" : [NSURL URLWithString:@"https://example.com"], + @"smartLoginMenuIconURL" : [NSURL URLWithString:@"https://example.com"], + @"updateMessage" : @"updateMessage", + @"eventBindings" : @{ @"foo" : @"bar" }, + @"restrictiveParams" : @{ @"restrictiveParams" : @"foo" }, + @"AAMRules" : @{ @"AAMRules" : @"foo" }, + @"suggestedEventsSetting" : @{ @"suggestedEventsSetting" : @"foo" }, + @"monitoringConfiguration" : monitoringConfiguration + }]; [config encodeWithCoder:coder]; @@ -572,8 +707,10 @@ - (void)testEncoding XCTAssertEqualObjects(coder.encodedObject[@"timestamp"], config.timestamp); XCTAssertEqualObjects(coder.encodedObject[@"errorConfigs"], config.errorConfiguration); XCTAssertEqual([coder.encodedObject[@"sessionTimeoutInterval"] intValue], config.sessionTimoutInterval); - XCTAssertNil(coder.encodedObject[@"defaults"], - @"Should not encode whether default values were used to create server configuration"); + XCTAssertNil( + coder.encodedObject[@"defaults"], + @"Should not encode whether default values were used to create server configuration" + ); XCTAssertEqualObjects(coder.encodedObject[@"loggingToken"], config.loggingToken); XCTAssertEqual([coder.encodedObject[@"smartLoginEnabled"] intValue], config.smartLoginOptions); XCTAssertEqualObjects(coder.encodedObject[@"smarstLoginBookmarkIconURL"], config.smartLoginBookmarkIconURL); @@ -599,30 +736,56 @@ - (void)testDecoding XCTAssertEqualObjects(decoder.decodedObject[@"appID"], NSString.class); XCTAssertEqualObjects(decoder.decodedObject[@"appName"], NSString.class); - XCTAssertEqualObjects(decoder.decodedObject[@"loginTooltipEnabled"], @"decodeBoolForKey", - @"Should decode loginTooltipEnabled as a BOOL"); + XCTAssertEqualObjects( + decoder.decodedObject[@"loginTooltipEnabled"], + @"decodeBoolForKey", + @"Should decode loginTooltipEnabled as a BOOL" + ); XCTAssertEqualObjects(decoder.decodedObject[@"loginTooltipText"], NSString.class); XCTAssertEqualObjects(decoder.decodedObject[@"defaultShareMode"], NSString.class); - XCTAssertEqualObjects(decoder.decodedObject[@"advertisingIDEnabled"], @"decodeBoolForKey", - @"Should decode advertisingIDEnabled as a BOOL"); - XCTAssertEqualObjects(decoder.decodedObject[@"implicitLoggingEnabled"], @"decodeBoolForKey", - @"Should decode implicitLoggingEnabled as a BOOL"); - XCTAssertEqualObjects(decoder.decodedObject[@"implicitPurchaseLoggingEnabled"], @"decodeBoolForKey", - @"Should decode implicitPurchaseLoggingEnabled as a BOOL"); - XCTAssertEqualObjects(decoder.decodedObject[@"codelessEventsEnabled"], @"decodeBoolForKey", - @"Should decode codelessEventsEnabled as a BOOL"); - XCTAssertEqualObjects(decoder.decodedObject[@"trackAppUninstallEnabled"], @"decodeBoolForKey", - @"Should decode trackAppUninstallEnabled as a BOOL"); + XCTAssertEqualObjects( + decoder.decodedObject[@"advertisingIDEnabled"], + @"decodeBoolForKey", + @"Should decode advertisingIDEnabled as a BOOL" + ); + XCTAssertEqualObjects( + decoder.decodedObject[@"implicitLoggingEnabled"], + @"decodeBoolForKey", + @"Should decode implicitLoggingEnabled as a BOOL" + ); + XCTAssertEqualObjects( + decoder.decodedObject[@"implicitPurchaseLoggingEnabled"], + @"decodeBoolForKey", + @"Should decode implicitPurchaseLoggingEnabled as a BOOL" + ); + XCTAssertEqualObjects( + decoder.decodedObject[@"codelessEventsEnabled"], + @"decodeBoolForKey", + @"Should decode codelessEventsEnabled as a BOOL" + ); + XCTAssertEqualObjects( + decoder.decodedObject[@"trackAppUninstallEnabled"], + @"decodeBoolForKey", + @"Should decode trackAppUninstallEnabled as a BOOL" + ); XCTAssertEqualObjects(decoder.decodedObject[@"dialogFlows"], dialogFlowsClasses); XCTAssertEqualObjects(decoder.decodedObject[@"timestamp"], NSDate.class); XCTAssertEqualObjects(decoder.decodedObject[@"errorConfigs"], FBSDKErrorConfiguration.class); - XCTAssertEqualObjects(decoder.decodedObject[@"sessionTimeoutInterval"], @"decodeDoubleForKey", - @"Should decode implicitLoggingEnabled as a double"); - XCTAssertNil(decoder.decodedObject[@"defaults"], - @"Should not encode whether default values were used to create server configuration"); + XCTAssertEqualObjects( + decoder.decodedObject[@"sessionTimeoutInterval"], + @"decodeDoubleForKey", + @"Should decode implicitLoggingEnabled as a double" + ); + XCTAssertNil( + decoder.decodedObject[@"defaults"], + @"Should not encode whether default values were used to create server configuration" + ); XCTAssertEqualObjects(decoder.decodedObject[@"loggingToken"], NSString.class); - XCTAssertEqualObjects(decoder.decodedObject[@"smartLoginEnabled"], @"decodeIntegerForKey", - @"Should decode smartLoginEnabled as an integer"); + XCTAssertEqualObjects( + decoder.decodedObject[@"smartLoginEnabled"], + @"decodeIntegerForKey", + @"Should decode smartLoginEnabled as an integer" + ); XCTAssertEqualObjects(decoder.decodedObject[@"smarstLoginBookmarkIconURL"], NSURL.class); XCTAssertEqualObjects(decoder.decodedObject[@"smarstLoginBookmarkMenuURL"], NSURL.class); XCTAssertEqualObjects(decoder.decodedObject[@"SDKUpdateMessage"], NSString.class); @@ -636,13 +799,16 @@ - (void)testDecoding - (void)testRetrievingInvalidDialogConfigurationForDialogName { config = [Fixtures configWithDictionary:@{ - @"dialogConfigurations": @{ - @"foo": @"bar" - } - }]; + @"dialogConfigurations" : @{ + @"foo" : @"bar" + } + }]; - XCTAssertEqualObjects([config dialogConfigurationForDialogName:@"foo"], @"bar", - @"Should be able to retrieve an invalid dialog configuration by name"); + XCTAssertEqualObjects( + [config dialogConfigurationForDialogName:@"foo"], + @"bar", + @"Should be able to retrieve an invalid dialog configuration by name" + ); } - (void)testRetrievingValidDialogConfigurationForDialogName @@ -652,13 +818,16 @@ - (void)testRetrievingValidDialogConfigurationForDialogName appVersions:nil]; config = [Fixtures configWithDictionary:@{ - @"dialogConfigurations": @{ - @"foo": fooConfig - } - }]; + @"dialogConfigurations" : @{ + @"foo" : fooConfig + } + }]; - XCTAssertEqualObjects([config dialogConfigurationForDialogName:@"foo"], fooConfig, - @"Should be able to retrieve a valid dialog configuration by name"); + XCTAssertEqualObjects( + [config dialogConfigurationForDialogName:@"foo"], + fooConfig, + @"Should be able to retrieve a valid dialog configuration by name" + ); } #pragma mark Native Dialog Checks @@ -1864,21 +2033,21 @@ - (void)setupConfigWithDialogFlowKey:(NSString *)flowKey NSMutableDictionary *dialogFlows = [NSMutableDictionary dictionary]; if (featureValue != nil) { dialogFlows[name] = @{ - flowKey: featureValue + flowKey : featureValue }; } if (sharingValue != nil) { dialogFlows[@"sharing"] = @{ - flowKey: sharingValue + flowKey : sharingValue }; } if (defaultValue != nil) { dialogFlows[@"default"] = @{ - flowKey: defaultValue + flowKey : defaultValue }; } - config = [Fixtures configWithDictionary:@{ @"dialogFlows": dialogFlows }]; + config = [Fixtures configWithDictionary:@{ @"dialogFlows" : dialogFlows }]; } - (void)assertSafariVcIs:(BOOL)expected @@ -1892,10 +2061,15 @@ - (void)assertSafariVcIs:(BOOL)expected withFeatureValue:featureValue sharingValue:sharingValue defaultValue:defaultValue]; - XCTAssertEqual([config useSafariViewControllerForDialogName:name], - expected, - "Use safari view controller for dialog name: %@, should return true when the feature value is: %@, the sharing value is: %@, and the default value is: %@", - name, featureValue, sharingValue, defaultValue); + XCTAssertEqual( + [config useSafariViewControllerForDialogName:name], + expected, + "Use safari view controller for dialog name: %@, should return true when the feature value is: %@, the sharing value is: %@, and the default value is: %@", + name, + featureValue, + sharingValue, + defaultValue + ); } - (void)assertNativeDialogIs:(BOOL)expected @@ -1910,11 +2084,15 @@ - (void)assertNativeDialogIs:(BOOL)expected sharingValue:sharingValue defaultValue:defaultValue]; - XCTAssertEqual([config useNativeDialogForDialogName:name], - expected, - "Use native dialog for dialog name: %@, should return true when the feature value is: %@, the sharing value is: %@, and the default value is: %@", - name, featureValue, sharingValue, defaultValue); - + XCTAssertEqual( + [config useNativeDialogForDialogName:name], + expected, + "Use native dialog for dialog name: %@, should return true when the feature value is: %@, the sharing value is: %@, and the default value is: %@", + name, + featureValue, + sharingValue, + defaultValue + ); } @end diff --git a/FBSDKGamingServicesKit.podspec b/FBSDKGamingServicesKit.podspec index 231fe54893..72f708ee53 100644 --- a/FBSDKGamingServicesKit.podspec +++ b/FBSDKGamingServicesKit.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| s.author = 'Facebook' s.platform = :ios - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '9.0' s.swift_version = '5.0' diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj index 577196a7d0..51a0ff96c7 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj @@ -39,6 +39,17 @@ 9FC20034247D8D170016A053 /* FBSDKShareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FC2001D247D83400016A053 /* FBSDKShareKit.framework */; }; F4234613244A2D2D006C9836 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5123F49C110030A346 /* FBSDKCoreKit.framework */; }; F4234614244A2D2D006C9836 /* FBSDKCoreKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5123F49C110030A346 /* FBSDKCoreKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F46A224524D9F14D005878A8 /* FBSDKGamingServicesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA1823F4902B0030A346 /* FBSDKGamingServicesKit.framework */; }; + F46A225024D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F46A224B24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m */; }; + F4DC057F2519499A0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */; }; + F4DC05832519499B0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */; }; + F4DE318124D9F4A700297C18 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4DE318024D9F4A700297C18 /* XCTest.framework */; }; + F4DE31A324D9FA5A00297C18 /* FBSDKFriendFinderDialogTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F46A224D24D9F184005878A8 /* FBSDKFriendFinderDialogTests.m */; }; + F4DE31A424D9FA6400297C18 /* FBSDKGamingImageUploaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F46A224E24D9F184005878A8 /* FBSDKGamingImageUploaderTests.m */; }; + F4DE31A524D9FA6F00297C18 /* FBSDKGamingVideoUploaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F46A224F24D9F184005878A8 /* FBSDKGamingVideoUploaderTests.m */; }; + F4DE31AD24D9FD6100297C18 /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DE31AC24D9FD6000297C18 /* FBSDKVideoUploader.m */; }; + F4DE31AE24D9FD6100297C18 /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DE31AC24D9FD6000297C18 /* FBSDKVideoUploader.m */; }; + F4DE31D024DA0DD400297C18 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4DE31CF24DA0DD400297C18 /* OCMock.framework */; }; F4F7C9E323F48F2C0030A346 /* FBSDKGamingImageUploaderConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F7C9B623F48F2C0030A346 /* FBSDKGamingImageUploaderConfiguration.m */; }; F4F7C9E423F48F2C0030A346 /* FBSDKGamingServiceCompletionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4F7C9B723F48F2C0030A346 /* FBSDKGamingServiceCompletionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4F7C9E523F48F2C0030A346 /* FBSDKFriendFinderDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F7C9B823F48F2C0030A346 /* FBSDKFriendFinderDialog.m */; }; @@ -115,6 +126,27 @@ remoteGlobalIDString = 81A07EDF1D1A2E6A0041A29C; remoteInfo = "FBSDKShareKit-Dynamic"; }; + F46A225424D9F1C7005878A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F4F7C9A123F48ED80030A346 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F4F7CA6A23F49D6F0030A346; + remoteInfo = "FBSDKGamingServicesKit-Dynamic"; + }; + F4DE319F24D9F9FC00297C18 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9FC20012247D83400016A053 /* FBSDKShareKit.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 81A07EDF1D1A2E6A0041A29C; + remoteInfo = "FBSDKShareKit-Dynamic"; + }; + F4DE31A124D9FA0100297C18 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F4F7CA3D23F49C110030A346 /* FBSDKCoreKit.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 81B71CFC1D19C87400933E93; + remoteInfo = "FBSDKCoreKit-Dynamic"; + }; F4F7CA2823F497410030A346 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = F4F7C9A123F48ED80030A346 /* Project object */; @@ -224,7 +256,18 @@ 9FC2000D247D82A00016A053 /* FBSDKGamingVideoUploaderConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKGamingVideoUploaderConfiguration.h; sourceTree = ""; }; 9FC20012247D83400016A053 /* FBSDKShareKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FBSDKShareKit.xcodeproj; path = ../FBSDKShareKit/FBSDKShareKit.xcodeproj; sourceTree = ""; }; 9FC2002C247D8ACF0016A053 /* FBSDKVideoUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKVideoUploader.h; path = ../../../FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h; sourceTree = ""; }; + F46A224024D9F14D005878A8 /* FBSDKGamingServicesKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FBSDKGamingServicesKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F46A224424D9F14D005878A8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F46A224B24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGamingServicesKitTestUtility.m; sourceTree = ""; }; + F46A224C24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKGamingServicesKitTestUtility.h; sourceTree = ""; }; + F46A224D24D9F184005878A8 /* FBSDKFriendFinderDialogTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKFriendFinderDialogTests.m; sourceTree = ""; }; + F46A224E24D9F184005878A8 /* FBSDKGamingImageUploaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGamingImageUploaderTests.m; sourceTree = ""; }; + F46A224F24D9F184005878A8 /* FBSDKGamingVideoUploaderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGamingVideoUploaderTests.m; sourceTree = ""; }; F4A54C8A244619630063015F /* FBSDKGamingServicesKit-Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKGamingServicesKit-Common.xcconfig"; sourceTree = ""; }; + F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitInternalImport.h; sourceTree = ""; }; + F4DE318024D9F4A700297C18 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + F4DE31AC24D9FD6000297C18 /* FBSDKVideoUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKVideoUploader.m; path = ../../../FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m; sourceTree = ""; }; + F4DE31CF24DA0DD400297C18 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = ../Carthage/Build/iOS/OCMock.framework; sourceTree = ""; }; F4F7C9B623F48F2C0030A346 /* FBSDKGamingImageUploaderConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGamingImageUploaderConfiguration.m; sourceTree = ""; }; F4F7C9B723F48F2C0030A346 /* FBSDKGamingServiceCompletionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKGamingServiceCompletionHandler.h; sourceTree = ""; }; F4F7C9B823F48F2C0030A346 /* FBSDKFriendFinderDialog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKFriendFinderDialog.m; sourceTree = ""; }; @@ -261,7 +304,6 @@ F4F7C9DE23F48F2C0030A346 /* FacebookSDK-Project-TVOS-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "FacebookSDK-Project-TVOS-Debug.xcconfig"; sourceTree = ""; }; F4F7C9DF23F48F2C0030A346 /* FBSDKGamingServicesKit.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FBSDKGamingServicesKit.xcconfig; sourceTree = ""; }; F4F7C9E023F48F2C0030A346 /* FBSDKGamingServicesKit-Dynamic.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "FBSDKGamingServicesKit-Dynamic.xcconfig"; sourceTree = ""; }; - F4F7C9E223F48F2C0030A346 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F4F7CA1823F4902B0030A346 /* FBSDKGamingServicesKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKGamingServicesKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F4F7CA3523F499600030A346 /* FBSDKCoreKit+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "FBSDKCoreKit+Internal.h"; path = "../../../FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h"; sourceTree = ""; }; F4F7CA3D23F49C110030A346 /* FBSDKCoreKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FBSDKCoreKit.xcodeproj; path = ../FBSDKCoreKit/FBSDKCoreKit.xcodeproj; sourceTree = ""; }; @@ -272,6 +314,16 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + F46A223D24D9F14D005878A8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F4DE318124D9F4A700297C18 /* XCTest.framework in Frameworks */, + F4DE31D024DA0DD400297C18 /* OCMock.framework in Frameworks */, + F46A224524D9F14D005878A8 /* FBSDKGamingServicesKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F4F7C9A723F48ED80030A346 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -305,16 +357,30 @@ name = Products; sourceTree = ""; }; + F46A224124D9F14D005878A8 /* FBSDKGamingServicesKitTests */ = { + isa = PBXGroup; + children = ( + F46A224D24D9F184005878A8 /* FBSDKFriendFinderDialogTests.m */, + F46A224E24D9F184005878A8 /* FBSDKGamingImageUploaderTests.m */, + F46A224C24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.h */, + F46A224B24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m */, + F46A224F24D9F184005878A8 /* FBSDKGamingVideoUploaderTests.m */, + F46A224424D9F14D005878A8 /* Info.plist */, + ); + path = FBSDKGamingServicesKitTests; + sourceTree = ""; + }; F4F7C9A023F48ED80030A346 = { isa = PBXGroup; children = ( F4F7C9C323F48F2C0030A346 /* Configurations */, F4F7C9B523F48F2C0030A346 /* FBSDKGamingServicesKit */, - F4F7C9E123F48F2C0030A346 /* FBSDKGamingServicesKitTests */, F4F7CA1823F4902B0030A346 /* FBSDKGamingServicesKit.framework */, + F46A224124D9F14D005878A8 /* FBSDKGamingServicesKitTests */, F4F7CA3223F498ED0030A346 /* Frameworks */, F4F7CA9923F49D6F0030A346 /* FBSDKGamingServicesKit.framework */, F4F7CA9A23F49D6F0030A346 /* FBSDKGamingServicesKit copy-Info.plist */, + F46A224024D9F14D005878A8 /* FBSDKGamingServicesKitTests.xctest */, ); sourceTree = ""; }; @@ -345,8 +411,10 @@ F4F7C9B923F48F2C0030A346 /* Internal */ = { isa = PBXGroup; children = ( + F4DE31AC24D9FD6000297C18 /* FBSDKVideoUploader.m */, 9FC2002C247D8ACF0016A053 /* FBSDKVideoUploader.h */, F4F7CA3523F499600030A346 /* FBSDKCoreKit+Internal.h */, + F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */, F4F7C9BA23F48F2C0030A346 /* FBSDKGamingServiceController.m */, F4F7C9BB23F48F2C0030A346 /* FBSDKGamingServiceController.h */, ); @@ -417,21 +485,15 @@ path = Platform; sourceTree = ""; }; - F4F7C9E123F48F2C0030A346 /* FBSDKGamingServicesKitTests */ = { - isa = PBXGroup; - children = ( - F4F7C9E223F48F2C0030A346 /* Info.plist */, - ); - path = FBSDKGamingServicesKitTests; - sourceTree = ""; - }; F4F7CA3223F498ED0030A346 /* Frameworks */ = { isa = PBXGroup; children = ( - 9FC20012247D83400016A053 /* FBSDKShareKit.xcodeproj */, - F4F7CAA123F4A1390030A346 /* UIKit.framework */, + F4DE31CF24DA0DD400297C18 /* OCMock.framework */, F4F7CA6823F49D1B0030A346 /* Accelerate.framework */, F4F7CA3D23F49C110030A346 /* FBSDKCoreKit.xcodeproj */, + 9FC20012247D83400016A053 /* FBSDKShareKit.xcodeproj */, + F4F7CAA123F4A1390030A346 /* UIKit.framework */, + F4DE318024D9F4A700297C18 /* XCTest.framework */, ); name = Frameworks; sourceTree = ""; @@ -468,6 +530,7 @@ F4F7C9EA23F48F2C0030A346 /* FBSDKFriendFinderDialog.h in Headers */, F4F7C9E423F48F2C0030A346 /* FBSDKGamingServiceCompletionHandler.h in Headers */, F4F7C9E823F48F2C0030A346 /* FBSDKGamingImageUploader.h in Headers */, + F4DC057F2519499A0073B380 /* FBSDKCoreKitInternalImport.h in Headers */, F4F7C9EB23F48F2C0030A346 /* FBSDKGamingServicesKit.h in Headers */, F4F7CA3623F499600030A346 /* FBSDKCoreKit+Internal.h in Headers */, ); @@ -486,6 +549,7 @@ F4F7CA7123F49D6F0030A346 /* FBSDKGamingServiceCompletionHandler.h in Headers */, F4F7CA7223F49D6F0030A346 /* FBSDKGamingImageUploader.h in Headers */, F4F7CA7323F49D6F0030A346 /* FBSDKGamingServicesKit.h in Headers */, + F4DC05832519499B0073B380 /* FBSDKCoreKitInternalImport.h in Headers */, F4F7CA7423F49D6F0030A346 /* FBSDKCoreKit+Internal.h in Headers */, 9FC2002E247D8ACF0016A053 /* FBSDKVideoUploader.h in Headers */, ); @@ -494,6 +558,26 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + F46A223F24D9F14D005878A8 /* FBSDKGamingServicesKitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F46A224824D9F14D005878A8 /* Build configuration list for PBXNativeTarget "FBSDKGamingServicesKitTests" */; + buildPhases = ( + F46A223C24D9F14D005878A8 /* Sources */, + F46A223D24D9F14D005878A8 /* Frameworks */, + F46A223E24D9F14D005878A8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F4DE31A224D9FA0100297C18 /* PBXTargetDependency */, + F4DE31A024D9F9FC00297C18 /* PBXTargetDependency */, + F46A225524D9F1C7005878A8 /* PBXTargetDependency */, + ); + name = FBSDKGamingServicesKitTests; + productName = FBSDKGamingServicesKitTests; + productReference = F46A224024D9F14D005878A8 /* FBSDKGamingServicesKitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; F4F7C9A923F48ED80030A346 /* FBSDKGamingServicesKit */ = { isa = PBXNativeTarget; buildConfigurationList = F4F7C9B223F48ED80030A346 /* Build configuration list for PBXNativeTarget "FBSDKGamingServicesKit" */; @@ -542,9 +626,13 @@ F4F7C9A123F48ED80030A346 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 1160; LastUpgradeCheck = 1140; ORGANIZATIONNAME = facebook; TargetAttributes = { + F46A223F24D9F14D005878A8 = { + CreatedOnToolsVersion = 11.6; + }; F4F7C9A923F48ED80030A346 = { CreatedOnToolsVersion = 10.1; }; @@ -579,6 +667,7 @@ F4F7C9A923F48ED80030A346 /* FBSDKGamingServicesKit */, F4F7CA6A23F49D6F0030A346 /* FBSDKGamingServicesKit-Dynamic */, F4F7CA2323F497200030A346 /* FBSDKGamingServicesKit-Universal */, + F46A223F24D9F14D005878A8 /* FBSDKGamingServicesKitTests */, ); }; /* End PBXProject section */ @@ -685,6 +774,13 @@ /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ + F46A223E24D9F14D005878A8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; F4F7C9A823F48ED80030A346 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -741,6 +837,17 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + F46A223C24D9F14D005878A8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F4DE31A324D9FA5A00297C18 /* FBSDKFriendFinderDialogTests.m in Sources */, + F4DE31A524D9FA6F00297C18 /* FBSDKGamingVideoUploaderTests.m in Sources */, + F46A225024D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m in Sources */, + F4DE31A424D9FA6400297C18 /* FBSDKGamingImageUploaderTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; F4F7C9A623F48ED80030A346 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -749,6 +856,7 @@ F4F7C9ED23F48F2C0030A346 /* FBSDKGamingImageUploader.m in Sources */, 9FC2000E247D82A00016A053 /* FBSDKGamingVideoUploaderConfiguration.m in Sources */, F4F7C9E323F48F2C0030A346 /* FBSDKGamingImageUploaderConfiguration.m in Sources */, + F4DE31AD24D9FD6100297C18 /* FBSDKVideoUploader.m in Sources */, 9FB51BA024B8BD4700059B77 /* FBSDKGamingGroupIntegration.m in Sources */, F4F7C9E623F48F2C0030A346 /* FBSDKGamingServiceController.m in Sources */, 9FC2000F247D82A00016A053 /* FBSDKGamingVideoUploader.m in Sources */, @@ -763,6 +871,7 @@ 9FC2002B247D83FF0016A053 /* FBSDKGamingVideoUploaderConfiguration.m in Sources */, F4F7CA7623F49D6F0030A346 /* FBSDKFriendFinderDialog.m in Sources */, F4F7CA7723F49D6F0030A346 /* FBSDKGamingImageUploader.m in Sources */, + F4DE31AE24D9FD6100297C18 /* FBSDKVideoUploader.m in Sources */, 9FB51BA324B8BD6100059B77 /* FBSDKGamingGroupIntegration.m in Sources */, F4F7CA7823F49D6F0030A346 /* FBSDKGamingImageUploaderConfiguration.m in Sources */, F4F7CA7923F49D6F0030A346 /* FBSDKGamingServiceController.m in Sources */, @@ -782,6 +891,21 @@ name = "FBSDKShareKit-Dynamic"; targetProxy = 9FC20028247D834D0016A053 /* PBXContainerItemProxy */; }; + F46A225524D9F1C7005878A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F4F7CA6A23F49D6F0030A346 /* FBSDKGamingServicesKit-Dynamic */; + targetProxy = F46A225424D9F1C7005878A8 /* PBXContainerItemProxy */; + }; + F4DE31A024D9F9FC00297C18 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FBSDKShareKit-Dynamic"; + targetProxy = F4DE319F24D9F9FC00297C18 /* PBXContainerItemProxy */; + }; + F4DE31A224D9FA0100297C18 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FBSDKCoreKit-Dynamic"; + targetProxy = F4DE31A124D9FA0100297C18 /* PBXContainerItemProxy */; + }; F4F7CA2923F497410030A346 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = F4F7C9A923F48ED80030A346 /* FBSDKGamingServicesKit */; @@ -800,6 +924,136 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + F46A224924D9F14D005878A8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = FBSDKGamingServicesKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = com.facebook.FBSDKGamingServicesKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F46A224A24D9F14D005878A8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INFOPLIST_FILE = FBSDKGamingServicesKitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_BUNDLE_IDENTIFIER = com.facebook.FBSDKGamingServicesKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; F4F7C9B023F48ED80030A346 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = F4F7C9C623F48F2C0030A346 /* Debug.xcconfig */; @@ -913,6 +1167,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + F46A224824D9F14D005878A8 /* Build configuration list for PBXNativeTarget "FBSDKGamingServicesKitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F46A224924D9F14D005878A8 /* Debug */, + F46A224A24D9F14D005878A8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; F4F7C9A423F48ED80030A346 /* Build configuration list for PBXProject "FBSDKGamingServicesKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/xcshareddata/xcschemes/FBSDKGamingServicesKit-Dynamic.xcscheme b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/xcshareddata/xcschemes/FBSDKGamingServicesKit-Dynamic.xcscheme index 5910dc9ad1..4e36fb9a2e 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/xcshareddata/xcschemes/FBSDKGamingServicesKit-Dynamic.xcscheme +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/xcshareddata/xcschemes/FBSDKGamingServicesKit-Dynamic.xcscheme @@ -26,8 +26,19 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKFriendFinderDialog.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKFriendFinderDialog.m index 80b76ca934..f603b65eac 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKFriendFinderDialog.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKFriendFinderDialog.m @@ -18,7 +18,7 @@ #import "FBSDKFriendFinderDialog.h" -#import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitInternalImport.h" #import "FBSDKGamingServiceController.h" @interface FBSDKFriendFinderDialog () @@ -34,10 +34,12 @@ - (instancetype)init + (void)launchFriendFinderDialogWithCompletionHandler:(FBSDKGamingServiceCompletionHandler _Nonnull)completionHandler { if ([FBSDKAccessToken currentAccessToken] == nil) { - completionHandler(false, - [FBSDKError - errorWithCode:FBSDKErrorAccessTokenRequired - message:@"A valid access token is required to launch the Friend Finder"]); + completionHandler( + false, + [FBSDKError + errorWithCode:FBSDKErrorAccessTokenRequired + message:@"A valid access token is required to launch the Friend Finder"] + ); return; } @@ -45,11 +47,11 @@ + (void)launchFriendFinderDialogWithCompletionHandler:(FBSDKGamingServiceComplet FBSDKGamingServiceController *const controller = [[FBSDKGamingServiceController alloc] initWithServiceType:FBSDKGamingServiceTypeFriendFinder - completionHandler:^(BOOL success, id _Nullable result, NSError * _Nullable error) { - if (completionHandler) { - completionHandler(success, error); - } - } + completionHandler:^(BOOL success, id _Nullable result, NSError *_Nullable error) { + if (completionHandler) { + completionHandler(success, error); + } + } pendingResult:nil]; [controller callWithArgument:FBSDKAccessToken.currentAccessToken.appID]; diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingGroupIntegration.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingGroupIntegration.m index 056051281b..4aa21c22ec 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingGroupIntegration.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingGroupIntegration.m @@ -18,7 +18,7 @@ #import "FBSDKGamingGroupIntegration.h" -#import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitInternalImport.h" #import "FBSDKGamingServiceController.h" @implementation FBSDKGamingGroupIntegration @@ -28,11 +28,11 @@ + (void)openGroupPageWithCompletionHandler:(FBSDKGamingServiceCompletionHandler FBSDKGamingServiceController *const controller = [[FBSDKGamingServiceController alloc] initWithServiceType:FBSDKGamingServiceTypeCommunity - completionHandler:^(BOOL success, id _Nullable result, NSError * _Nullable error) { - if (completionHandler) { - completionHandler(success, error); - } - } + completionHandler:^(BOOL success, id _Nullable result, NSError *_Nullable error) { + if (completionHandler) { + completionHandler(success, error); + } + } pendingResult:nil]; [controller callWithArgument:FBSDKSettings.appID]; diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploader.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploader.m index 0905fab6bb..f7e20d9a9f 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploader.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploader.m @@ -18,7 +18,7 @@ #import "FBSDKGamingImageUploader.h" -#import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitInternalImport.h" #import "FBSDKGamingImageUploaderConfiguration.h" #import "FBSDKGamingServiceController.h" @@ -36,21 +36,21 @@ - (instancetype)init return [super init]; } -+ (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration * _Nonnull)configuration ++ (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration *_Nonnull)configuration andCompletionHandler:(FBSDKGamingServiceCompletionHandler _Nonnull)completionHandler { return [self uploadImageWithConfiguration:configuration - completionHandler:^(BOOL success, id _Nullable result, NSError * _Nullable error) { - if (completionHandler) { - completionHandler(success, error); - } - } + completionHandler:^(BOOL success, id _Nullable result, NSError *_Nullable error) { + if (completionHandler) { + completionHandler(success, error); + } + } andProgressHandler:nil]; } -+ (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration * _Nonnull)configuration ++ (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration *_Nonnull)configuration andResultCompletionHandler:(FBSDKGamingServiceResultCompletionHandler _Nonnull)completionHandler { return @@ -60,26 +60,30 @@ + (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration * _N andProgressHandler:nil]; } -+ (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration * _Nonnull)configuration ++ (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration *_Nonnull)configuration completionHandler:(FBSDKGamingServiceResultCompletionHandler _Nonnull)completionHandler andProgressHandler:(FBSDKGamingServiceProgressHandler _Nullable)progressHandler { if ([FBSDKAccessToken currentAccessToken] == nil) { - completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorAccessTokenRequired - message:@"A valid access token is required to upload Images"]); + completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorAccessTokenRequired + message:@"A valid access token is required to upload Images"] + ); return; } if (configuration.image == nil) { - completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorInvalidArgument - message:@"Attempting to upload a nil image"]); + completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorInvalidArgument + message:@"Attempting to upload a nil image"] + ); return; } @@ -99,36 +103,38 @@ + (void)uploadImageWithConfiguration:(FBSDKGamingImageUploaderConfiguration * _N [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/photos" parameters:@{ - @"caption": configuration.caption ?: @"", - @"picture": UIImagePNGRepresentation(configuration.image) + @"caption" : configuration.caption ?: @"", + @"picture" : UIImagePNGRepresentation(configuration.image) } HTTPMethod:FBSDKHTTPMethodPOST] - completionHandler:^(FBSDKGraphRequestConnection * _Nullable graphConnection, id _Nullable result, NSError * _Nullable error) { - [FBSDKInternalUtility unregisterTransientObject:graphConnection.delegate]; - - if (error || !result) { - completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorGraphRequestGraphAPI - message:@"Image upload failed" - underlyingError:error]); - return; - } - - if (!configuration.shouldLaunchMediaDialog) { - completionHandler(true, result, nil); - return; - } - - FBSDKGamingServiceController *const controller = - [[FBSDKGamingServiceController alloc] - initWithServiceType:FBSDKGamingServiceTypeMediaAsset - completionHandler:completionHandler - pendingResult:result]; - - [controller callWithArgument:result[@"id"]]; - }]; + completionHandler:^(FBSDKGraphRequestConnection *_Nullable graphConnection, id _Nullable result, NSError *_Nullable error) { + [FBSDKInternalUtility unregisterTransientObject:graphConnection.delegate]; + + if (error || !result) { + completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorGraphRequestGraphAPI + message:@"Image upload failed" + underlyingError:error] + ); + return; + } + + if (!configuration.shouldLaunchMediaDialog) { + completionHandler(true, result, nil); + return; + } + + FBSDKGamingServiceController *const controller = + [[FBSDKGamingServiceController alloc] + initWithServiceType:FBSDKGamingServiceTypeMediaAsset + completionHandler:completionHandler + pendingResult:result]; + + [controller callWithArgument:result[@"id"]]; + }]; [connection start]; } @@ -143,10 +149,10 @@ - (instancetype)initWithProgressHandler:(FBSDKGamingServiceProgressHandler _Null #pragma mark - FBSDKGraphRequestConnectionDelegate -- (void)requestConnection:(FBSDKGraphRequestConnection *)connection - didSendBodyData:(NSInteger)bytesWritten - totalBytesWritten:(NSInteger)totalBytesWritten -totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite +- (void) requestConnection:(FBSDKGraphRequestConnection *)connection + didSendBodyData:(NSInteger)bytesWritten + totalBytesWritten:(NSInteger)totalBytesWritten + totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { if (!_progressHandler) { return; diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploaderConfiguration.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploaderConfiguration.m index 0921c39165..296fc34358 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploaderConfiguration.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingImageUploaderConfiguration.m @@ -25,8 +25,8 @@ - (instancetype)init return [super init]; } -- (instancetype)initWithImage:(UIImage * _Nonnull)image - caption:(NSString * _Nullable)caption +- (instancetype)initWithImage:(UIImage *_Nonnull)image + caption:(NSString *_Nullable)caption shouldLaunchMediaDialog:(BOOL)shouldLaunchMediaDialog { if (self = [super init]) { diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingServicesKit.h b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingServicesKit.h index 8c8d347e9f..3a20b286da 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingServicesKit.h +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingServicesKit.h @@ -18,23 +18,22 @@ #if defined FBSDKCOCOAPODS || defined BUCK -#import -#import -#import -#import -#import -#import -#import + #import + #import + #import + #import + #import + #import + #import #else -#import "FBSDKFriendFinderDialog.h" -#import "FBSDKGamingImageUploader.h" -#import "FBSDKGamingImageUploaderConfiguration.h" -#import "FBSDKGamingServiceCompletionHandler.h" -#import "FBSDKGamingVideoUploader.h" -#import "FBSDKGamingVideoUploaderConfiguration.h" -#import "FBSDKGamingGroupIntegration.h" + #import "FBSDKFriendFinderDialog.h" + #import "FBSDKGamingGroupIntegration.h" + #import "FBSDKGamingImageUploader.h" + #import "FBSDKGamingImageUploaderConfiguration.h" + #import "FBSDKGamingServiceCompletionHandler.h" + #import "FBSDKGamingVideoUploader.h" + #import "FBSDKGamingVideoUploaderConfiguration.h" #endif - diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m index 66f40268d5..aec7ec6f54 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m @@ -18,11 +18,17 @@ #import "FBSDKGamingVideoUploader.h" -#import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitInternalImport.h" + +#if defined FBSDKCOCOAPODS + #import +#else + #import "FBSDKVideoUploader.h" +#endif + #import "FBSDKGamingVideoUploaderConfiguration.h" -#import "FBSDKVideoUploader.h" -@interface FBSDKGamingVideoUploader() +@interface FBSDKGamingVideoUploader () { NSFileHandle *_fileHandle; FBSDKGamingServiceResultCompletionHandler _completionHandler; @@ -39,21 +45,21 @@ - (instancetype)init return [super init]; } -+ (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration * _Nonnull)configuration ++ (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration *_Nonnull)configuration andCompletionHandler:(FBSDKGamingServiceCompletionHandler _Nonnull)completionHandler { return [self uploadVideoWithConfiguration:configuration - completionHandler:^(BOOL success, id _Nullable result, NSError * _Nullable error) { - if (completionHandler) { - completionHandler(success, error); - } - } + completionHandler:^(BOOL success, id _Nullable result, NSError *_Nullable error) { + if (completionHandler) { + completionHandler(success, error); + } + } andProgressHandler:nil]; } -+ (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration * _Nonnull)configuration ++ (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration *_Nonnull)configuration andResultCompletionHandler:(FBSDKGamingServiceResultCompletionHandler _Nonnull)completionHandler { return @@ -63,26 +69,30 @@ + (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration * _N andProgressHandler:nil]; } -+ (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration * _Nonnull)configuration ++ (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration *_Nonnull)configuration completionHandler:(FBSDKGamingServiceResultCompletionHandler _Nonnull)completionHandler andProgressHandler:(FBSDKGamingServiceProgressHandler _Nullable)progressHandler { if ([FBSDKAccessToken currentAccessToken] == nil) { - completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorAccessTokenRequired - message:@"A valid access token is required to upload Images"]); + completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorAccessTokenRequired + message:@"A valid access token is required to upload Images"] + ); return; } if (configuration.videoURL == nil) { - completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorInvalidArgument - message:@"Attempting to upload a nil videoURL"]); + completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorInvalidArgument + message:@"Attempting to upload a nil videoURL"] + ); return; } @@ -93,16 +103,17 @@ + (void)uploadVideoWithConfiguration:(FBSDKGamingVideoUploaderConfiguration * _N error:nil]; if ((unsigned long)[fileHandle seekToEndOfFile] == 0) { - completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorInvalidArgument - message:@"Attempting to upload an empty video file"]); + completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorInvalidArgument + message:@"Attempting to upload an empty video file"] + ); return; } - const NSUInteger fileSize = (unsigned long)[fileHandle seekToEndOfFile]; FBSDKGamingVideoUploader *const uploader = @@ -141,11 +152,10 @@ - (instancetype)initWithFileHandle:(NSFileHandle *)fileHandle - (void)safeCompleteWithSuccess:(BOOL)success error:(NSError *)error result:(id)result - { NSError *finalError = error; - if (success == false && error == nil) { + if (success == false && error == nil) { finalError = [FBSDKError errorWithCode:FBSDKErrorUnknown @@ -189,15 +199,15 @@ - (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader return videoChunkData; } -- (void)videoUploader:(FBSDKVideoUploader *)videoUploader -didCompleteWithResults:(NSDictionary *)results +- (void) videoUploader:(FBSDKVideoUploader *)videoUploader + didCompleteWithResults:(NSDictionary *)results { [self safeProgressWithTotalBytesSent:_totalBytesExpectedToSend]; [self safeCompleteWithSuccess:[results[@"success"] boolValue] error:nil - result:@{@"video_id": results[@"video_id"] ?: @""}]; + result:@{@"video_id" : results[@"video_id"] ?: @""}]; } - (void)videoUploader:(FBSDKVideoUploader *)videoUploader diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploaderConfiguration.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploaderConfiguration.m index f0544d1502..4b5f9cdb29 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploaderConfiguration.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploaderConfiguration.m @@ -25,8 +25,8 @@ - (instancetype)init return [super init]; } -- (instancetype)initWithVideoURL:(NSURL * _Nonnull)videoURL - caption:(NSString * _Nullable)caption; +- (instancetype)initWithVideoURL:(NSURL *_Nonnull)videoURL + caption:(NSString *_Nullable)caption; { if (self = [super init]) { _videoURL = videoURL; diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKCoreKitInternalImport.h b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKCoreKitInternalImport.h new file mode 100644 index 0000000000..2e3713615b --- /dev/null +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKCoreKitInternalImport.h @@ -0,0 +1,26 @@ +// 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. + +// Importing FBSDKCoreKit+Internal is tricky due to build variants. +// SPM, xcodebuild, and BUCK require that it is imported as "FBSDKCoreKit+Internal.h" +// CocoaPods requires that is is imported as +#if defined FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.h b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.h index 1dd60fb497..7c9e436dc1 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.h +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.h @@ -18,9 +18,10 @@ #import -#import "FBSDKCoreKit+Internal.h" #import +#import "FBSDKCoreKitInternalImport.h" + typedef NS_ENUM(NSUInteger, FBSDKGamingServiceType) { FBSDKGamingServiceTypeFriendFinder, FBSDKGamingServiceTypeMediaAsset, diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.m index 3d02ff71a6..951779a023 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKGamingServiceController.m @@ -18,13 +18,12 @@ #import "FBSDKGamingServiceController.h" -#import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitInternalImport.h" static NSString *const kServiceTypeStringFriendFinder = @"friendfinder"; static NSString *const kServiceTypeStringMediaAsset = @"media_asset"; static NSString *const kServiceTypeStringCommunity = @"community"; - static NSString *FBSDKGamingServiceTypeString(FBSDKGamingServiceType type) { switch (type) { @@ -39,7 +38,7 @@ } } -static NSURL* FBSDKGamingServicesUrl(FBSDKGamingServiceType serviceType, NSString *argument) +static NSURL *FBSDKGamingServicesUrl(FBSDKGamingServiceType serviceType, NSString *argument) { return [NSURL URLWithString: @@ -50,7 +49,6 @@ argument]]; } - @implementation FBSDKGamingServiceController { FBSDKGamingServiceType _serviceType; @@ -76,11 +74,11 @@ - (void)callWithArgument:(NSString *)argument [[FBSDKBridgeAPI sharedInstance] openURL:FBSDKGamingServicesUrl(_serviceType, argument) sender:weakSelf - handler:^(BOOL success, NSError * _Nullable error) { - if (!success) { - [weakSelf handleBridgeAPIError:error]; - } - }]; + handler:^(BOOL success, NSError *_Nullable error) { + if (!success) { + [weakSelf handleBridgeAPIError:error]; + } + }]; } - (void)handleBridgeAPIError:(NSError *)error @@ -90,18 +88,22 @@ - (void)handleBridgeAPIError:(NSError *)error } if (error) { - _completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorBridgeAPIInterruption - message:@"Error occured while interacting with Gaming Services" - underlyingError:error]); + _completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorBridgeAPIInterruption + message:@"Error occured while interacting with Gaming Services" + underlyingError:error] + ); } else { - _completionHandler(false, - nil, - [FBSDKError - errorWithCode:FBSDKErrorBridgeAPIInterruption - message:@"An Unknown error occured while interacting with Gaming Services"]); + _completionHandler( + false, + nil, + [FBSDKError + errorWithCode:FBSDKErrorBridgeAPIInterruption + message:@"An Unknown error occured while interacting with Gaming Services"] + ); } _completionHandler = nil; @@ -133,10 +135,10 @@ - (BOOL)application:(UIApplication *)application return isGamingUrl; } -- (BOOL)canOpenURL:(NSURL *)url - forApplication:(UIApplication *)application - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation +- (BOOL) canOpenURL:(NSURL *)url + forApplication:(UIApplication *)application + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { return [self @@ -156,15 +158,14 @@ - (BOOL)isAuthenticationURL:(NSURL *)url return false; } - #pragma mark - Helpers - (BOOL)isValidCallbackURL:(NSURL *)url forService:(NSString *)service { // verify the URL is intended as a callback for the SDK's friend finder return - [url.scheme hasPrefix:[NSString stringWithFormat:@"fb%@", [FBSDKSettings appID]]] && - [url.host isEqualToString:service]; + [url.scheme hasPrefix:[NSString stringWithFormat:@"fb%@", [FBSDKSettings appID]]] + && [url.host isEqualToString:service]; } @end diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKFriendFinderDialogTests.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKFriendFinderDialogTests.m index 50da53799a..5efc5a1e1e 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKFriendFinderDialogTests.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKFriendFinderDialogTests.m @@ -16,9 +16,8 @@ // 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 @@ -51,10 +50,10 @@ - (void)testFailureWhenNoValidAccessTokenPresent __block BOOL actioned = false; [FBSDKFriendFinderDialog - launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorAccessTokenRequired, "Expected error requiring a valid access token"); - actioned = true; - }]; + launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorAccessTokenRequired, "Expected error requiring a valid access token"); + actioned = true; + }]; XCTAssertTrue(actioned); } @@ -62,21 +61,23 @@ - (void)testFailureWhenNoValidAccessTokenPresent - (void)testServiceIsCalledCorrectly { OCMStub([_mockToken appID]).andReturn(@"123"); - OCMStub([_mockApp - openURL:[OCMArg any] - options:[OCMArg any] - completionHandler:([OCMArg invokeBlockWithArgs:@(false), nil])]); + OCMStub( + [_mockApp + openURL:[OCMArg any] + options:[OCMArg any] + completionHandler:([OCMArg invokeBlockWithArgs:@(false), nil])] + ); id expectation = [self expectationWithDescription:@"callback"]; [FBSDKFriendFinderDialog - launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - [expectation fulfill]; - }]; + launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError *_Nullable error) { + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:1 handler:nil]; - id urlCheck = [OCMArg checkWithBlock:^BOOL(id obj) { + id urlCheck = [OCMArg checkWithBlock:^BOOL (id obj) { return [[(NSURL *)obj absoluteString] isEqualToString:@"https://fb.gg/me/friendfinder/123"]; }]; OCMVerify([_mockApp openURL:urlCheck options:[OCMArg any] completionHandler:[OCMArg any]]); @@ -84,18 +85,20 @@ - (void)testServiceIsCalledCorrectly - (void)testFailuresReturnAnError { - OCMStub([_mockApp - openURL:[OCMArg any] - options:[OCMArg any] - completionHandler:([OCMArg invokeBlockWithArgs:@(false), nil])]); + OCMStub( + [_mockApp + openURL:[OCMArg any] + options:[OCMArg any] + completionHandler:([OCMArg invokeBlockWithArgs:@(false), nil])] + ); id expectation = [self expectationWithDescription:@"callback"]; [FBSDKFriendFinderDialog - launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - XCTAssertFalse(success); - XCTAssert(error.code == FBSDKErrorBridgeAPIInterruption); - [expectation fulfill]; - }]; + launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError *_Nullable error) { + XCTAssertFalse(success); + XCTAssert(error.code == FBSDKErrorBridgeAPIInterruption); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:1 handler:nil]; } @@ -112,10 +115,10 @@ - (void)testHandlingOfCallbackURL __block BOOL actioned = false; [FBSDKFriendFinderDialog - launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - XCTAssertTrue(success); - actioned = true; - }]; + launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError *_Nullable error) { + XCTAssertTrue(success); + actioned = true; + }]; [delegate application:_mockApp openURL:[NSURL URLWithString:@"fb123://friendfinder"] sourceApplication:@"foo" annotation:nil]; @@ -131,10 +134,10 @@ - (void)testHandlingOfUserManuallyReturningToOriginalApp __block BOOL actioned = false; [FBSDKFriendFinderDialog - launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError * _Nullable error) { - XCTAssertTrue(success); - actioned = true; - }]; + launchFriendFinderDialogWithCompletionHandler:^(BOOL success, NSError *_Nullable error) { + XCTAssertTrue(success); + actioned = true; + }]; [delegate applicationDidBecomeActive:_mockApp]; diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingImageUploaderTests.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingImageUploaderTests.m index c8f73731ab..b4fd50dfe3 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingImageUploaderTests.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingImageUploaderTests.m @@ -16,9 +16,8 @@ // 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 @@ -72,10 +71,10 @@ - (void)testFailureWhenNoValidAccessTokenPresent __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorAccessTokenRequired, "Expected error requiring a valid access token"); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorAccessTokenRequired, "Expected error requiring a valid access token"); + actioned = true; + }]; XCTAssertTrue(actioned); } @@ -87,10 +86,10 @@ - (void)testNilImageFails __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:nilImageConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorInvalidArgument, "Expected error requiring a non nil image"); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorInvalidArgument, "Expected error requiring a non nil image"); + actioned = true; + }]; XCTAssertTrue(actioned); } @@ -102,54 +101,56 @@ - (void)testGraphErrorsAreHandled __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorGraphRequestGraphAPI, "Expected error from Graph API"); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorGraphRequestGraphAPI, "Expected error from Graph API"); + actioned = true; + }]; XCTAssertTrue(actioned); } - (void)testGraphResponsesTriggerCompletionIfDialogNotRequested { - [self stubGraphRequestWithResult:@{@"id": @"123"} error:nil]; + [self stubGraphRequestWithResult:@{@"id" : @"123"} error:nil]; __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssertTrue(success); - XCTAssertNil(error); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssertTrue(success); + XCTAssertNil(error); + actioned = true; + }]; XCTAssertTrue(actioned); } - (void)testGraphResponsesDoNotTriggerCompletionIfDialogIsRequested { - [self stubGraphRequestWithResult:@{@"id": @"123"} error:nil]; + [self stubGraphRequestWithResult:@{@"id" : @"123"} error:nil]; OCMStub([_mockConfig shouldLaunchMediaDialog]).andReturn(true); __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + actioned = true; + }]; XCTAssertFalse(actioned, "Callback should not have been called because there was more work to do"); } - (void)testGraphResponsesTriggerDialogIfDialogIsRequested { - [self stubGraphRequestWithResult:@{@"id": @"111"} error:nil]; + [self stubGraphRequestWithResult:@{@"id" : @"111"} error:nil]; OCMStub([_mockConfig shouldLaunchMediaDialog]).andReturn(true); - OCMStub([_mockApp - openURL:[OCMArg any] - options:[OCMArg any] - completionHandler:([OCMArg invokeBlockWithArgs:@(false), nil])]); + OCMStub( + [_mockApp + openURL:[OCMArg any] + options:[OCMArg any] + completionHandler:([OCMArg invokeBlockWithArgs:@(false), nil])] + ); // This will cause an lint warning, ignore it, this is an external sdk test // @lint-ignore FBOBJCDISCOURAGEDFUNCTION @@ -157,13 +158,13 @@ - (void)testGraphResponsesTriggerDialogIfDialogIsRequested [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - [expectation fulfill]; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:1 handler:nil]; - id urlCheck = [OCMArg checkWithBlock:^BOOL(id obj) { + id urlCheck = [OCMArg checkWithBlock:^BOOL (id obj) { return [[(NSURL *)obj absoluteString] isEqualToString:@"https://fb.gg/me/media_asset/111"]; }]; OCMVerify([_mockApp openURL:urlCheck options:[OCMArg any] completionHandler:[OCMArg any]]); @@ -174,7 +175,7 @@ - (void)testDialogCompletionOnURLCallback id settings = OCMClassMock([FBSDKSettings class]); OCMStub([settings appID]).andReturn(@"123"); - [self stubGraphRequestWithResult:@{@"id": @"111"} error:nil]; + [self stubGraphRequestWithResult:@{@"id" : @"111"} error:nil]; OCMStub([_mockConfig shouldLaunchMediaDialog]).andReturn(true); __block id delegate; @@ -185,10 +186,10 @@ - (void)testDialogCompletionOnURLCallback __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssertTrue(success); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssertTrue(success); + actioned = true; + }]; [delegate application:_mockApp @@ -201,7 +202,7 @@ - (void)testDialogCompletionOnURLCallback - (void)testDialogCompletionOnApplicationBecameActive { - [self stubGraphRequestWithResult:@{@"id": @"111"} error:nil]; + [self stubGraphRequestWithResult:@{@"id" : @"111"} error:nil]; OCMStub([_mockConfig shouldLaunchMediaDialog]).andReturn(true); __block id delegate; @@ -212,10 +213,10 @@ - (void)testDialogCompletionOnApplicationBecameActive __block BOOL actioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssertTrue(success); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssertTrue(success); + actioned = true; + }]; [delegate applicationDidBecomeActive:_mockApp]; @@ -227,31 +228,31 @@ - (void)testUploadProgress __block id delegate; __block FBSDKGraphRequestBlock completion; id mockConnection = [self stubGraphRequestWithDelegateCapture:^(id obj) { - delegate = obj; - } andCompletionCapture:^(FBSDKGraphRequestBlock obj) { - completion = obj; - }]; + delegate = obj; + } andCompletionCapture:^(FBSDKGraphRequestBlock obj) { + completion = obj; + }]; __block BOOL completionActioned = false; __block BOOL progressActioned = false; [FBSDKGamingImageUploader uploadImageWithConfiguration:_mockConfig - completionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(success); - XCTAssertEqual(result[@"id"], @"foo"); - completionActioned = true; - } + completionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(success); + XCTAssertEqual(result[@"id"], @"foo"); + completionActioned = true; + } andProgressHandler:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { - XCTAssertEqual(bytesSent, 123); - XCTAssertEqual(totalBytesSent, 456); - XCTAssertEqual(totalBytesExpectedToSend, 789); - progressActioned = true; - }]; + XCTAssertEqual(bytesSent, 123); + XCTAssertEqual(totalBytesSent, 456); + XCTAssertEqual(totalBytesExpectedToSend, 789); + progressActioned = true; + }]; [delegate requestConnection:mockConnection didSendBodyData:123 totalBytesWritten:456 totalBytesExpectedToWrite:789]; XCTAssertTrue(progressActioned); - completion(mockConnection, @{@"id": @"foo"}, nil); + completion(mockConnection, @{@"id" : @"foo"}, nil); XCTAssertTrue(completionActioned); } @@ -276,14 +277,18 @@ - (id)stubGraphRequestWithDelegateCapture:(void (^)(id))captureHa id mock = OCMClassMock([FBSDKBridgeAPI class]); OCMStub([mock sharedInstance]).andReturn(mock); - OCMStub([mock openURL:[OCMArg any] sender:[OCMArg checkWithBlock:^BOOL(id obj) { - captureHandler(obj); - return true; - }] handler:[OCMArg any]]); + OCMStub( + [mock openURL:[OCMArg any] sender:[OCMArg checkWithBlock:^BOOL (id obj) { + captureHandler(obj); + return true; + }] handler:[OCMArg any]] + ); } @end diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingVideoUploaderTests.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingVideoUploaderTests.m index f3a1f41c42..f0955e03c4 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingVideoUploaderTests.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKitTests/FBSDKGamingVideoUploaderTests.m @@ -16,9 +16,8 @@ // 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 @@ -66,10 +65,10 @@ - (void)testFailureWhenNoValidAccessTokenPresent __block BOOL actioned = false; [FBSDKGamingVideoUploader uploadVideoWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorAccessTokenRequired, "Expected error requiring a valid access token"); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorAccessTokenRequired, "Expected error requiring a valid access token"); + actioned = true; + }]; XCTAssertTrue(actioned); } @@ -81,10 +80,10 @@ - (void)testNilVideoURLFails __block BOOL actioned = false; [FBSDKGamingVideoUploader uploadVideoWithConfiguration:nilVideoConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorInvalidArgument, "Expected error requiring a non nil video url"); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorInvalidArgument, "Expected error requiring a non nil video url"); + actioned = true; + }]; XCTAssertTrue(actioned); } @@ -97,10 +96,10 @@ - (void)testBadVideoURLFails __block BOOL actioned = false; [FBSDKGamingVideoUploader uploadVideoWithConfiguration:badVideoConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorInvalidArgument, "Expected error requiring a non nil video url"); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorInvalidArgument, "Expected error requiring a non nil video url"); + actioned = true; + }]; XCTAssertTrue(actioned); } @@ -117,10 +116,10 @@ - (void)testVideoUploaderErrorsAreHandled __block BOOL actioned = false; [FBSDKGamingVideoUploader uploadVideoWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == expectedError.code); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == expectedError.code); + actioned = true; + }]; [delegate videoUploader:mockUploader didFailWithError:expectedError]; @@ -137,15 +136,15 @@ - (void)testVideoUploaderErrorOnUnsuccessful __block BOOL actioned = false; [FBSDKGamingVideoUploader uploadVideoWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssert(error.code == FBSDKErrorUnknown); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssert(error.code == FBSDKErrorUnknown); + actioned = true; + }]; [delegate videoUploader:mockUploader didCompleteWithResults:@{ - @"success": @(false) + @"success" : @(false) }]; XCTAssertTrue(actioned); @@ -161,15 +160,15 @@ - (void)testVideoUploaderSucceeds __block BOOL actioned = false; [FBSDKGamingVideoUploader uploadVideoWithConfiguration:_mockConfig - andResultCompletionHandler:^(BOOL success, id result, NSError * _Nullable error) { - XCTAssertTrue(success); - actioned = true; - }]; + andResultCompletionHandler:^(BOOL success, id result, NSError *_Nullable error) { + XCTAssertTrue(success); + actioned = true; + }]; [delegate videoUploader:mockUploader didCompleteWithResults:@{ - @"success": @(true) + @"success" : @(true) }]; XCTAssertTrue(actioned); @@ -184,7 +183,7 @@ - (void)testVideoUploaderProgress __block BOOL actionedFirst = false; __block void (^ProgressCheck)(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) = - ^void(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { + ^void (int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { XCTAssertEqual(bytesSent, 0); XCTAssertEqual(totalBytesSent, 0); XCTAssertEqual(totalBytesExpectedToSend, 999); @@ -193,10 +192,10 @@ __block void (^ProgressCheck)(int64_t bytesSent, int64_t totalBytesSent, int64_t [FBSDKGamingVideoUploader uploadVideoWithConfiguration:_mockConfig - completionHandler:^(BOOL success, id result, NSError * _Nullable error) {} + completionHandler:^(BOOL success, id result, NSError *_Nullable error) {} andProgressHandler:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { - ProgressCheck(bytesSent, totalBytesSent, totalBytesExpectedToSend); - }]; + ProgressCheck(bytesSent, totalBytesSent, totalBytesExpectedToSend); + }]; // Send some bytes [delegate @@ -206,7 +205,7 @@ __block void (^ProgressCheck)(int64_t bytesSent, int64_t totalBytesSent, int64_t __block BOOL actionedSecond = false; ProgressCheck = - ^void(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { + ^void (int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { XCTAssertEqual(bytesSent, 500); XCTAssertEqual(totalBytesSent, 500); XCTAssertEqual(totalBytesExpectedToSend, 999); @@ -215,24 +214,24 @@ __block void (^ProgressCheck)(int64_t bytesSent, int64_t totalBytesSent, int64_t // Send some more bytes [delegate - videoChunkDataForVideoUploader:mockUploader - startOffset:500 - endOffset:999]; + videoChunkDataForVideoUploader:mockUploader + startOffset:500 + endOffset:999]; __block BOOL actionedThird = false; ProgressCheck = - ^void(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { - XCTAssertEqual(bytesSent, 499); - XCTAssertEqual(totalBytesSent, 999); - XCTAssertEqual(totalBytesExpectedToSend, 999); - actionedThird = true; - }; + ^void (int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { + XCTAssertEqual(bytesSent, 499); + XCTAssertEqual(totalBytesSent, 999); + XCTAssertEqual(totalBytesExpectedToSend, 999); + actionedThird = true; + }; // Finish upload [delegate videoUploader:mockUploader didCompleteWithResults:@{ - @"success": @(true) + @"success" : @(true) }]; XCTAssertTrue(actionedFirst); @@ -258,10 +257,12 @@ - (id)mockVideoUploaderWithDelegateCapture:(void (^)(id + #import #else -#import + #import #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginCodeInfo.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginCodeInfo.m index 4f22fce519..ebe3a3b365 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginCodeInfo.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginCodeInfo.m @@ -21,10 +21,10 @@ @implementation FBSDKDeviceLoginCodeInfo - (instancetype)initWithIdentifier:(NSString *)identifier - loginCode:(NSString *)loginCode - verificationURL:(NSURL *)verificationURL - expirationDate:(NSDate *)expirationDate - pollingInterval:(NSUInteger)pollingInterval + loginCode:(NSString *)loginCode + verificationURL:(NSURL *)verificationURL + expirationDate:(NSDate *)expirationDate + pollingInterval:(NSUInteger)pollingInterval { if ((self = [super init])) { _identifier = [identifier copy]; @@ -35,4 +35,5 @@ - (instancetype)initWithIdentifier:(NSString *)identifier } return self; } + @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginManager.m index 7acc8731b0..6c802b64a8 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKDeviceLoginManager.m @@ -17,13 +17,14 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKDeviceLoginManager.h" + #import "FBSDKDeviceLoginManagerResult+Internal.h" #ifdef FBSDKCOCOAPODS -#import -#import + #import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKDeviceLoginCodeInfo+Internal.h" @@ -31,10 +32,11 @@ static NSMutableArray *g_loginManagerInstances; -@implementation FBSDKDeviceLoginManager { +@implementation FBSDKDeviceLoginManager +{ FBSDKDeviceLoginCodeInfo *_codeInfo; BOOL _isCancelled; - NSNetService * _loginAdvertisementService; + NSNetService *_loginAdvertisementService; BOOL _isSmartLoginEnabled; } @@ -60,10 +62,10 @@ - (void)start [FBSDKTypeUtility array:g_loginManagerInstances addObject:self]; NSDictionary *parameters = @{ - @"scope": [self.permissions componentsJoinedByString:@","] ?: @"", - @"redirect_uri": self.redirectURL.absoluteString ?: @"", - FBSDK_DEVICE_INFO_PARAM: [FBSDKDeviceRequestsHelper getDeviceInfo], - }; + @"scope" : [self.permissions componentsJoinedByString:@","] ?: @"", + @"redirect_uri" : self.redirectURL.absoluteString ?: @"", + FBSDK_DEVICE_INFO_PARAM : [FBSDKDeviceRequestsHelper getDeviceInfo], + }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"device/login" parameters:parameters tokenString:[FBSDKInternalUtility validateRequiredClientAccessToken] @@ -77,11 +79,11 @@ - (void)start } self->_codeInfo = [[FBSDKDeviceLoginCodeInfo alloc] - initWithIdentifier:result[@"code"] - loginCode:result[@"user_code"] - verificationURL:[NSURL URLWithString:result[@"verification_uri"]] - expirationDate:[[NSDate date] dateByAddingTimeInterval:[result[@"expires_in"] doubleValue]] - pollingInterval:[result[@"interval"] integerValue]]; + initWithIdentifier:result[@"code"] + loginCode:result[@"user_code"] + verificationURL:[NSURL URLWithString:result[@"verification_uri"]] + expirationDate:[[NSDate date] dateByAddingTimeInterval:[result[@"expires_in"] doubleValue]] + pollingInterval:[result[@"interval"] integerValue]]; if (self->_isSmartLoginEnabled) { [FBSDKDeviceRequestsHelper startAdvertisementService:self->_codeInfo.loginCode @@ -92,7 +94,7 @@ - (void)start [self.delegate deviceLoginManager:self startedWithCodeInfo:self->_codeInfo]; [self _schedulePoll:self->_codeInfo.pollingInterval]; }]; - } +} - (void)cancel { @@ -112,10 +114,10 @@ - (void)_notifyError:(NSError *)error [g_loginManagerInstances removeObject:self]; } -- (void)_notifyToken:(NSString *)tokenString +- (void)_notifyToken:(NSString *)tokenString withExpirationDate:(NSDate *)expirationDate withDataAccessExpirationDate:(NSDate *)dataAccessExpirationDate { [FBSDKDeviceRequestsHelper cleanUpAdvertisementService:self]; - void(^completeWithResult)(FBSDKDeviceLoginManagerResult *) = ^(FBSDKDeviceLoginManagerResult *result) { + void (^completeWithResult)(FBSDKDeviceLoginManagerResult *) = ^(FBSDKDeviceLoginManagerResult *result) { [self.delegate deviceLoginManager:self completedWithResult:result error:nil]; [g_loginManagerInstances removeObject:self]; }; @@ -123,27 +125,27 @@ - (void)_notifyToken:(NSString *)tokenString if (tokenString) { FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" - parameters:@{@"fields": @"id,permissions"} + parameters:@{@"fields" : @"id,permissions"} tokenString:tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [permissionsRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id permissionRawResult, NSError *error) { NSString *userID = permissionRawResult[@"id"]; NSDictionary *permissionResult = permissionRawResult[@"permissions"]; - if (error || - !userID || - !permissionResult) { -#if TARGET_TV_OS + if (error + || !userID + || !permissionResult) { + #if TARGET_TV_OS NSError *wrappedError = [FBSDKError errorWithDomain:FBSDKShareErrorDomain code:FBSDKErrorTVOSUnknown message:@"Unable to fetch permissions for token" underlyingError:error]; -#else + #else NSError *wrappedError = [FBSDKError errorWithDomain:FBSDKLoginErrorDomain code:FBSDKErrorUnknown message:@"Unable to fetch permissions for token" underlyingError:error]; -#endif + #endif [self _notifyError:wrappedError]; } else { NSMutableSet *permissions = [NSMutableSet set]; @@ -153,19 +155,20 @@ - (void)_notifyToken:(NSString *)tokenString [FBSDKInternalUtility extractPermissionsFromResponse:permissionResult grantedPermissions:permissions declinedPermissions:declinedPermissions - expiredPermissions:expiredPermissions]; + expiredPermissions:expiredPermissions]; FBSDKAccessToken *accessToken = [[FBSDKAccessToken alloc] initWithTokenString:tokenString permissions:permissions.allObjects declinedPermissions:declinedPermissions.allObjects expiredPermissions:expiredPermissions.allObjects appID:[FBSDKSettings appID] userID:userID - expirationDate:nil + expirationDate:expirationDate refreshDate:nil - dataAccessExpirationDate:nil + dataAccessExpirationDate:dataAccessExpirationDate graphDomain:nil]; FBSDKDeviceLoginManagerResult *result = [[FBSDKDeviceLoginManagerResult alloc] initWithToken:accessToken isCancelled:NO]; + [FBSDKAccessToken setCurrentAccessToken:accessToken]; completeWithResult(result); } }]; @@ -185,7 +188,7 @@ - (void)_processError:(NSError *)error break; case FBSDKDeviceLoginErrorCodeExpired: case FBSDKDeviceLoginErrorAuthorizationDeclined: - [self _notifyToken:nil]; + [self _notifyToken:nil withExpirationDate:nil withDataAccessExpirationDate:nil]; break; case FBSDKDeviceLoginErrorExcessivePolling: [self _schedulePoll:_codeInfo.pollingInterval * 2]; @@ -197,45 +200,55 @@ - (void)_processError:(NSError *)error - (void)_schedulePoll:(NSUInteger)interval { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - if (self->_isCancelled) { - return; - } - - NSDictionary *parameters = @{ @"code": self->_codeInfo.identifier }; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"device/login_status" - parameters:parameters - tokenString:[FBSDKInternalUtility validateRequiredClientAccessToken] - HTTPMethod:@"POST" - flags:FBSDKGraphRequestFlagNone]; - [request setGraphErrorRecoveryDisabled:YES]; - [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ if (self->_isCancelled) { return; } - if (error) { - [self _processError:error]; - } else { - NSString *tokenString = result[@"access_token"]; - if (tokenString) { - [self _notifyToken:tokenString]; + + NSDictionary *parameters = @{ @"code" : self->_codeInfo.identifier }; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"device/login_status" + parameters:parameters + tokenString:[FBSDKInternalUtility validateRequiredClientAccessToken] + HTTPMethod:@"POST" + flags:FBSDKGraphRequestFlagNone]; + [request setGraphErrorRecoveryDisabled:YES]; + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + if (self->_isCancelled) { + return; + } + if (error) { + [self _processError:error]; } else { - NSError *unknownError = [FBSDKError errorWithDomain:FBSDKLoginErrorDomain - code:FBSDKErrorUnknown - message:@"Device Login poll failed. No token nor error was found."]; - [self _notifyError:unknownError]; + NSString *tokenString = result[@"access_token"]; + NSDate *expirationDate = [NSDate distantFuture]; + if ([result[@"expires_in"] integerValue] > 0) { + expirationDate = [NSDate dateWithTimeIntervalSinceNow:[result[@"expires_in"] integerValue]]; + } + + NSDate *dataAccessExpirationDate = [NSDate distantFuture]; + if ([result[@"data_access_expiration_time"] integerValue] > 0) { + dataAccessExpirationDate = [NSDate dateWithTimeIntervalSince1970:[result[@"data_access_expiration_time"] integerValue]]; + } + + if (tokenString) { + [self _notifyToken:tokenString withExpirationDate:expirationDate withDataAccessExpirationDate:dataAccessExpirationDate]; + } else { + NSError *unknownError = [FBSDKError errorWithDomain:FBSDKLoginErrorDomain + code:FBSDKErrorUnknown + message:@"Device Login poll failed. No token nor error was found."]; + [self _notifyError:unknownError]; + } } - } - }]; - }); + }]; + }); } - (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict { // Only cleanup if the publish error is from our advertising service - if ([FBSDKDeviceRequestsHelper isDelegate:self forAdvertisementService:sender]) - { + if ([FBSDKDeviceRequestsHelper isDelegate:self forAdvertisementService:sender]) { [FBSDKDeviceRequestsHelper cleanUpAdvertisementService:self]; } } diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index 933e21d18a..98ddb4acc6 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -20,15 +20,15 @@ #if !TARGET_OS_TV -#import "FBSDKLoginButton.h" + #import "FBSDKLoginButton.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif -#import "FBSDKLoginTooltipView.h" + #import "FBSDKLoginTooltipView.h" static const CGFloat kFBLogoSize = 16.0; static const CGFloat kFBLogoLeftMargin = 6.0; @@ -36,7 +36,7 @@ static const CGFloat kRightMargin = 8.0; static const CGFloat kPaddingBetweenLogoTitle = 8.0; -@interface FBSDKLoginButton() +@interface FBSDKLoginButton () @end @implementation FBSDKLoginButton @@ -47,14 +47,14 @@ @implementation FBSDKLoginButton NSString *_userName; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -#pragma mark - Properties + #pragma mark - Properties - (FBSDKDefaultAudience)defaultAudience { @@ -77,20 +77,20 @@ - (UIFont *)defaultFont } } -#pragma mark - UIView + #pragma mark - UIView - (void)didMoveToWindow { [super didMoveToWindow]; - if (self.window && - ((self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorForceDisplay) || !_hasShownTooltipBubble)) { + if (self.window + && ((self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorForceDisplay) || !_hasShownTooltipBubble)) { [self performSelector:@selector(_showTooltipIfNeeded) withObject:nil afterDelay:0]; _hasShownTooltipBubble = YES; } } -#pragma mark - Layout + #pragma mark - Layout - (CGRect)imageRectForContentRect:(CGRect)contentRect { @@ -115,9 +115,9 @@ - (void)layoutSubviews { CGSize size = self.bounds.size; CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]]; - NSString *title = (longTitleSize.width <= size.width ? - [self _longLogInTitle] : - [self _shortLogInTitle]); + NSString *title = (longTitleSize.width <= size.width + ? [self _longLogInTitle] + : [self _shortLogInTitle]); if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) { [self setTitle:title forState:UIControlStateNormal]; } @@ -143,7 +143,7 @@ - (CGSize)sizeThatFits:(CGSize)size return CGSizeMake(buttonWidth, kButtonHeight); } -#pragma mark - FBSDKButtonImpressionTracking + #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { @@ -160,7 +160,7 @@ - (NSString *)impressionTrackingIdentifier return @"login"; } -#pragma mark - FBSDKButton + #pragma mark - FBSDKButton - (void)configureButton { @@ -170,13 +170,13 @@ - (void)configureButton NSString *logOutTitle = [self _logOutTitle]; [self configureWithIcon:nil - title:logInTitle - backgroundColor:self.backgroundColor - highlightedColor:nil - selectedTitle:logOutTitle - selectedIcon:nil - selectedColor:self.backgroundColor - selectedHighlightedColor:nil]; + title:logInTitle + backgroundColor:self.backgroundColor + highlightedColor:nil + selectedTitle:logOutTitle + selectedIcon:nil + selectedColor:self.backgroundColor + selectedHighlightedColor:nil]; self.titleLabel.textAlignment = NSTextAlignmentCenter; [self addConstraint:[NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight @@ -194,7 +194,7 @@ - (void)configureButton object:nil]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { @@ -211,25 +211,41 @@ - (void)_buttonPressed:(id)sender if (_userName) { NSString *localizedFormatString = - NSLocalizedStringWithDefaultValue(@"LoginButton.LoggedInAs", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Logged in as %@", - @"The format string for the FBSDKLoginButton label when the user is logged in"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.LoggedInAs", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Logged in as %@", + @"The format string for the FBSDKLoginButton label when the user is logged in" + ); title = [NSString localizedStringWithFormat:localizedFormatString, _userName]; } else { NSString *localizedLoggedIn = - NSLocalizedStringWithDefaultValue(@"LoginButton.LoggedIn", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Logged in using Facebook", - @"The fallback string for the FBSDKLoginButton label when the user name is not available yet"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.LoggedIn", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Logged in using Facebook", + @"The fallback string for the FBSDKLoginButton label when the user name is not available yet" + ); title = localizedLoggedIn; } NSString *cancelTitle = - NSLocalizedStringWithDefaultValue(@"LoginButton.CancelLogout", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Cancel", - @"The label for the FBSDKLoginButton action sheet to cancel logging out"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.CancelLogout", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Cancel", + @"The label for the FBSDKLoginButton action sheet to cancel logging out" + ); NSString *logOutTitle = - NSLocalizedStringWithDefaultValue(@"LoginButton.ConfirmLogOut", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log Out", - @"The label for the FBSDKLoginButton action sheet to confirm logging out"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.ConfirmLogOut", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log Out", + @"The label for the FBSDKLoginButton action sheet to confirm logging out" + ); UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet]; @@ -240,7 +256,7 @@ - (void)_buttonPressed:(id)sender handler:nil]; UIAlertAction *logout = [UIAlertAction actionWithTitle:logOutTitle style:UIAlertActionStyleDestructive - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *_Nonnull action) { [self->_loginManager logOut]; [self.delegate loginButtonDidLogOut:self]; }]; @@ -266,29 +282,40 @@ - (void)_buttonPressed:(id)sender [_loginManager logInWithPermissions:self.permissions fromViewController:[FBSDKInternalUtility viewControllerForView:self] handler:handler]; - } } - (NSString *)_logOutTitle { - return NSLocalizedStringWithDefaultValue(@"LoginButton.LogOut", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log out", - @"The label for the FBSDKLoginButton when the user is currently logged in"); + return NSLocalizedStringWithDefaultValue( + @"LoginButton.LogOut", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log out", + @"The label for the FBSDKLoginButton when the user is currently logged in" + ); } - (NSString *)_longLogInTitle { - return NSLocalizedStringWithDefaultValue(@"LoginButton.LogInContinue", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Continue with Facebook", - @"The long label for the FBSDKLoginButton when the user is currently logged out"); + return NSLocalizedStringWithDefaultValue( + @"LoginButton.LogInContinue", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Continue with Facebook", + @"The long label for the FBSDKLoginButton when the user is currently logged out" + ); } - (NSString *)_shortLogInTitle { - return NSLocalizedStringWithDefaultValue(@"LoginButton.LogIn", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log in", - @"The short label for the FBSDKLoginButton when the user is currently logged out"); + return NSLocalizedStringWithDefaultValue( + @"LoginButton.LogIn", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log in", + @"The short label for the FBSDKLoginButton when the user is currently logged out" + ); } - (void)_showTooltipIfNeeded diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h index f19b1accbe..7ae9c67e20 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h @@ -25,8 +25,10 @@ #import "FBSDKLoginConstants.h" #if !TARGET_OS_TV -#import "FBSDKLoginButton.h" -#import "FBSDKLoginManager.h" -#import "FBSDKLoginManagerLoginResult.h" -#import "FBSDKLoginTooltipView.h" + #import "FBSDKLoginButton.h" + #import "FBSDKLoginManager.h" + #import "FBSDKLoginManagerLoginResult.h" + #import "FBSDKLoginTooltipView.h" + #import "FBSDKReferralManager.h" + #import "FBSDKReferralManagerResult.h" #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index 71997442ec..7e8de2365d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -144,6 +144,17 @@ NS_SWIFT_NAME(LoginManager) handler:(nullable FBSDKLoginManagerLoginResultBlock)handler NS_SWIFT_NAME(logIn(permissions:from:handler:)); +/** + Logs the user in with the given deep link url. Will only log user in if the given url contains valid login data. + @param url the deep link url + @param handler the callback. + + This method should be called with the url from the openURL method. + */ +- (void)logInWithURL:(NSURL *)url + handler:(nullable FBSDKLoginManagerLoginResultBlock)handler +NS_SWIFT_NAME(logIn(url:handler:)); + /** Requests user's permission to reathorize application's data access, after it has expired due to inactivity. @param fromViewController the view controller to present from. If nil, the topmost view controller will be diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index a001ce857d..1d76f71768 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -20,28 +20,29 @@ #if !TARGET_OS_TV -#import "FBSDKLoginManager+Internal.h" -#import "FBSDKLoginManagerLoginResult+Internal.h" - -#ifdef SWIFT_PACKAGE -#import "FBSDKAccessToken.h" -#import "FBSDKSettings.h" -#else -#import -#endif - -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif - -#import "_FBSDKLoginRecoveryAttempter.h" -#import "FBSDKLoginCompletion.h" -#import "FBSDKLoginConstants.h" -#import "FBSDKLoginError.h" -#import "FBSDKLoginManagerLogger.h" -#import "FBSDKLoginUtility.h" + #import "FBSDKLoginManager+Internal.h" + + #import "FBSDKLoginManagerLoginResult+Internal.h" + + #ifdef SWIFT_PACKAGE + #import "FBSDKAccessToken.h" + #import "FBSDKSettings.h" + #else + #import + #endif + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + + #import "FBSDKLoginCompletion.h" + #import "FBSDKLoginConstants.h" + #import "FBSDKLoginError.h" + #import "FBSDKLoginManagerLogger.h" + #import "FBSDKLoginUtility.h" + #import "_FBSDKLoginRecoveryAttempter.h" static int const FBClientStateChallengeLength = 20; static NSString *const FBSDKExpectedChallengeKey = @"expected_login_challenge"; @@ -53,14 +54,6 @@ FBSDKLoginAuthType FBSDKLoginAuthTypeRerequest = @"rerequest"; FBSDKLoginAuthType FBSDKLoginAuthTypeReauthorize = @"reauthorize"; -typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { - FBSDKLoginManagerStateIdle, - // We received a call to start login. - FBSDKLoginManagerStateStart, - // We're calling out to the Facebook app or Safari to perform a log in - FBSDKLoginManagerStatePerformingLogin, -}; - @implementation FBSDKLoginManager { FBSDKLoginManagerLoginResultBlock _handler; @@ -110,14 +103,13 @@ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FB [self reauthorizeDataAccess:handler]; } - - (void)logOut { [FBSDKAccessToken setCurrentAccessToken:nil]; [FBSDKProfile setCurrentProfile:nil]; } -#pragma mark - Private + #pragma mark - Private - (void)raiseLoginException:(NSException *)exception { @@ -153,7 +145,7 @@ - (BOOL)validateLoginStartState formatString:@"%@", errorStr]; return NO; } - case FBSDKLoginManagerStatePerformingLogin:{ + case FBSDKLoginManagerStatePerformingLogin: { [self handleImplicitCancelOfLogIn]; return YES; } @@ -173,8 +165,8 @@ - (void)assertPermissions:(NSArray *)permissions for (NSString *permission in permissions) { if (![permission isKindOfClass:[NSString class]]) { [self raiseLoginException:[NSException exceptionWithName:NSInvalidArgumentException - reason:@"Permissions must be string values." - userInfo:nil]]; + reason:@"Permissions must be string values." + userInfo:nil]]; } if ([permission rangeOfString:@","].location != NSNotFound) { [self raiseLoginException:[NSException exceptionWithName:NSInvalidArgumentException @@ -230,7 +222,7 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe userID:parameters.userID expirationDate:parameters.expirationDate refreshDate:[NSDate date] - dataAccessExpirationDate:parameters.dataAccessExpirationDate + dataAccessExpirationDate:parameters.dataAccessExpirationDate graphDomain:parameters.graphDomain]; result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:token isCancelled:NO @@ -273,15 +265,15 @@ - (void)determineRecentlyGrantedPermissions:(NSSet **)recentlyGrantedPermissions declinedPermissions:(NSSet *)declinedPermissions { NSMutableSet *recentlyGrantedPermissions = [grantedPermissions mutableCopy]; - NSSet *previouslyGrantedPermissions = ([FBSDKAccessToken currentAccessToken] ? - [FBSDKAccessToken currentAccessToken].permissions : - nil); + NSSet *previouslyGrantedPermissions = ([FBSDKAccessToken currentAccessToken] + ? [FBSDKAccessToken currentAccessToken].permissions + : nil); if (previouslyGrantedPermissions.count > 0) { - // If there were no requested permissions for this auth - treat all permissions as granted. - // Otherwise this is a reauth, so recentlyGranted should be a subset of what was requested. - if (_requestedPermissions.count != 0) { - [recentlyGrantedPermissions intersectSet:_requestedPermissions]; - } + // If there were no requested permissions for this auth - treat all permissions as granted. + // Otherwise this is a reauth, so recentlyGranted should be a subset of what was requested. + if (_requestedPermissions.count != 0) { + [recentlyGrantedPermissions intersectSet:_requestedPermissions]; + } } NSMutableSet *recentlyDeclinedPermissions = [_requestedPermissions mutableCopy]; @@ -345,7 +337,7 @@ - (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConf [FBSDKTypeUtility dictionary:loginParams setObject:[permissions.allObjects componentsJoinedByString:@","] forKey:@"scope"]; NSString *expectedChallenge = [FBSDKLoginManager stringForChallenge]; - NSDictionary *state = @{@"challenge": [FBSDKUtility URLEncode:expectedChallenge]}; + NSDictionary *state = @{@"challenge" : [FBSDKUtility URLEncode:expectedChallenge]}; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKBasicUtility JSONStringForObject:state error:NULL invalidObjectHandler:nil] forKey:@"state"]; [self storeExpectedChallenge:expectedChallenge]; @@ -366,6 +358,43 @@ - (void)logInWithPermissions:(NSSet *)permissions handler:(FBSDKLoginManagerLogi [self logIn]; } +- (NSDictionary *)logInParametersFromURL:(NSURL *)url +{ + NSError *error = nil; + FBSDKURL *parsedUrl = [FBSDKURL URLWithURL:url]; + NSDictionary *extras = parsedUrl.appLinkExtras; + + if (extras) { + NSString *fbLoginDataString = extras[@"fb_login"]; + NSDictionary *fbLoginData = [FBSDKTypeUtility dictionaryValue:[FBSDKBasicUtility objectForJSONString:fbLoginDataString error:&error]]; + if (!error && fbLoginData) { + return fbLoginData; + } + } + error = error ?: [FBSDKError errorWithCode:FBSDKLoginErrorUnknown message:@"Failed to parse deep link url for login data"]; + [self invokeHandler:nil error:error]; + return nil; +} + +- (void)logInWithURL:(NSURL *)url + handler:(nullable FBSDKLoginManagerLoginResultBlock)handler +{ + FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; + _logger = [[FBSDKLoginManagerLogger alloc] initWithLoggingToken:serverConfiguration.loggingToken]; + _handler = [handler copy]; + + [_logger startSessionForLoginManager:self]; + [_logger startAuthMethod:FBSDKLoginManagerLoggerAuthMethod_Applink]; + + NSDictionary *params = [self logInParametersFromURL:url]; + if (params) { + id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:params appID:[FBSDKSettings appID]]; + [completer completeLoginWithHandler:^(FBSDKLoginCompletionParameters *parameters) { + [self completeAuthentication:parameters expectChallenge:NO]; + }]; + } +} + - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler { FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; @@ -384,11 +413,11 @@ - (void)logIn NSDictionary *loginParams = [self logInParametersWithPermissions:_requestedPermissions serverConfiguration:serverConfiguration]; self->_usedSFAuthSession = NO; - void(^completion)(BOOL, NSError *) = ^void(BOOL didPerformLogIn, NSError *error) { + void (^completion)(BOOL, NSError *) = ^void (BOOL didPerformLogIn, NSError *error) { if (didPerformLogIn) { self->_state = FBSDKLoginManagerStatePerformingLogin; - } else if ([error.domain isEqualToString:SFVCCanceledLogin] || - [error.domain isEqualToString:ASCanceledLogin]) { + } else if ([error.domain isEqualToString:SFVCCanceledLogin] + || [error.domain isEqualToString:ASCanceledLogin]) { [self handleImplicitCancelOfLogIn]; } else { if (!error) { @@ -400,8 +429,8 @@ - (void)logIn [self performBrowserLogInWithParameters:loginParams handler:^(BOOL openedURL, NSError *openedURLError) { - completion(openedURL, openedURLError); - }]; + completion(openedURL, openedURLError); + }]; } - (void)storeExpectedChallenge:(NSString *)challengeExpected @@ -411,7 +440,8 @@ - (void)storeExpectedChallenge:(NSString *)challengeExpected accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; } -+ (NSString *)stringForChallenge { ++ (NSString *)stringForChallenge +{ NSString *challenge = [FBSDKCrypto randomString:FBClientStateChallengeLength]; return [challenge stringByReplacingOccurrencesOfString:@"+" withString:@"="]; @@ -420,7 +450,7 @@ + (NSString *)stringForChallenge { - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult { FBSDKGraphRequest *requestMe = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" - parameters:@{@"fields":@""} + parameters:@{@"fields" : @""} tokenString:loginResult.token.tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -435,12 +465,12 @@ - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FB NSError *resultError = [NSError errorWithDomain:FBSDKLoginErrorDomain code:FBSDKLoginErrorUserMismatch userInfo:userInfo]; - [self invokeHandler:nil error:resultError]; + [self invokeHandler:nil error:resultError]; } }]; } -#pragma mark - Test Methods + #pragma mark - Test Methods - (void)setHandler:(FBSDKLoginManagerLoginResultBlock)handler { @@ -470,8 +500,8 @@ - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams if (!error) { NSMutableDictionary *browserParams = [loginParams mutableCopy]; [FBSDKTypeUtility dictionary:browserParams - setObject:redirectURL - forKey:@"redirect_uri"]; + setObject:redirectURL + forKey:@"redirect_uri"]; authURL = [FBSDKInternalUtility facebookURLWithHostPrefix:@"m." path:FBSDKOauthPath queryParameters:browserParams @@ -481,7 +511,7 @@ - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams [_logger startAuthMethod:authMethod]; if (authURL) { - void(^handlerWrapper)(BOOL, NSError*) = ^(BOOL didOpen, NSError *anError) { + void (^handlerWrapper)(BOOL, NSError *) = ^(BOOL didOpen, NSError *anError) { if (handler) { handler(didOpen, anError); } @@ -491,9 +521,9 @@ - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams // Note based on above, authURL must be a http scheme. If that changes, add a guard, otherwise SFVC can throw self->_usedSFAuthSession = YES; [[FBSDKBridgeAPI sharedInstance] openURLWithSafariViewController:authURL - sender:self - fromViewController:self.fromViewController - handler:handlerWrapper]; + sender:self + fromViewController:self.fromViewController + handler:handlerWrapper]; } else { [[FBSDKBridgeAPI sharedInstance] openURL:authURL sender:self handler:handlerWrapper]; } @@ -505,7 +535,7 @@ - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams } } -#pragma mark - FBSDKURLOpening + #pragma mark - FBSDKURLOpening - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { BOOL isFacebookURL = [self canOpenURL:url forApplication:application sourceApplication:sourceApplication annotation:annotation]; @@ -531,14 +561,14 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl return isFacebookURL; } -- (BOOL)canOpenURL:(NSURL *)url - forApplication:(UIApplication *)application - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation +- (BOOL) canOpenURL:(NSURL *)url + forApplication:(UIApplication *)application + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { // verify the URL is intended as a callback for the SDK's log in - return [url.scheme hasPrefix:[NSString stringWithFormat:@"fb%@", [FBSDKSettings appID]]] && - [url.host isEqualToString:@"authorize"]; + return [url.scheme hasPrefix:[NSString stringWithFormat:@"fb%@", [FBSDKSettings appID]]] + && [url.host isEqualToString:@"authorize"]; } - (void)applicationDidBecomeActive:(UIApplication *)application diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m index a3009e4d97..708685570b 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m @@ -20,29 +20,32 @@ #if !TARGET_OS_TV -#import "FBSDKLoginManagerLoginResult+Internal.h" + #import "FBSDKLoginManagerLoginResult+Internal.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif -@implementation FBSDKLoginManagerLoginResult { +@implementation FBSDKLoginManagerLoginResult +{ NSMutableDictionary *_mutableLoggingExtras; } - (instancetype)initWithToken:(FBSDKAccessToken *)token isCancelled:(BOOL)isCancelled grantedPermissions:(NSSet *)grantedPermissions - declinedPermissions:(NSSet *)declinedPermissions { + declinedPermissions:(NSSet *)declinedPermissions +{ if ((self = [super init])) { _mutableLoggingExtras = [NSMutableDictionary dictionary]; _token = token ? [token copy] : nil; _isCancelled = isCancelled; _grantedPermissions = [grantedPermissions copy]; _declinedPermissions = [declinedPermissions copy]; - }; + } + ; return self; } diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.m index 7ebe1cb63a..dbbe49fa4d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.m @@ -20,13 +20,13 @@ #if !TARGET_OS_TV -#import "FBSDKLoginTooltipView.h" + #import "FBSDKLoginTooltipView.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif @interface FBSDKLoginTooltipView () @end @@ -36,9 +36,13 @@ @implementation FBSDKLoginTooltipView - (instancetype)init { NSString *tooltipMessage = - NSLocalizedStringWithDefaultValue(@"LoginTooltip.Message", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"You're in control - choose what info you want to share with apps.", - @"The message of the FBSDKLoginTooltipView"); + NSLocalizedStringWithDefaultValue( + @"LoginTooltip.Message", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"You're in control - choose what info you want to share with apps.", + @"The message of the FBSDKLoginTooltipView" + ); return [super initWithTagline:nil message:tooltipMessage colorStyle:FBSDKTooltipColorStyleFriendlyBlue]; } @@ -47,7 +51,6 @@ - (void)presentInView:(UIView *)view withArrowPosition:(CGPoint)arrowPosition di if (self.forceDisplay) { [super presentInView:view withArrowPosition:arrowPosition direction:arrowDirection]; } else { - [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) { self.message = serverConfiguration.loginTooltipText; BOOL shouldDisplay = serverConfiguration.loginTooltipEnabled; @@ -67,6 +70,7 @@ - (void)presentInView:(UIView *)view withArrowPosition:(CGPoint)arrowPosition di }]; } } + @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h new file mode 100644 index 0000000000..67783a7cb5 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h @@ -0,0 +1,52 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + Represent a referral code used in the referral process +*/ +NS_SWIFT_NAME(ReferralCode) +@interface FBSDKReferralCode : NSObject + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + The string value of the referral code +*/ +@property NSString *value; + +/** + Initializes a new instance if the referral code is valid. Otherwise returns nil. + A code is valid if it is non-empty and contains only alphanumeric characters. + @param string the raw string referral code +*/ ++ (instancetype)initWithString:(NSString *)string; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m new file mode 100644 index 0000000000..50feb792d6 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m @@ -0,0 +1,64 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKReferralCode.h" + + #import + +@implementation FBSDKReferralCode + ++ (instancetype)initWithString:(NSString *)string +{ + if (string.length == 0) { + return nil; + } + + NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet]; + if (![[string stringByTrimmingCharactersInSet:alphanumericSet] isEqualToString:@""]) { + return nil; + } + + FBSDKReferralCode *instance; + if ((instance = [super new])) { + instance.value = string; + } + return instance; +} + +- (BOOL)isEqual:(id)obj +{ + if (![obj isKindOfClass:[FBSDKReferralCode class]]) { + return NO; + } + + FBSDKReferralCode *other = (FBSDKReferralCode *)obj; + return [self.value isEqual:other.value]; +} + +- (NSString *)description +{ + return self.value; +} + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.h new file mode 100644 index 0000000000..f923d54d79 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.h @@ -0,0 +1,60 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FBSDKReferralManagerResult; + +/** + Describes the call back to the FBSDKReferralManager + @param result the result of the referral + @param error the referral error, if any. + */ +typedef void (^FBSDKReferralManagerResultBlock)(FBSDKReferralManagerResult *_Nullable result, + NSError *_Nullable error) +NS_SWIFT_NAME(ReferralManagerResultBlock); + +/** + `FBSDKReferralManager` provides methods for starting the referral process. +*/ +NS_SWIFT_NAME(ReferralManager) +@interface FBSDKReferralManager : NSObject + +/** + Initialize a new instance with the provided view controller + @param viewController the view controller to present from. If nil, the topmost view controller will be automatically determined as best as possible. + */ +- (instancetype)initWithViewController:(nullable UIViewController *)viewController; + +/** + Open the referral dialog. + @param handler the callback. + */ +-(void)startReferralWithCompletionHandler:(nullable FBSDKReferralManagerResultBlock)handler; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m new file mode 100644 index 0000000000..563dd31b92 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m @@ -0,0 +1,241 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKReferralManager+Internal.h" + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + + #import "FBSDKLoginConstants.h" + #import "FBSDKReferralManagerLogger.h" + #import "FBSDKReferralManagerResult.h" + +static NSString *const FBSDKReferralPath = @"/dialog/share_referral"; +static NSString *const ReferralCodesKey = @"fb_referral_codes"; +static NSString *const ChalllengeKey = @"state"; +static NSString *const SFVCCanceledLogin = @"com.apple.SafariServices.Authentication"; +static NSString *const ASCanceledLogin = @"com.apple.AuthenticationServices.WebAuthenticationSession"; +static int const FBClientStateChallengeLength = 20; + +@implementation FBSDKReferralManager +{ + UIViewController *_viewController; + FBSDKReferralManagerResultBlock _handler; + FBSDKReferralManagerLogger *_logger; + BOOL _isPerformingReferral; + NSString *_expectedChallenge; +} + +- (instancetype)initWithViewController:(UIViewController *)viewController +{ + self = [super init]; + if (self) { + _viewController = viewController; + } + + return self; +} + +- (void)startReferralWithCompletionHandler:(FBSDKReferralManagerResultBlock)handler +{ + _handler = [handler copy]; + _logger = [FBSDKReferralManagerLogger new]; + + [_logger logReferralStart]; + + @try { + [FBSDKInternalUtility validateURLSchemes]; + } @catch (NSException *exception) { + NSError *error = [FBSDKError errorWithCode:FBSDKLoginErrorUnknown + message:[NSString stringWithFormat:@"%@: %@", exception.name, exception.reason]]; + [self handleReferralError:error]; + return; + } + + NSURL *referralURL = [self referralURL]; + if (referralURL) { + void (^completionHandler)(BOOL, NSError *) = ^(BOOL didOpen, NSError *error) { + [self handleOpenURLComplete:didOpen error:error]; + }; + + [[FBSDKBridgeAPI sharedInstance] openURLWithSafariViewController:referralURL + sender:self + fromViewController:_viewController + handler:completionHandler]; + } +} + +- (NSURL *)referralURL +{ + NSError *error; + NSURL *url; + NSMutableDictionary *params = [NSMutableDictionary dictionary]; + + [FBSDKTypeUtility dictionary:params setObject:FBSDKSettings.appID forKey:@"app_id"]; + + _expectedChallenge = [self stringForChallenge]; + [FBSDKTypeUtility dictionary:params setObject:_expectedChallenge forKey:@"state"]; + + NSURL *redirectURL = [FBSDKInternalUtility appURLWithHost:@"authorize" path:@"" queryParameters:@{} error:&error]; + if (!error) { + [FBSDKTypeUtility dictionary:params setObject:redirectURL forKey:@"redirect_uri"]; + + url = [FBSDKInternalUtility facebookURLWithHostPrefix:@"m." + path:FBSDKReferralPath + queryParameters:params + error:&error]; + } + + if (error || !url) { + error = error ?: [FBSDKError errorWithCode:FBSDKLoginErrorUnknown message:@"Failed to construct referral browser url"]; + [self handleReferralError:error]; + return nil; + } + + return url; +} + +- (NSString *)stringForChallenge +{ + NSString *challenge = [FBSDKCrypto randomString:FBClientStateChallengeLength]; + + return [challenge stringByReplacingOccurrencesOfString:@"+" withString:@"="]; +} + +- (void)invokeHandler:(FBSDKReferralManagerResult *)result error:(NSError *)error +{ + _isPerformingReferral = NO; + [_logger logReferralEnd:result error:error]; + _logger = nil; + + if (_handler) { + _handler(result, error); + _handler = nil; + } +} + +- (void)handleReferralCancel +{ + FBSDKReferralManagerResult *result = [[FBSDKReferralManagerResult alloc] initWithReferralCodes:nil isCancelled:YES]; + [self invokeHandler:result error:(NSError *)nil]; +} + +- (void)handleReferralError:(NSError *)error +{ + [self invokeHandler:nil error:error]; +} + +- (void)handleOpenURLComplete:(BOOL)didOpen error:(NSError *)error +{ + if (didOpen) { + self->_isPerformingReferral = YES; + } else if ([error.domain isEqualToString:SFVCCanceledLogin] + || [error.domain isEqualToString:ASCanceledLogin]) { + [self handleReferralCancel]; + } else { + if (!error) { + error = [FBSDKError errorWithCode:FBSDKLoginErrorUnknown message:@"Failed to open referral dialog"]; + } + [self handleReferralError:error]; + } +} + +- (BOOL)validateChallenge:(NSString *)challenge +{ + BOOL challengeValid = YES; + if (_expectedChallenge && ![_expectedChallenge isEqualToString:challenge]) { + challengeValid = NO; + } + + _expectedChallenge = nil; + return challengeValid; +} + + #pragma mark - FBSDKURLOpening + +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + BOOL isFacebookURL = [self canOpenURL:url + forApplication:application + sourceApplication:sourceApplication + annotation:annotation]; + + if (isFacebookURL) { + NSError *error; + NSDictionary *params = [FBSDKInternalUtility dictionaryFromFBURL:url]; + + if (![self validateChallenge:params[ChalllengeKey]]) { + error = [FBSDKError errorWithCode:FBSDKLoginErrorBadChallengeString + message:@"The referral response was missing a valid challenge string"]; + [self handleReferralError:error]; + return YES; + } + + NSString *rawReferralCodes = params[ReferralCodesKey]; + NSArray *referralCodesJSON = [FBSDKCreateJSONFromString(rawReferralCodes, &error) matchArrayOrNil]; + if (!error) { + NSMutableArray *referralCodes = [NSMutableArray array]; + for (FBSDKJSONField *object in referralCodesJSON) { + FBSDKReferralCode *referralCode = [FBSDKReferralCode initWithString:[FBSDKTypeUtility stringValue:[object rawObject]]]; + if (referralCode) { + [FBSDKTypeUtility array:referralCodes addObject:referralCode]; + } + } + + FBSDKReferralManagerResult *result = [[FBSDKReferralManagerResult alloc]initWithReferralCodes:referralCodes isCancelled:NO]; + [self invokeHandler:result error:nil]; + } else { + [self handleReferralError:error]; + } + } else if (_isPerformingReferral) { + [self handleReferralCancel]; + } + + return isFacebookURL; +} + +- (BOOL) canOpenURL:(NSURL *)url + forApplication:(UIApplication *)application + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation +{ + // verify the URL is intended as a callback for the SDK's referral request + return [url.scheme hasPrefix:[NSString stringWithFormat:@"fb%@", FBSDKSettings.appID]] + && [url.host isEqualToString:@"authorize"]; +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + // Do nothing since currently we don't switch to external app +} + +- (BOOL)isAuthenticationURL:(NSURL *)url +{ + return [url.path hasSuffix:FBSDKReferralPath]; +} + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.h new file mode 100644 index 0000000000..8406c3036b --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.h @@ -0,0 +1,59 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + +#import + +#import "FBSDKReferralCode.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Describes the result of a referral request. + */ +NS_SWIFT_NAME(ReferralManagerResult) +@interface FBSDKReferralManagerResult : NSObject + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + whether the referral was cancelled by the user. + */ +@property (readonly, nonatomic) BOOL isCancelled; + +/** + An array of referral codes for each referral made by the user + */ +@property (copy, nonatomic) NSArray *referralCodes; + +/** Initializes a new instance. + @param referralCodes the referral codes + @param isCancelled whether the referral was cancelled by the user + */ +- (instancetype)initWithReferralCodes:(nullable NSArray *)referralCodes + isCancelled:(BOOL)isCancelled +NS_DESIGNATED_INITIALIZER; +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.m new file mode 100644 index 0000000000..50f1abc9fc --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManagerResult.m @@ -0,0 +1,40 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKReferralManagerResult.h" + +@implementation FBSDKReferralManagerResult + +- (instancetype)initWithReferralCodes:(nullable NSArray *)referralCodes + isCancelled:(BOOL)isCancelled +{ + if (self = [super init]) { + _referralCodes = referralCodes; + _isCancelled = isCancelled; + } + ; + return self; +} + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.m index 446ca035d7..8c5884f449 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.m @@ -20,34 +20,34 @@ #if !TARGET_OS_TV -#import "FBSDKTooltipView.h" - -#import - -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif - -static const CGFloat kTransitionDuration = 0.3; -static const CGFloat kZoomOutScale = 0.001f; -static const CGFloat kZoomInScale = 1.1f; -static const CGFloat kZoomBounceScale = 0.98f; - -static const CGFloat kNUXRectInset = 6; -static const CGFloat kNUXBubbleMargin = 17 - kNUXRectInset; -static const CGFloat kNUXPointMargin = -3; -static const CGFloat kNUXCornerRadius = 4; -static const CGFloat kNUXStrokeLineWidth = 0.5f; -static const CGFloat kNUXSideCap = 6; -static const CGFloat kNUXFontSize = 10; -static const CGFloat kNUXCrossGlyphSize = 11; + #import "FBSDKTooltipView.h" + + #import + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + +static const CGFloat kTransitionDuration = 0.3; +static const CGFloat kZoomOutScale = 0.001f; +static const CGFloat kZoomInScale = 1.1f; +static const CGFloat kZoomBounceScale = 0.98f; + +static const CGFloat kNUXRectInset = 6; +static const CGFloat kNUXBubbleMargin = 17 - kNUXRectInset; +static const CGFloat kNUXPointMargin = -3; +static const CGFloat kNUXCornerRadius = 4; +static const CGFloat kNUXStrokeLineWidth = 0.5f; +static const CGFloat kNUXSideCap = 6; +static const CGFloat kNUXFontSize = 10; +static const CGFloat kNUXCrossGlyphSize = 11; static CGMutablePathRef _fbsdkCreateUpPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius); static CGMutablePathRef _fbsdkCreateDownPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius); -#pragma mark - + #pragma mark - @implementation FBSDKTooltipView { @@ -82,12 +82,12 @@ - (instancetype)initWithTagline:(NSString *)tagline message:(NSString *)message _textLabel.backgroundColor = [UIColor clearColor]; _textLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; _textLabel.numberOfLines = 0; - _textLabel.font = [UIFont boldSystemFontOfSize: kNUXFontSize]; + _textLabel.font = [UIFont boldSystemFontOfSize:kNUXFontSize]; _textLabel.textAlignment = NSTextAlignmentLeft; _arrowHeight = 7; _textPadding = 10; _maximumTextWidth = 185; - _verticalCrossOffset = - 2.5f; + _verticalCrossOffset = -2.5f; _verticalTextOffset = 0; _displayDuration = 6.0; self.colorStyle = colorStyle; @@ -117,7 +117,7 @@ - (void)dealloc [_insideTapGestureRecognizer removeTarget:self action:NULL]; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (void)setMessage:(NSString *)message { @@ -135,7 +135,7 @@ - (void)setTagline:(NSString *)tagline } } -#pragma mark Presentation + #pragma mark Presentation - (void)presentFromView:(UIView *)anchorView { @@ -196,7 +196,7 @@ - (void)dismiss }]; } -#pragma mark Style + #pragma mark Style - (FBSDKTooltipColorStyle)colorStyle { @@ -209,29 +209,29 @@ - (void)setColorStyle:(FBSDKTooltipColorStyle)colorStyle switch (colorStyle) { case FBSDKTooltipColorStyleNeutralGray: _gradientColors = @[ - (id)(FBSDKUIColorWithRGB(0x51, 0x50, 0x4f).CGColor), - (id)(FBSDKUIColorWithRGB(0x2d, 0x2c, 0x2c).CGColor) - ]; - _innerStrokeColor = [UIColor colorWithWhite:0.13f alpha:1.0f]; - _crossCloseGlyphColor = [UIColor colorWithWhite:0.69f alpha:1.0f]; - break; + (id)(FBSDKUIColorWithRGB(0x51, 0x50, 0x4f).CGColor), + (id)(FBSDKUIColorWithRGB(0x2d, 0x2c, 0x2c).CGColor) + ]; + _innerStrokeColor = [UIColor colorWithWhite:0.13f alpha:1.0f]; + _crossCloseGlyphColor = [UIColor colorWithWhite:0.69f alpha:1.0f]; + break; case FBSDKTooltipColorStyleFriendlyBlue: default: _gradientColors = @[ - (id)(FBSDKUIColorWithRGB(0x6e, 0x9c, 0xf5).CGColor), - (id)(FBSDKUIColorWithRGB(0x49, 0x74, 0xc6).CGColor) - ]; - _innerStrokeColor = [UIColor colorWithRed:0.12f green:0.26f blue:0.55f alpha:1.0f]; - _crossCloseGlyphColor = [UIColor colorWithRed:0.60f green:0.73f blue:1.0f alpha:1.0f]; - break; + (id)(FBSDKUIColorWithRGB(0x6e, 0x9c, 0xf5).CGColor), + (id)(FBSDKUIColorWithRGB(0x49, 0x74, 0xc6).CGColor) + ]; + _innerStrokeColor = [UIColor colorWithRed:0.12f green:0.26f blue:0.55f alpha:1.0f]; + _crossCloseGlyphColor = [UIColor colorWithRed:0.60f green:0.73f blue:1.0f alpha:1.0f]; + break; } _textLabel.textColor = [UIColor whiteColor]; } -#pragma mark - Private Methods -#pragma mark Animation + #pragma mark - Private Methods + #pragma mark Animation - (void)animateFadeIn { @@ -243,8 +243,10 @@ - (void)animateFadeIn if (_pointingUp) { zoomOffsetY = -zoomOffsetY; } - self.layer.transform = fbsdkdfl_CATransform3DConcat(fbsdkdfl_CATransform3DMakeScale(kZoomOutScale, kZoomOutScale, kZoomOutScale), - fbsdkdfl_CATransform3DMakeTranslation(zoomOffsetX, zoomOffsetY, 0)); + self.layer.transform = fbsdkdfl_CATransform3DConcat( + fbsdkdfl_CATransform3DMakeScale(kZoomOutScale, kZoomOutScale, kZoomOutScale), + fbsdkdfl_CATransform3DMakeTranslation(zoomOffsetX, zoomOffsetY, 0) + ); self.hidden = NO; // Prepare animation steps @@ -259,7 +261,7 @@ - (void)animateFadeIn } CATransform3D scale = fbsdkdfl_CATransform3DMakeScale(kZoomInScale, kZoomInScale, kZoomInScale); - CATransform3D translate =fbsdkdfl_CATransform3DMakeTranslation(newZoomOffsetX, newZoomOffsetY, 0); + CATransform3D translate = fbsdkdfl_CATransform3DMakeTranslation(newZoomOffsetX, newZoomOffsetY, 0); self.layer.transform = fbsdkdfl_CATransform3DConcat(scale, translate); }; @@ -271,8 +273,10 @@ - (void)animateFadeIn if (self->_pointingUp) { zoomOffsetY2 = -zoomOffsetY2; } - self.layer.transform = fbsdkdfl_CATransform3DConcat(fbsdkdfl_CATransform3DMakeScale(kZoomBounceScale, kZoomBounceScale, kZoomBounceScale), - fbsdkdfl_CATransform3DMakeTranslation(zoomOffsetX2, zoomOffsetY2, 0)); + self.layer.transform = fbsdkdfl_CATransform3DConcat( + fbsdkdfl_CATransform3DMakeScale(kZoomBounceScale, kZoomBounceScale, kZoomBounceScale), + fbsdkdfl_CATransform3DMakeTranslation(zoomOffsetX2, zoomOffsetY2, 0) + ); }; // 3rd Step. @@ -281,21 +285,21 @@ - (void)animateFadeIn }; // Animate 3 steps sequentially - [UIView animateWithDuration:kTransitionDuration/1.5 + [UIView animateWithDuration:kTransitionDuration / 1.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:zoomIn completion:^(BOOL finished) { - [UIView animateWithDuration:kTransitionDuration/2.2 + [UIView animateWithDuration:kTransitionDuration / 2.2 animations:bounceZoom completion:^(BOOL innerFinished) { - [UIView animateWithDuration:kTransitionDuration/5 - animations:normalizeZoom]; - }]; + [UIView animateWithDuration:kTransitionDuration / 5 + animations:normalizeZoom]; + }]; }]; } -- (void) animateFadeOutWithCompletion: (void(^)(void)) completionHandler +- (void)animateFadeOutWithCompletion:(void (^)(void))completionHandler { [UIView animateWithDuration:0.3 delay:0 @@ -304,14 +308,15 @@ - (void) animateFadeOutWithCompletion: (void(^)(void)) completionHandler self.alpha = 0.0; } completion:^(BOOL complete) { - if(completionHandler) + if (completionHandler) { completionHandler(); + } }]; } -#pragma mark Gestures + #pragma mark Gestures -- (void)onTapInTooltip:(UIGestureRecognizer*)sender +- (void)onTapInTooltip:(UIGestureRecognizer *)sender { // ignore incomplete tap gestures if (sender.state != UIGestureRecognizerStateEnded) { @@ -322,7 +327,7 @@ - (void)onTapInTooltip:(UIGestureRecognizer*)sender [self dismiss]; } -#pragma mark Drawing + #pragma mark Drawing CGMutablePathRef _fbsdkCreateUpPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius) { @@ -396,17 +401,25 @@ - (void)drawRect:(CGRect)rect CGFloat arrowSideMargin = 1 + 0.5f * MAX(kNUXRectInset, _arrowHeight); CGFloat arrowYMarginOffset = _pointingUp ? arrowSideMargin : kNUXRectInset; CGFloat halfStroke = kNUXStrokeLineWidth / 2.0; - CGRect outerRect = CGRectMake(kNUXRectInset + halfStroke, - arrowYMarginOffset + halfStroke, - self.bounds.size.width - 2 * kNUXRectInset - kNUXStrokeLineWidth, - self.bounds.size.height - kNUXRectInset - arrowSideMargin - kNUXStrokeLineWidth); + CGRect outerRect = CGRectMake( + kNUXRectInset + halfStroke, + arrowYMarginOffset + halfStroke, + self.bounds.size.width - 2 * kNUXRectInset - kNUXStrokeLineWidth, + self.bounds.size.height - kNUXRectInset - arrowSideMargin - kNUXStrokeLineWidth + ); outerRect = CGRectInset(outerRect, 5, 5); CGRect innerRect = CGRectInset(outerRect, kNUXStrokeLineWidth, kNUXStrokeLineWidth); - CGRect fillRect = CGRectInset(innerRect, kNUXStrokeLineWidth/2.0, kNUXStrokeLineWidth/2.0); - CGFloat closeCrossGlyphPositionY = MIN(CGRectGetMinY(fillRect) + _textPadding + _verticalCrossOffset, - CGRectGetMidY(fillRect) - 0.5f * kNUXCrossGlyphSize); - CGRect closeCrossGlyphRect = CGRectMake(CGRectGetMaxX(fillRect) - 2 * kNUXFontSize, closeCrossGlyphPositionY, - kNUXCrossGlyphSize, kNUXCrossGlyphSize); + CGRect fillRect = CGRectInset(innerRect, kNUXStrokeLineWidth / 2.0, kNUXStrokeLineWidth / 2.0); + CGFloat closeCrossGlyphPositionY = MIN( + CGRectGetMinY(fillRect) + _textPadding + _verticalCrossOffset, + CGRectGetMidY(fillRect) - 0.5f * kNUXCrossGlyphSize + ); + CGRect closeCrossGlyphRect = CGRectMake( + CGRectGetMaxX(fillRect) - 2 * kNUXFontSize, + closeCrossGlyphPositionY, + kNUXCrossGlyphSize, + kNUXCrossGlyphSize + ); // setup and get paths CGContextRef context = UIGraphicsGetCurrentContext(); @@ -416,27 +429,45 @@ - (void)drawRect:(CGRect)rect CGMutablePathRef crossCloseGlyphPath = _createCloseCrossGlyphWithRect(closeCrossGlyphRect); CGRect gradientRect = fillRect; if (_pointingUp) { - outerPath = _fbsdkCreateUpPointingBubbleWithRect(outerRect, - _arrowMidpoint, _arrowHeight, - kNUXCornerRadius + kNUXStrokeLineWidth); - innerPath = _fbsdkCreateUpPointingBubbleWithRect(innerRect, - _arrowMidpoint, _arrowHeight, - kNUXCornerRadius); - fillPath = _fbsdkCreateUpPointingBubbleWithRect(fillRect, - _arrowMidpoint, _arrowHeight, - kNUXCornerRadius - kNUXStrokeLineWidth); + outerPath = _fbsdkCreateUpPointingBubbleWithRect( + outerRect, + _arrowMidpoint, + _arrowHeight, + kNUXCornerRadius + kNUXStrokeLineWidth + ); + innerPath = _fbsdkCreateUpPointingBubbleWithRect( + innerRect, + _arrowMidpoint, + _arrowHeight, + kNUXCornerRadius + ); + fillPath = _fbsdkCreateUpPointingBubbleWithRect( + fillRect, + _arrowMidpoint, + _arrowHeight, + kNUXCornerRadius - kNUXStrokeLineWidth + ); gradientRect.origin.y -= _arrowHeight; gradientRect.size.height += _arrowHeight; } else { - outerPath = _fbsdkCreateDownPointingBubbleWithRect(outerRect, - _arrowMidpoint, _arrowHeight, - kNUXCornerRadius + kNUXStrokeLineWidth); - innerPath = _fbsdkCreateDownPointingBubbleWithRect(innerRect, - _arrowMidpoint, _arrowHeight, - kNUXCornerRadius); - fillPath = _fbsdkCreateDownPointingBubbleWithRect(fillRect, - _arrowMidpoint, _arrowHeight, - kNUXCornerRadius - kNUXStrokeLineWidth); + outerPath = _fbsdkCreateDownPointingBubbleWithRect( + outerRect, + _arrowMidpoint, + _arrowHeight, + kNUXCornerRadius + kNUXStrokeLineWidth + ); + innerPath = _fbsdkCreateDownPointingBubbleWithRect( + innerRect, + _arrowMidpoint, + _arrowHeight, + kNUXCornerRadius + ); + fillPath = _fbsdkCreateDownPointingBubbleWithRect( + fillRect, + _arrowMidpoint, + _arrowHeight, + kNUXCornerRadius - kNUXStrokeLineWidth + ); gradientRect.size.height += _arrowHeight; } self.layer.shadowPath = outerPath; @@ -467,7 +498,7 @@ - (void)drawRect:(CGRect)rect CFRelease(crossCloseGlyphPath); } -#pragma mark Layout + #pragma mark Layout - (void)layoutSubviews { @@ -478,8 +509,8 @@ - (void)layoutSubviews [self layoutSubviewsAndDetermineFrame]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (CGRect)layoutSubviewsAndDetermineFrame { // Compute the positioning of the arrow. @@ -501,10 +532,12 @@ - (CGRect)layoutSubviewsAndDetermineFrame CGFloat yPos = arrowYMarginOffset + kNUXStrokeLineWidth + _textPadding; // Set the text label frame. - _textLabel.frame = CGRectMake(xPos, - yPos + _verticalTextOffset, // sizing function may not return desired height exactly - CGRectGetWidth(_textLabel.bounds), - CGRectGetHeight(_textLabel.bounds)); + _textLabel.frame = CGRectMake( + xPos, + yPos + _verticalTextOffset, // sizing function may not return desired height exactly + CGRectGetWidth(_textLabel.bounds), + CGRectGetHeight(_textLabel.bounds) + ); // Determine the size of the nux bubble. CGFloat bubbleHeight = CGRectGetHeight(_textLabel.bounds) + _verticalTextOffset + _textPadding * 2; @@ -539,34 +572,38 @@ - (CGRect)layoutSubviewsAndDetermineFrame yOrigin = _positionInView.y - nuxHeight - kNUXPointMargin + MAX(0, kNUXRectInset - _arrowHeight); } - return CGRectMake(originX - kNUXRectInset, - yOrigin, - nuxWidth, - nuxHeight); + return CGRectMake( + originX - kNUXRectInset, + yOrigin, + nuxWidth, + nuxHeight + ); } -#pragma clang diagnostic pop -#pragma mark Message & Tagline + #pragma clang diagnostic pop + + #pragma mark Message & Tagline - (void)setMessage:(NSString *)message tagline:(NSString *)tagline { message = message ?: @""; // Ensure tagline is empty string or ends with space tagline = tagline ?: @""; - if (tagline.length && ![tagline hasSuffix:@" "]) + if (tagline.length && ![tagline hasSuffix:@" "]) { tagline = [tagline stringByAppendingString:@" "]; + } // Concatenate tagline & main message message = [tagline stringByAppendingString:message]; NSRange fullRange = NSMakeRange(0, message.length); - NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString: message]; + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:message]; - UIFont *font=[UIFont boldSystemFontOfSize:kNUXFontSize]; + UIFont *font = [UIFont boldSystemFontOfSize:kNUXFontSize]; [attrString addAttribute:NSFontAttributeName value:font range:fullRange]; [attrString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:fullRange]; if (tagline.length) { - [attrString addAttribute:NSForegroundColorAttributeName value: FBSDKUIColorWithRGB(0x6D, 0x87, 0xC7) range:NSMakeRange(0, tagline.length)]; + [attrString addAttribute:NSForegroundColorAttributeName value:FBSDKUIColorWithRGB(0x6D, 0x87, 0xC7) range:NSMakeRange(0, tagline.length)]; } _textLabel.attributedText = attrString; @@ -577,7 +614,7 @@ - (void)setMessage:(NSString *)message tagline:(NSString *)tagline [self setNeedsDisplay]; } -#pragma mark Auto Dismiss Timeout + #pragma mark Auto Dismiss Timeout - (void)scheduleAutomaticFadeout { diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKDeviceLoginManagerResult+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKDeviceLoginManagerResult+Internal.h index a3b683c191..986c07363b 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKDeviceLoginManagerResult+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKDeviceLoginManagerResult+Internal.h @@ -19,7 +19,7 @@ #import #if defined BUCK || defined FBSDKCOCOAPODS -#import + #import #else @import FBSDKCoreKit; #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h index 118407a21c..1ce89f7fc9 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKLoginCompletion.h" + #import "FBSDKLoginCompletion.h" @interface FBSDKLoginCompletionParameters () @@ -45,4 +45,12 @@ @end +@interface FBSDKLoginURLCompleter () + +@property (nonatomic, strong) FBSDKLoginCompletionParameters *parameters; + +- (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler; + +@end + #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 7db05098b2..8be484dc4d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -20,23 +20,23 @@ #if !TARGET_OS_TV -#import "FBSDKLoginCompletion+Internal.h" + #import "FBSDKLoginCompletion+Internal.h" -#if SWIFT_PACKAGE + #if SWIFT_PACKAGE @import FBSDKCoreKit; -#else -#import -#endif + #else + #import + #endif -#import "FBSDKLoginConstants.h" -#import "FBSDKLoginError.h" -#import "FBSDKLoginManager+Internal.h" -#import "FBSDKLoginUtility.h" + #import "FBSDKLoginConstants.h" + #import "FBSDKLoginError.h" + #import "FBSDKLoginManager+Internal.h" + #import "FBSDKLoginUtility.h" -static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *parameters, void(^completionBlock)(void)) +static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *parameters, void (^completionBlock)(void)) { __block NSUInteger pendingCount = 1; - void(^didCompleteBlock)(void) = ^{ + void (^didCompleteBlock)(void) = ^{ if (--pendingCount == 0) { completionBlock(); } @@ -55,16 +55,16 @@ static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *pa [connection addRequest:userIDRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *error) { - parameters.userID = result[@"id"]; - if (error) { - parameters.error = error; - } - didCompleteBlock(); - }]; + parameters.userID = result[@"id"]; + if (error) { + parameters.error = error; + } + didCompleteBlock(); + }]; pendingCount++; FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/permissions" - parameters:@{@"fields":@""} + parameters:@{@"fields" : @""} tokenString:tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -72,23 +72,23 @@ static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *pa [connection addRequest:permissionsRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *error) { - NSMutableSet *grantedPermissions = [NSMutableSet set]; - NSMutableSet *declinedPermissions = [NSMutableSet set]; - NSMutableSet *expiredPermissions = [NSMutableSet set]; - - [FBSDKInternalUtility extractPermissionsFromResponse:result - grantedPermissions:grantedPermissions - declinedPermissions:declinedPermissions - expiredPermissions:expiredPermissions]; - - parameters.permissions = [grantedPermissions copy]; - parameters.declinedPermissions = [declinedPermissions copy]; - parameters.expiredPermissions = [expiredPermissions copy]; - if (error) { - parameters.error = error; - } - didCompleteBlock(); - }]; + NSMutableSet *grantedPermissions = [NSMutableSet set]; + NSMutableSet *declinedPermissions = [NSMutableSet set]; + NSMutableSet *expiredPermissions = [NSMutableSet set]; + + [FBSDKInternalUtility extractPermissionsFromResponse:result + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions]; + + parameters.permissions = [grantedPermissions copy]; + parameters.declinedPermissions = [declinedPermissions copy]; + parameters.expiredPermissions = [expiredPermissions copy]; + if (error) { + parameters.error = error; + } + didCompleteBlock(); + }]; [connection start]; didCompleteBlock(); @@ -111,7 +111,7 @@ - (instancetype)initWithError:(NSError *)error @end -#pragma mark - Completers + #pragma mark - Completers @implementation FBSDKLoginURLCompleter { @@ -141,10 +141,10 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler { if (_parameters.nonceString) { - [self _exchangeNonceForTokenWithHandler:handler]; + [self exchangeNonceForTokenWithHandler:handler]; return; } else if (_parameters.accessTokenString && !_parameters.userID) { - void(^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; + void (^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; FBSDKLoginRequestMeAndPermissions(_parameters, ^{ handlerCopy(self->_parameters); }); @@ -207,8 +207,8 @@ - (void)setErrorWithDictionary:(NSDictionary *)parameters { NSString *legacyErrorReason = parameters[@"error"]; - if ([legacyErrorReason isEqualToString:@"service_disabled_use_browser"] || - [legacyErrorReason isEqualToString:@"service_disabled"]) { + if ([legacyErrorReason isEqualToString:@"service_disabled_use_browser"] + || [legacyErrorReason isEqualToString:@"service_disabled"]) { _performExplicitFallback = YES; } @@ -217,7 +217,8 @@ - (void)setErrorWithDictionary:(NSDictionary *)parameters _parameters.error = [NSError fbErrorFromReturnURLParameters:parameters]; } -- (void)attemptBrowserLogIn:(FBSDKLoginManager *)loginManager { +- (void)attemptBrowserLogIn:(FBSDKLoginManager *)loginManager +{ if (_observer != nil) { [[NSNotificationCenter defaultCenter] removeObserver:_observer]; _observer = nil; @@ -234,10 +235,10 @@ - (void)attemptBrowserLogIn:(FBSDKLoginManager *)loginManager { } } -- (void)_exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler +- (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler { if (!handler) { - return; + return; } NSString *nonce = _parameters.nonceString ?: @""; @@ -257,31 +258,31 @@ - (void)_exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)h @"fb_exchange_nonce" : nonce, @"client_id" : appID, @"fields" : @"" } - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | - FBSDKGraphRequestFlagDisableErrorRecovery]; + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError + | FBSDKGraphRequestFlagDisableErrorRecovery]; __block FBSDKLoginCompletionParameters *parameters = _parameters; [connection addRequest:tokenRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *error) { - if (!error) { - parameters.accessTokenString = result[@"access_token"]; - NSDate *expirationDate = [NSDate distantFuture]; - if (result[@"expires_in"] && [result[@"expires_in"] integerValue] > 0) { - expirationDate = [NSDate dateWithTimeIntervalSinceNow:[result[@"expires_in"] integerValue]]; - } - parameters.expirationDate = expirationDate; - - NSDate *dataAccessExpirationDate = [NSDate distantFuture]; - if (result[@"data_access_expiration_time"] && [result[@"data_access_expiration_time"] integerValue] > 0) { - dataAccessExpirationDate = [NSDate dateWithTimeIntervalSince1970:[result[@"data_access_expiration_time"] integerValue]]; - } - parameters.dataAccessExpirationDate = dataAccessExpirationDate; - } else { - parameters.error = error; - } - - handler(parameters); - }]; + if (!error) { + parameters.accessTokenString = result[@"access_token"]; + NSDate *expirationDate = [NSDate distantFuture]; + if (result[@"expires_in"] && [result[@"expires_in"] integerValue] > 0) { + expirationDate = [NSDate dateWithTimeIntervalSinceNow:[result[@"expires_in"] integerValue]]; + } + parameters.expirationDate = expirationDate; + + NSDate *dataAccessExpirationDate = [NSDate distantFuture]; + if (result[@"data_access_expiration_time"] && [result[@"data_access_expiration_time"] integerValue] > 0) { + dataAccessExpirationDate = [NSDate dateWithTimeIntervalSince1970:[result[@"data_access_expiration_time"] integerValue]]; + } + parameters.dataAccessExpirationDate = dataAccessExpirationDate; + } else { + parameters.error = error; + } + + handler(parameters); + }]; [connection start]; } diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.h index af51ee7f9e..1659a17814 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.h @@ -20,9 +20,13 @@ #if !TARGET_OS_TV -#import + #import -#import "FBSDKLoginConstants.h" + #if SWIFT_PACKAGE + #import "FBSDKLoginConstants.h" + #else + #import + #endif NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m index 34c2f2e655..21588573f8 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m @@ -20,19 +20,19 @@ #if !TARGET_OS_TV -#import "FBSDKLoginError.h" + #import "FBSDKLoginError.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif -#ifndef NS_ERROR_ENUM -#define NS_ERROR_ENUM(_domain, _name) \ -enum _name: NSInteger _name; \ -enum __attribute__((ns_error_domain(_domain))) _name: NSInteger -#endif + #ifndef NS_ERROR_ENUM + #define NS_ERROR_ENUM(_domain, _name) \ + enum _name : NSInteger _name; \ + enum __attribute__((ns_error_domain(_domain))) _name: NSInteger + #endif typedef NS_ERROR_ENUM(FBSDKLoginErrorDomain, FBSDKLoginErrorSubcode) { @@ -62,33 +62,53 @@ + (NSError *)fbErrorForFailedLoginWithCode:(FBSDKLoginError)code case FBSDKErrorNetwork: errorDomain = FBSDKErrorDomain; localizedDescription = - NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Network", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Unable to connect to Facebook. Check your network connection and try again.", - @"The user facing error message when the Accounts framework encounters a network error."); + NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.Network", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Unable to connect to Facebook. Check your network connection and try again.", + @"The user facing error message when the Accounts framework encounters a network error." + ); break; case FBSDKLoginErrorUserCheckpointed: localizedDescription = - NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.UserCheckpointed", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"You cannot log in to apps at this time. Please log in to www.facebook.com and follow the instructions given.", - @"The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed."); + NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.UserCheckpointed", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"You cannot log in to apps at this time. Please log in to www.facebook.com and follow the instructions given.", + @"The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed." + ); break; case FBSDKLoginErrorUnconfirmedUser: localizedDescription = - NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.UnconfirmedUser", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Your account is not confirmed. Please log in to www.facebook.com and follow the instructions given.", - @"The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed."); + NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.UnconfirmedUser", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Your account is not confirmed. Please log in to www.facebook.com and follow the instructions given.", + @"The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed." + ); break; case FBSDKLoginErrorSystemAccountAppDisabled: localizedDescription = - NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Disabled", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Access has not been granted to the Facebook account. Verify device settings.", - @"The user facing error message when the app slider has been disabled and login fails."); + NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.Disabled", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Access has not been granted to the Facebook account. Verify device settings.", + @"The user facing error message when the app slider has been disabled and login fails." + ); break; case FBSDKLoginErrorSystemAccountUnavailable: localizedDescription = - NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Unavailable", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"The Facebook account has not been configured on the device.", - @"The user facing error message when the device Facebook account is unavailable and login fails."); + NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.Unavailable", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"The Facebook account has not been configured on the device.", + @"The user facing error message when the device Facebook account is unavailable and login fails." + ); break; default: break; @@ -105,9 +125,13 @@ + (NSError *)fbErrorForFailedLoginWithCode:(FBSDKLoginError)code + (NSError *)fbErrorForSystemPasswordChange:(NSError *)innerError { NSString *failureReasonAndDescription = - NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.PasswordChange", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Your Facebook password has changed. To confirm your password, open Settings > Facebook and tap your name.", - @"The user facing error message when the device Facebook account password is incorrect and login fails."); + NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.PasswordChange", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Your Facebook password has changed. To confirm your password, open Settings > Facebook and tap your name.", + @"The user facing error message when the device Facebook account password is incorrect and login fails." + ); NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: failureReasonAndDescription, FBSDKErrorLocalizedDescriptionKey, failureReasonAndDescription, NSLocalizedDescriptionKey, @@ -193,8 +217,8 @@ + (NSError *)fbErrorWithSystemAccountStoreDeniedError:(NSError *)accountStoreErr // The OAuth endpoint directs people to www.facebook.com when an account has been // checkpointed. If the web address is present, assume it's due to a checkpoint. errorCode = FBSDKLoginErrorUserCheckpointed; - } else if ([description rangeOfString:@"(452)"].location != NSNotFound || - [description rangeOfString:@"(460)"].location != NSNotFound) { + } else if ([description rangeOfString:@"(452)"].location != NSNotFound + || [description rangeOfString:@"(460)"].location != NSNotFound) { // The Facebook server could not fulfill this access request: Error validating access token: // Session does not match current stored session. This may be because the user changed the password since // the time the session was created or Facebook has changed the session for security reasons. (452)or(460) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h index a94b7cdc82..313c9d4e37 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h @@ -17,7 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "../FBSDKLoginKit.h" - #import "FBSDKLoginCompletion+Internal.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h index cc05176e03..d24c9b03e6 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h @@ -28,10 +28,15 @@ #import "FBSDKCoreKit+Internal.h" #endif +#if SWIFT_PACKAGE #import "FBSDKLoginManager.h" +#else +#import +#endif @class FBSDKAccessToken; @class FBSDKLoginCompletionParameters; +@class FBSDKLoginManagerLogger; /** Success Block @@ -39,9 +44,20 @@ typedef void (^FBSDKBrowserLoginSuccessBlock)(BOOL didOpen, NSError *error) NS_SWIFT_NAME(BrowserLoginSuccessBlock); +typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { + FBSDKLoginManagerStateIdle, + // We received a call to start login. + FBSDKLoginManagerStateStart, + // We're calling out to the Facebook app or Safari to perform a log in + FBSDKLoginManagerStatePerformingLogin, +}; + @interface FBSDKLoginManager () @property (nonatomic, weak) UIViewController *fromViewController; @property (nonatomic, readonly) NSSet *requestedPermissions; +@property (nonatomic, strong) FBSDKLoginManagerLogger *logger; +@property (nonatomic) FBSDKLoginManagerState state; +@property (nonatomic) BOOL usedSFAuthSession; // for testing only @property (nonatomic, readonly, copy) NSString *loadExpectedChallenge; @@ -64,6 +80,14 @@ NS_SWIFT_NAME(BrowserLoginSuccessBlock); // for testing only - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams handler:(FBSDKBrowserLoginSuccessBlock)handler; +// available to internal modules +- (void)handleImplicitCancelOfLogIn; +- (void)invokeHandler:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error; +- (BOOL)validateLoginStartState; +- (BOOL)isPerformingLogin; ++ (NSString *)stringForChallenge; +- (void)storeExpectedChallenge:(NSString *)expectedChallenge; + @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h index 5c2ea0947e..1ce4ddffb2 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h @@ -25,6 +25,7 @@ FOUNDATION_EXPORT NSString *const FBSDKLoginManagerLoggerAuthMethod_Native; FOUNDATION_EXPORT NSString *const FBSDKLoginManagerLoggerAuthMethod_Browser; FOUNDATION_EXPORT NSString *const FBSDKLoginManagerLoggerAuthMethod_SFVC; +FOUNDATION_EXPORT NSString *const FBSDKLoginManagerLoggerAuthMethod_Applink; NS_SWIFT_NAME(LoginManagerLogger) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m index e45f61771f..ecfcc5fdb1 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m @@ -20,20 +20,21 @@ #if !TARGET_OS_TV -#import "FBSDKLoginManagerLogger.h" + #import "FBSDKLoginManagerLogger.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKLoginError.h" -#import "FBSDKLoginManagerLoginResult+Internal.h" -#import "FBSDKLoginUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKLoginError.h" + #import "FBSDKLoginManagerLoginResult+Internal.h" + #import "FBSDKLoginUtility.h" NSString *const FBSDKLoginManagerLoggerAuthMethod_Native = @"fb_application_web_auth"; NSString *const FBSDKLoginManagerLoggerAuthMethod_Browser = @"browser_auth"; NSString *const FBSDKLoginManagerLoggerAuthMethod_SFVC = @"sfvc_auth"; +NSString *const FBSDKLoginManagerLoggerAuthMethod_Applink = @"applink_auth"; static NSString *const FBSDKLoginManagerLoggingClientStateKey = @"state"; static NSString *const FBSDKLoginManagerLoggingClientStateIsClientState = @"com.facebook.sdk_client_state"; @@ -59,7 +60,7 @@ @implementation FBSDKLoginManagerLogger { -@private + @private NSString *_identifier; NSMutableDictionary *_extras; @@ -105,20 +106,20 @@ - (void)startSessionForLoginManager:(FBSDKLoginManager *)loginManager NSString *behaviorString = @"FBSDKLoginBehaviorBrowser"; [_extras addEntriesFromDictionary:@{ - FBSDKLoginManagerLoggerTryNative : @(willTryNative), - FBSDKLoginManagerLoggerTryBrowser : @(willTryBrowser), - @"isReauthorize" : @(isReauthorize), - @"login_behavior" : behaviorString, - @"default_audience" : [FBSDKLoginUtility stringForAudience:loginManager.defaultAudience], - @"permissions" : [loginManager.requestedPermissions.allObjects componentsJoinedByString:@","] ?: @"" - }]; + FBSDKLoginManagerLoggerTryNative : @(willTryNative), + FBSDKLoginManagerLoggerTryBrowser : @(willTryBrowser), + @"isReauthorize" : @(isReauthorize), + @"login_behavior" : behaviorString, + @"default_audience" : [FBSDKLoginUtility stringForAudience:loginManager.defaultAudience], + @"permissions" : [loginManager.requestedPermissions.allObjects componentsJoinedByString:@","] ?: @"" + }]; [self logEvent:FBSDKAppEventNameFBSessionAuthStart params:[self _parametersForNewEvent]]; } - (void)endSession { - [self logEvent:FBSDKAppEventNameFBSessionAuthEnd result:_lastResult error:_lastError]; + [self logEvent:FBSDKAppEventNameFBSessionAuthEnd result:_lastResult error:_lastError]; } - (void)startAuthMethod:(NSString *)authMethod @@ -157,8 +158,8 @@ - (NSDictionary *)parametersWithTimeStampAndClientState:(NSDictionary *)loginPar NSTimeInterval timeValue = (NSTimeInterval)FBSDKMonotonicTimeGetCurrentSeconds(); NSString *e2eTimestampString = [FBSDKBasicUtility JSONStringForObject:@{ @"init" : @(timeValue) } - error:NULL - invalidObjectHandler:NULL]; + error:NULL + invalidObjectHandler:NULL]; [FBSDKTypeUtility dictionary:params setObject:e2eTimestampString forKey:@"e2e"]; NSDictionary *existingState = [FBSDKBasicUtility objectForJSONString:params[FBSDKLoginManagerLoggingClientStateKey] error:NULL]; @@ -176,10 +177,10 @@ - (void)willAttemptAppSwitchingBehavior BOOL isMessengerAppCanOpenURLSchemeRegistered = [FBSDKInternalUtility isRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MESSENGER]; [_extras addEntriesFromDictionary:@{ - @"isURLSchemeRegistered" : @(isURLSchemeRegistered), - @"isFacebookAppCanOpenURLSchemeRegistered" : @(isFacebookAppCanOpenURLSchemeRegistered), - @"isMessengerAppCanOpenURLSchemeRegistered" : @(isMessengerAppCanOpenURLSchemeRegistered), - }]; + @"isURLSchemeRegistered" : @(isURLSchemeRegistered), + @"isFacebookAppCanOpenURLSchemeRegistered" : @(isFacebookAppCanOpenURLSchemeRegistered), + @"isMessengerAppCanOpenURLSchemeRegistered" : @(isMessengerAppCanOpenURLSchemeRegistered), + }]; } - (void)logNativeAppDialogResult:(BOOL)result dialogDuration:(NSTimeInterval)dialogDuration @@ -192,14 +193,14 @@ - (void)logNativeAppDialogResult:(BOOL)result dialogDuration:(NSTimeInterval)dia } } -#pragma mark - Private + #pragma mark - Private - (NSString *)clientStateForAuthMethod:(NSString *)authMethod andExistingState:(NSDictionary *)existingState { NSDictionary *clientState = @{ - FBSDKLoginManagerLoggerParamAuthMethodKey: authMethod ?: @"", - FBSDKLoginManagerLoggerParamIdentifierKey: _identifier, - FBSDKLoginManagerLoggingClientStateIsClientState: @YES, + FBSDKLoginManagerLoggerParamAuthMethodKey : authMethod ?: @"", + FBSDKLoginManagerLoggerParamIdentifierKey : _identifier, + FBSDKLoginManagerLoggingClientStateIsClientState : @YES, }; if (existingState) { @@ -213,29 +214,29 @@ - (NSString *)clientStateForAuthMethod:(NSString *)authMethod andExistingState:( - (NSMutableDictionary *)_parametersForNewEvent { - NSMutableDictionary *eventParameters = [[NSMutableDictionary alloc] init]; - - // NOTE: We ALWAYS add all params to each event, to ensure predictable mapping on the backend. - [FBSDKTypeUtility dictionary:eventParameters setObject:_identifier ?: FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamIdentifierKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:@(round(1000 * [NSDate date].timeIntervalSince1970)) forKey:FBSDKLoginManagerLoggerParamTimestampKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamResultKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:_authMethod forKey:FBSDKLoginManagerLoggerParamAuthMethodKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamErrorCodeKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamErrorMessageKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamExtrasKey]; - [FBSDKTypeUtility dictionary:eventParameters setObject:_loggingToken ?: FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamLoggingTokenKey]; - - return eventParameters; + NSMutableDictionary *eventParameters = [[NSMutableDictionary alloc] init]; + + // NOTE: We ALWAYS add all params to each event, to ensure predictable mapping on the backend. + [FBSDKTypeUtility dictionary:eventParameters setObject:_identifier ?: FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamIdentifierKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:@(round(1000 * [NSDate date].timeIntervalSince1970)) forKey:FBSDKLoginManagerLoggerParamTimestampKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamResultKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:_authMethod forKey:FBSDKLoginManagerLoggerParamAuthMethodKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamErrorCodeKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamErrorMessageKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamExtrasKey]; + [FBSDKTypeUtility dictionary:eventParameters setObject:_loggingToken ?: FBSDKLoginManagerLoggerValueEmpty forKey:FBSDKLoginManagerLoggerParamLoggingTokenKey]; + + return eventParameters; } - (void)logEvent:(NSString *)eventName params:(NSMutableDictionary *)params { if (_identifier) { NSString *extrasJSONString = [FBSDKBasicUtility JSONStringForObject:_extras - error:NULL - invalidObjectHandler:NULL]; + error:NULL + invalidObjectHandler:NULL]; if (extrasJSONString) { - [FBSDKTypeUtility dictionary:params setObject:extrasJSONString forKey:FBSDKLoginManagerLoggerParamExtrasKey]; + [FBSDKTypeUtility dictionary:params setObject:extrasJSONString forKey:FBSDKLoginManagerLoggerParamExtrasKey]; } [_extras removeAllObjects]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLoginResult+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLoginResult+Internal.h index 18dd7cef1b..1935c6707c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLoginResult+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLoginResult+Internal.h @@ -20,11 +20,11 @@ #if !TARGET_OS_TV -#import + #import -#import "FBSDKLoginManagerLoginResult.h" + #import "FBSDKLoginManagerLoginResult.h" -@interface FBSDKLoginManagerLoginResult() +@interface FBSDKLoginManagerLoginResult () @property (nonatomic, readonly) NSDictionary *loggingExtras; @@ -32,7 +32,7 @@ @property (nonatomic, assign) BOOL isSkipped; // adds additional logging entry to extras - only sent as part of `endLoginWithResult:` --(void)addLoggingExtra:(id)object forKey:(id)key; +- (void)addLoggingExtra:(id)object forKey:(id)key; @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.h index 440f651efc..c397975c91 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.h @@ -22,7 +22,11 @@ #import -#import "FBSDKLoginManager.h" +#if SWIFT_PACKAGE + #import "FBSDKLoginManager.h" +#else + #import +#endif NS_SWIFT_NAME(LoginUtility) @interface FBSDKLoginUtility : NSObject diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m index f403b3336b..578db9154a 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m @@ -20,20 +20,20 @@ #if !TARGET_OS_TV -#import "FBSDKLoginUtility.h" + #import "FBSDKLoginUtility.h" -#if SWIFT_PACKAGE + #if SWIFT_PACKAGE @import FBSDKCoreKit; -#else -#import -#endif + #else + #import + #endif -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKLoginConstants.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKLoginConstants.h" @implementation FBSDKLoginUtility diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h new file mode 100644 index 0000000000..7d0311783d --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h @@ -0,0 +1,35 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKReferralManager.h" + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + +@interface FBSDKReferralManager () + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.h new file mode 100644 index 0000000000..48fa93b26f --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.h @@ -0,0 +1,34 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + +#import "FBSDKReferralManager+Internal.h" + +NS_SWIFT_NAME(ReferralManagerLogger) +@interface FBSDKReferralManagerLogger : NSObject + +- (void)logReferralStart; + +- (void)logReferralEnd:(FBSDKReferralManagerResult *)result error:(NSError *)error; + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.m new file mode 100644 index 0000000000..2d084dc030 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManagerLogger.m @@ -0,0 +1,174 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKReferralManagerLogger.h" + + #import "FBSDKLoginConstants.h" + #import "FBSDKReferralManagerResult.h" + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + +static NSString *const FBSDKReferralManagerLoggerParamIdentifierKey = @"0_logger_id"; +static NSString *const FBSDKReferralManagerLoggerParamTimestampKey = @"1_timestamp_ms"; +static NSString *const FBSDKReferralManagerLoggerParamResultKey = @"2_result"; +static NSString *const FBSDKReferralManagerLoggerParamErrorCodeKey = @"3_error_code"; +static NSString *const FBSDKReferralManagerLoggerParamErrorMessageKey = @"4_error_message"; +static NSString *const FBSDKReferralManagerLoggerParamExtrasKey = @"5_extras"; +static NSString *const FBSDKReferralManagerLoggerParamLoggingTokenKey = @"6_logging_token"; + +static NSString *const FBSDKReferralManagerLoggerValueEmpty = @""; + +static NSString *const FBSDKReferralManagerLoggerResultSuccessString = @"success"; +static NSString *const FBSDKReferralManagerLoggerResultCancelString = @"cancelled"; +static NSString *const FBSDKReferralManagerLoggerResultErrorString = @"error"; + +@implementation FBSDKReferralManagerLogger +{ + @private + NSString *_identifier; + NSMutableDictionary *_extras; + NSString *_loggingToken; +} + +- (instancetype)init +{ + if (self = [super init]) { + FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; + NSString *loggingToken = serverConfiguration.loggingToken; + _identifier = [NSUUID UUID].UUIDString; + _extras = [NSMutableDictionary dictionary]; + _loggingToken = [loggingToken copy]; + } + return self; +} + +- (void)logReferralStart +{ + [self logEvent:FBSDKAppEventNameFBReferralStart params:[self _parametersForNewEvent]]; +} + +- (void)logReferralEnd:(FBSDKReferralManagerResult *)result error:(NSError *)error +{ + NSString *resultString = FBSDKReferralManagerLoggerValueEmpty; + + if (error != nil) { + resultString = FBSDKReferralManagerLoggerResultErrorString; + } else if (result.isCancelled) { + resultString = FBSDKReferralManagerLoggerResultCancelString; + } else if (result.referralCodes) { + resultString = FBSDKReferralManagerLoggerResultSuccessString; + } + + NSMutableDictionary *params = [self _parametersForNewEvent]; + [FBSDKTypeUtility dictionary:params setObject:resultString forKey:FBSDKReferralManagerLoggerParamResultKey]; + + if ([error.domain isEqualToString:FBSDKErrorDomain] || [error.domain isEqualToString:FBSDKLoginErrorDomain]) { + NSString *errorMessage = error.userInfo[@"error_message"] ?: error.userInfo[FBSDKErrorLocalizedDescriptionKey]; + [FBSDKTypeUtility dictionary:params + setObject:errorMessage + forKey:FBSDKReferralManagerLoggerParamErrorMessageKey]; + + NSString *errorCode = error.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] ?: [NSString stringWithFormat:@"%ld", (long)error.code]; + [FBSDKTypeUtility dictionary:params + setObject:errorCode + forKey:FBSDKReferralManagerLoggerParamErrorCodeKey]; + + NSError *innerError = error.userInfo[NSUnderlyingErrorKey]; + if (innerError != nil) { + NSString *innerErrorMessage = innerError.userInfo[@"error_message"] ?: innerError.userInfo[NSLocalizedDescriptionKey]; + [FBSDKTypeUtility dictionary:_extras + setObject:innerErrorMessage + forKey:@"inner_error_message"]; + + NSString *innerErrorCode = innerError.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] ?: [NSString stringWithFormat:@"%ld", (long)innerError.code]; + [FBSDKTypeUtility dictionary:_extras + setObject:innerErrorCode + forKey:@"inner_error_code"]; + } + } else if (error) { + [FBSDKTypeUtility dictionary:params + setObject:@(error.code) + forKey:FBSDKReferralManagerLoggerParamErrorCodeKey]; + [FBSDKTypeUtility dictionary:params + setObject:error.localizedDescription + forKey:FBSDKReferralManagerLoggerParamErrorMessageKey]; + } + + [self logEvent:FBSDKAppEventNameFBReferralEnd params:params]; +} + +- (NSMutableDictionary *)_parametersForNewEvent +{ + NSMutableDictionary *eventParameters = [NSMutableDictionary new]; + + // NOTE: We ALWAYS add all params to each event, to ensure predictable mapping on the backend. + [FBSDKTypeUtility dictionary:eventParameters + setObject:_identifier ?: FBSDKReferralManagerLoggerValueEmpty + forKey:FBSDKReferralManagerLoggerParamIdentifierKey]; + [FBSDKTypeUtility dictionary:eventParameters + setObject:@(round(1000 * [NSDate date].timeIntervalSince1970)) + forKey:FBSDKReferralManagerLoggerParamTimestampKey]; + [FBSDKTypeUtility dictionary:eventParameters + setObject:FBSDKReferralManagerLoggerValueEmpty + forKey:FBSDKReferralManagerLoggerParamResultKey]; + [FBSDKTypeUtility dictionary:eventParameters + setObject:FBSDKReferralManagerLoggerValueEmpty + forKey:FBSDKReferralManagerLoggerParamErrorCodeKey]; + [FBSDKTypeUtility dictionary:eventParameters + setObject:FBSDKReferralManagerLoggerValueEmpty + forKey:FBSDKReferralManagerLoggerParamErrorMessageKey]; + [FBSDKTypeUtility dictionary:eventParameters + setObject:FBSDKReferralManagerLoggerValueEmpty + forKey:FBSDKReferralManagerLoggerParamExtrasKey]; + [FBSDKTypeUtility dictionary:eventParameters + setObject:_loggingToken ?: FBSDKReferralManagerLoggerValueEmpty + forKey:FBSDKReferralManagerLoggerParamLoggingTokenKey]; + + return eventParameters; +} + +- (void)logEvent:(NSString *)eventName params:(NSMutableDictionary *)params +{ + if (_identifier) { + NSString *extrasJSONString = [FBSDKBasicUtility JSONStringForObject:_extras + error:NULL + invalidObjectHandler:NULL]; + if (extrasJSONString) { + [FBSDKTypeUtility dictionary:params + setObject:extrasJSONString + forKey:FBSDKReferralManagerLoggerParamExtrasKey]; + } + [_extras removeAllObjects]; + + [FBSDKAppEvents logInternalEvent:eventName + parameters:params + isImplicitlyLogged:YES]; + } +} + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.h index 63efb5e81f..a1643ba80b 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.h @@ -20,11 +20,11 @@ #if !TARGET_OS_TV -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif @interface _FBSDKLoginRecoveryAttempter : FBSDKErrorRecoveryAttempter diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m index d344be4689..b4fd34b75c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m @@ -20,9 +20,9 @@ #if !TARGET_OS_TV -#import "_FBSDKLoginRecoveryAttempter.h" + #import "_FBSDKLoginRecoveryAttempter.h" -#import "FBSDKLoginKit+Internal.h" + #import "FBSDKLoginKit+Internal.h" @implementation _FBSDKLoginRecoveryAttempter @@ -30,9 +30,9 @@ - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector - contextInfo:(void *)contextInfo { - - void(^handler)(BOOL) = ^(BOOL didRecover) { + contextInfo:(void *)contextInfo +{ + void (^handler)(BOOL) = ^(BOOL didRecover) { [super completeRecovery:didRecover delegate:delegate didRecoverSelector:didRecoverSelector contextInfo:contextInfo]; }; NSSet *currentPermissions = [FBSDKAccessToken currentAccessToken].permissions; diff --git a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralCode.h b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralCode.h new file mode 120000 index 0000000000..c35a2341f1 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralCode.h @@ -0,0 +1 @@ +../FBSDKReferralCode.h \ No newline at end of file diff --git a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManager.h b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManager.h new file mode 120000 index 0000000000..78b0848922 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManager.h @@ -0,0 +1 @@ +../FBSDKReferralManager.h \ No newline at end of file diff --git a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManagerResult.h b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManagerResult.h new file mode 120000 index 0000000000..b142bb3321 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKReferralManagerResult.h @@ -0,0 +1 @@ +../FBSDKReferralManagerResult.h \ No newline at end of file diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 198f8b742f..77aeb30541 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -16,14 +16,12 @@ // 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 #import -#import - #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLoginResult.h" #import "FBSDKLoginUtilityTests.h" @@ -32,6 +30,12 @@ static NSString *const kFakeChallenge = @"a =bcdef"; +@interface FBSDKLoginManager (Testing) + +- (NSDictionary *)logInParametersFromURL:(NSURL *)url; + +@end + @interface FBSDKLoginManagerTests : XCTestCase @end @@ -59,9 +63,8 @@ - (NSURL *)authorizeURLWithFragment:(NSString *)fragment challenge:(NSString *)c fragment, fragment.length > 0 ? @"&" : @"", [FBSDKUtility URLEncode:[NSString stringWithFormat:@"{\"challenge\":\"%@\"}", challenge]] - ]; + ]; return [self authorizeURLWithParameters:fragment joinedBy:@"#"]; - } - (NSURL *)authorizeURLWithFragment:(NSString *)fragment @@ -153,15 +156,15 @@ - (void)testOpenURLRecentlyDeclined }]; } -//verify that a reauth for already granted permissions is not treated as a cancellation. +// verify that a reauth for already granted permissions is not treated as a cancellation. - (void)testOpenURLReauthSamePermissionsIsNotCancelled { -// XCTestExpectation *expectation = [self expectationWithDescription:@"completed reauth"]; + // XCTestExpectation *expectation = [self expectationWithDescription:@"completed reauth"]; // set up a current token with public_profile FBSDKAccessToken *existingToken = [[FBSDKAccessToken alloc] initWithTokenString:@"token" permissions:@[@"public_profile", @"read_stream"] declinedPermissions:@[] - expiredPermissions:@[] + expiredPermissions:@[] appID:@"" userID:@"" expirationDate:nil @@ -180,51 +183,51 @@ - (void)testOpenURLReauthSamePermissionsIsNotCancelled [target setRequestedPermissions:[NSSet setWithObjects:@"public_profile", @"read_stream", nil]]; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wnonnull" XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); -#pragma clang diagnostic pop + #pragma clang diagnostic pop [target verify]; } -//verify that a reauth for already granted permissions is not treated as a cancellation. +// verify that a reauth for already granted permissions is not treated as a cancellation. - (void)testOpenURLReauthNoPermissionsIsNotCancelled { - // XCTestExpectation *expectation = [self expectationWithDescription:@"completed reauth"]; - // set up a current token with public_profile - FBSDKAccessToken *existingToken = [[FBSDKAccessToken alloc] initWithTokenString:@"token" - permissions:@[@"public_profile", @"read_stream"] - declinedPermissions:@[] - expiredPermissions:@[] - appID:@"" - userID:@"" - expirationDate:nil - refreshDate:nil - dataAccessExpirationDate:nil]; - [FBSDKAccessToken setCurrentAccessToken:existingToken]; - NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile,read_stream&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; - // Use OCMock to verify the validateReauthentication: call and verify the result there. - id target = [OCMockObject partialMockForObject:[[FBSDKLoginManager alloc] init]]; - [[[target stub] andDo:^(NSInvocation *invocation) { - __unsafe_unretained FBSDKLoginManagerLoginResult *result; - [invocation getArgument:&result atIndex:3]; - XCTAssertFalse(result.isCancelled); - XCTAssertNotNil(result.token); - }] validateReauthentication:[OCMArg any] withResult:[OCMArg any]]; - - [target setRequestedPermissions:nil]; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - - XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); - -#pragma clang diagnostic pop - - [target verify]; + // XCTestExpectation *expectation = [self expectationWithDescription:@"completed reauth"]; + // set up a current token with public_profile + FBSDKAccessToken *existingToken = [[FBSDKAccessToken alloc] initWithTokenString:@"token" + permissions:@[@"public_profile", @"read_stream"] + declinedPermissions:@[] + expiredPermissions:@[] + appID:@"" + userID:@"" + expirationDate:nil + refreshDate:nil + dataAccessExpirationDate:nil]; + [FBSDKAccessToken setCurrentAccessToken:existingToken]; + NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile,read_stream&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; + // Use OCMock to verify the validateReauthentication: call and verify the result there. + id target = [OCMockObject partialMockForObject:[[FBSDKLoginManager alloc] init]]; + [[[target stub] andDo:^(NSInvocation *invocation) { + __unsafe_unretained FBSDKLoginManagerLoginResult *result; + [invocation getArgument:&result atIndex:3]; + XCTAssertFalse(result.isCancelled); + XCTAssertNotNil(result.token); + }] validateReauthentication:[OCMArg any] withResult:[OCMArg any]]; + + [target setRequestedPermissions:nil]; + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wnonnull" + + XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + #pragma clang diagnostic pop + + [target verify]; } - (void)testOpenURLWithBadChallenge @@ -232,7 +235,7 @@ - (void)testOpenURLWithBadChallenge XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; [FBSDKAccessToken setCurrentAccessToken:nil]; NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949" - challenge:@"someotherchallenge"]; + challenge:@"someotherchallenge"]; FBSDKLoginManager *target = [self loginManagerExpectingChallenge]; [target setRequestedPermissions:[NSSet setWithObjects:@"email", @"user_friends", nil]]; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { @@ -268,7 +271,6 @@ - (void)testOpenURLWithNoChallengeAndError }]; } - - (void)testLoginManagerRetainsItselfForLoginMethod { // Mock some methods to force an error callback. @@ -278,10 +280,10 @@ - (void)testLoginManagerRetainsItselfForLoginMethod }] validateURLSchemes]; [[[FBSDKInternalUtilityMock stub] andReturnValue:@NO] isFacebookAppInstalled]; NSError *URLError = [[NSError alloc] initWithDomain:FBSDKErrorDomain code:0 userInfo:nil]; - [[FBSDKInternalUtilityMock stub] appURLWithHost:OCMOCK_ANY - path:OCMOCK_ANY - queryParameters:OCMOCK_ANY - error:((NSError __autoreleasing **)[OCMArg setTo:URLError])]; + [[FBSDKInternalUtilityMock stub] appURLWithHost:OCMOCK_ANY + path:OCMOCK_ANY + queryParameters:OCMOCK_ANY + error:((NSError __autoreleasing **)[OCMArg setTo:URLError])]; XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; FBSDKLoginManager *manager = [FBSDKLoginManager new]; @@ -290,7 +292,7 @@ - (void)testLoginManagerRetainsItselfForLoginMethod }]; // This makes sure that FBSDKLoginManager is retaining itself for the duration of the call manager = nil; - [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:5 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; } @@ -324,24 +326,79 @@ - (void)testCallingLoginWhileAnotherLoginHasNotFinishedNoOps - (void)testLoginParams { - id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { - // Nothing - }] validateURLSchemes]; - FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; - NSDictionary *params = [loginManager logInParametersWithPermissions:[NSSet setWithArray:@[@"public_profile", @"email"]] serverConfiguration:nil]; - long long cbt = [params[@"cbt"] longLongValue]; - long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); - XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); - XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); - XCTAssertEqualObjects(params[@"response_type"], @"token_or_nonce,signed_request,graph_domain"); - XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); - XCTAssertEqualObjects(params[@"display"], @"touch"); - XCTAssertEqualObjects(params[@"sdk"], @"ios"); - XCTAssertEqualObjects(params[@"return_scopes"], @"true"); - XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); - XCTAssertEqualObjects(params[@"fbapp_pres"], @0); - XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); + id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; + [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { + // Nothing + }] validateURLSchemes]; + FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; + NSDictionary *params = [loginManager logInParametersWithPermissions:[NSSet setWithArray:@[@"public_profile", @"email"]] serverConfiguration:nil]; + long long cbt = [params[@"cbt"] longLongValue]; + long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); + XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); + XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); + XCTAssertEqualObjects(params[@"response_type"], @"token_or_nonce,signed_request,graph_domain"); + XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); + XCTAssertEqualObjects(params[@"display"], @"touch"); + XCTAssertEqualObjects(params[@"sdk"], @"ios"); + XCTAssertEqualObjects(params[@"return_scopes"], @"true"); + XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); + XCTAssertEqualObjects(params[@"fbapp_pres"], @0); + XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); +} + +- (void)testlogInParametersFromURL +{ + NSURL *url = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22fb_login%22%3A%22%7B%5C%22granted_scopes%5C%22%3A%5C%22public_profile%5C%22%2C%5C%22denied_scopes%5C%22%3A%5C%22%5C%22%2C%5C%22signed_request%5C%22%3A%5C%22ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0%5C%22%2C%5C%22nonce%5C%22%3A%5C%22someNonce%5C%22%2C%5C%22data_access_expiration_time%5C%22%3A%5C%221607374566%5C%22%2C%5C%22expires_in%5C%22%3A%5C%225183401%5C%22%7D%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + + NSDictionary *params = [loginManager logInParametersFromURL:url]; + + XCTAssertNotNil(params); + XCTAssertEqualObjects(params[@"nonce"], @"someNonce"); + XCTAssertEqualObjects(params[@"granted_scopes"], @"public_profile"); + XCTAssertEqualObjects(params[@"denied_scopes"], @""); +} + +- (void)testLogInWithURLFailWithInvalidLoginData +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + NSURL *urlWithInvalidLoginData = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22fb_login%22%3A%22invalid%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + FBSDKLoginManagerLoginResultBlock handler = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { + if (error) { + XCTAssertNil(result); + [expectation fulfill]; + } else { + XCTFail(@"Should have error"); + } + }; + + [loginManager logInWithURL:urlWithInvalidLoginData handler:handler]; + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testLogInWithURLFailWithNoLoginData +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + NSURL *urlWithNoLoginData = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22some_param%22%3A%22some_value%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + FBSDKLoginManagerLoginResultBlock handler = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { + if (error) { + XCTAssertNil(result); + [expectation fulfill]; + } else { + XCTFail(@"Should have error"); + } + }; + + [loginManager logInWithURL:urlWithNoLoginData handler:handler]; + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; } @end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m new file mode 100644 index 0000000000..39f5fb07a6 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m @@ -0,0 +1,72 @@ +// 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 "FBSDKReferralCode.h" + +static NSString *const _validReferralCode1 = @"abcd"; +static NSString *const _validReferralCode2 = @"123"; +static NSString *const _validReferralCode3 = @"123abc"; + +static NSString *const _invalidReferralCode1 = @"abd?"; +static NSString *const _invalidReferralCode2 = @"a b1"; +static NSString *const _invalidReferralCode3 = @" "; +static NSString *const _invalidReferralCode4 = @"\n\n"; + +static NSString *const _emptyReferralCode = @""; + +@interface FBSDKReferralCodeTests : XCTestCase + +@end + +@implementation FBSDKReferralCodeTests + +- (void)testCreateValidReferralCodeShouldSucceed +{ + [self assertCreationSucceedWithString:_validReferralCode1]; + [self assertCreationSucceedWithString:_validReferralCode2]; +} + +- (void)testCreateInvalidReferralCodeShoudFail +{ + [self assertCreationFailWithString:_invalidReferralCode1]; + [self assertCreationFailWithString:_invalidReferralCode2]; + [self assertCreationFailWithString:_invalidReferralCode3]; + [self assertCreationFailWithString:_invalidReferralCode4]; +} + +- (void)testCreateEmptyReferralCodeShoudFail +{ + [self assertCreationFailWithString:_emptyReferralCode]; +} + +- (void)assertCreationFailWithString:(NSString *)string +{ + FBSDKReferralCode *referralCode = [FBSDKReferralCode initWithString:string]; + XCTAssertNil(referralCode); +} + +- (void)assertCreationSucceedWithString:(NSString *)string +{ + FBSDKReferralCode *referralCode = [FBSDKReferralCode initWithString:string]; + XCTAssertNotNil(referralCode); + XCTAssertEqual(referralCode.value, string); +} + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m new file mode 100644 index 0000000000..eae4d1b6e7 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m @@ -0,0 +1,311 @@ +// 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 "FBSDKLoginUtility.h" +#import "FBSDKReferralManager+Internal.h" +#import "FBSDKReferralManagerResult.h" + +static NSString *const _mockAppID = @"mockAppID"; +static NSString *const _mockChallenge = @"mockChallenge"; + +@interface FBSDKReferralManager (Testing) + +- (NSURL *)referralURL; + +- (void)handleOpenURLComplete:(BOOL)didOpen error:(NSError *)error; + +- (BOOL)validateChallenge:(NSString *)challenge; + +@end + +@interface FBSDKReferralManagerTests : XCTestCase +{ + FBSDKReferralManager *_manager; +} + +@end + +@implementation FBSDKReferralManagerTests + +- (void)setUp +{ + [super setUp]; + _manager = OCMPartialMock([FBSDKReferralManager new]); + [FBSDKSettings setAppID:_mockAppID]; +} + +- (void)mockURLScheme +{ + id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; + OCMStub(ClassMethod([FBSDKInternalUtilityMock validateURLSchemes])).andDo(^(NSInvocation *invocation) { + // Nothing + }); +} + +- (void)mockBridgeAPI +{ + id partialBridgeAPIMock = OCMPartialMock([FBSDKBridgeAPI sharedInstance]); + OCMStub([partialBridgeAPIMock openURLWithSafariViewController:OCMArg.any sender:OCMArg.any fromViewController:OCMArg.any handler:OCMArg.any]).andDo(^(NSInvocation *invocation) { + // Nothing + }); +} + +- (void)testReferralURL +{ + NSURL *url = [_manager referralURL]; + + XCTAssertTrue([url.path hasSuffix:@"dialog/share_referral"]); + + NSDictionary *params = [FBSDKInternalUtility dictionaryFromFBURL:url]; + NSString *appID = params[@"app_id"]; + NSString *redirectURI = params[@"redirect_uri"]; + NSString *challenge = params[@"state"]; + NSString *expectedUrlPrefix = [FBSDKInternalUtility + appURLWithHost:@"authorize" + path:@"" + queryParameters:@{} + error:NULL].absoluteString; + + XCTAssertEqualObjects(appID, _mockAppID); + XCTAssertTrue([redirectURI hasPrefix:expectedUrlPrefix]); + XCTAssert(challenge.length > 0); +} + +- (void)testStartReferralOpensSFVC +{ + [self mockURLScheme]; + + id partialBridgeAPIMock = OCMPartialMock([FBSDKBridgeAPI sharedInstance]); + + [_manager startReferralWithCompletionHandler:nil]; + OCMVerify([partialBridgeAPIMock openURLWithSafariViewController:OCMArg.any sender:OCMArg.any fromViewController:OCMArg.any handler:OCMArg.any]); +} + +- (void)testReferralSuccess +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + OCMStub([_manager validateChallenge:_mockChallenge]).andReturn(YES); + + NSString *queryString = [@"?fb_referral_codes=%5B%22abc%22%2C%22def%22%5D&state=" stringByAppendingString:_mockChallenge]; + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"fb%@://authorize/%@", _mockAppID, queryString]]; + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTFail(@"Should not have error"); + } else { + NSArray *referralCodes = result.referralCodes; + NSArray *expectedReferralCodes = @[[FBSDKReferralCode initWithString:@"abc"], [FBSDKReferralCode initWithString:@"def"]]; + XCTAssertEqualObjects(referralCodes, expectedReferralCodes); + XCTAssertFalse(result.isCancelled); + [expectation fulfill]; + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + XCTAssertTrue([_manager application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralCancelWithOpenURLCompletionHandler +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + NSError *cancelError = [[NSError alloc]initWithDomain:@"com.apple.SafariServices.Authentication" code:0 userInfo:nil]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTFail(@"Should not have error"); + } else { + XCTAssertTrue(result.isCancelled); + XCTAssertNil(result.referralCodes); + [expectation fulfill]; + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + [_manager handleOpenURLComplete:NO error:cancelError]; + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralCancelWithAppDelegate +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + NSURL *fakeURL = [NSURL URLWithString:@"https://www.facebook.com"]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTFail(@"Should not have error"); + } else { + XCTAssertTrue(result.isCancelled); + XCTAssertNil(result.referralCodes); + [expectation fulfill]; + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + [_manager handleOpenURLComplete:YES error:nil]; + XCTAssertFalse([_manager application:nil openURL:fakeURL sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralErrorWithInvalidURLSchemes +{ + id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; + [OCMStub(ClassMethod([FBSDKInternalUtilityMock validateURLSchemes])) andThrow:[NSException exceptionWithName:@"InvalidOperationException" reason:nil userInfo:nil]]; + + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTAssertNil(result); + [expectation fulfill]; + } else { + XCTFail(@"Should have error"); + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralErrorWithOpenURLCompletionHandler +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + NSError *fakeError = [[NSError alloc]initWithDomain:FBSDKErrorDomain code:FBSDKErrorBridgeAPIInterruption userInfo:nil]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTAssertNil(result); + [expectation fulfill]; + } else { + XCTFail(@"Should have error"); + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + [_manager handleOpenURLComplete:NO error:fakeError]; + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralErrorWithAppDelegate +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + OCMStub([_manager validateChallenge:_mockChallenge]).andReturn(YES); + + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + NSString *invalidQueryString = @"?fb_referral_codes=%5B%22abc%2C%22def"; + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"fb%@://authorize/%@", _mockAppID, invalidQueryString]]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTAssertNil(result); + [expectation fulfill]; + } else { + XCTFail(@"Should have error"); + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + XCTAssertTrue([_manager application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralErrorWithBadChallenge +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + OCMStub([_manager validateChallenge:_mockChallenge]).andReturn(YES); + + NSString *badChallenge = @"badChallenge"; + NSString *queryString = [@"?fb_referral_codes=%5B%22abc%22%2C%22def%22%5D&state=" stringByAppendingString:badChallenge]; + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"fb%@://authorize/%@", _mockAppID, queryString]]; + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTAssertNil(result); + [expectation fulfill]; + } else { + XCTFail(@"Should have error"); + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + XCTAssertTrue([_manager application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void)testReferralSuccessWithInvalidReferralCode +{ + [self mockURLScheme]; + [self mockBridgeAPI]; + OCMStub([_manager validateChallenge:_mockChallenge]).andReturn(YES); + + NSString *queryStringWithInvalidCode = [@"?fb_referral_codes=%5B%22abc%22%2C%22def?%22%5D&state=" stringByAppendingString:_mockChallenge]; + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"fb%@://authorize/%@", _mockAppID, queryStringWithInvalidCode]]; + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + FBSDKReferralManagerResultBlock completionHandler = ^(FBSDKReferralManagerResult *result, NSError *referralError) { + if (referralError) { + XCTFail(@"Should not have error"); + } else { + NSArray *referralCodes = result.referralCodes; + NSArray *expectedReferralCodes = @[[FBSDKReferralCode initWithString:@"abc"]]; + XCTAssertEqualObjects(referralCodes, expectedReferralCodes, @"Only valid referral codes should be returned"); + XCTAssertFalse(result.isCancelled); + [expectation fulfill]; + } + }; + + [_manager startReferralWithCompletionHandler:completionHandler]; + XCTAssertTrue([_manager application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +@end diff --git a/FBSDKMarketingKit.podspec b/FBSDKMarketingKit.podspec deleted file mode 100644 index 9ca9776e7b..0000000000 --- a/FBSDKMarketingKit.podspec +++ /dev/null @@ -1,45 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'FBSDKMarketingKit' - s.version = '7.0.0' - s.deprecated = true - s.summary = 'Official Facebook SDK for iOS to set up Codeless Events' - - s.description = <<-DESC - The Facebook SDK for iOS Marketing framework provides: - * Set up codeless events. - DESC - - s.homepage = 'https://developers.facebook.com/docs/ios/' - - s.author = 'Facebook' - s.license = { :type => 'Facebook Platform License', :text => <<-LICENSE - 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. - LICENSE - } - s.platform = :ios - s.source = { :http => "https://github.com/facebook/facebook-ios-sdk/releases/download/v#{s.version}/FBSDKMarketingKit.zip", - :type => :zip } - s.source_files = 'FBSDKMarketingKit.framework/**/*.h' - s.public_header_files = 'FBSDKMarketingKit.framework/**/*.h' - s.ios.vendored_frameworks = 'FBSDKMarketingKit.framework' - - s.ios.deployment_target = '8.0' - - s.ios.dependency 'FBSDKCoreKit', "~> #{s.version}" -end diff --git a/FBSDKShareKit.podspec b/FBSDKShareKit.podspec index e8c268914c..228fc04f92 100644 --- a/FBSDKShareKit.podspec +++ b/FBSDKShareKit.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.author = 'Facebook' s.platform = :ios, :tvos - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '9.0' s.tvos.deployment_target = '10.0' s.source = { @@ -45,7 +45,8 @@ Pod::Spec.new do |s| ss.exclude_files = 'FBSDKShareKit/FBSDKShareKit/include/**/*', 'FBSDKShareKit/FBSDKShareKit/Swift/Exports.swift' - ss.public_header_files = 'FBSDKShareKit/FBSDKShareKit/*.{h}' + ss.public_header_files = 'FBSDKShareKit/FBSDKShareKit/*.{h}', + 'FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h' ss.source_files = 'FBSDKShareKit/FBSDKShareKit/**/*.{h,m,swift}' end end diff --git a/FBSDKShareKit/Configurations/FBSDKShareKit-Dynamic.xcconfig b/FBSDKShareKit/Configurations/FBSDKShareKit-Dynamic.xcconfig index 6c278289d3..c7d7b14469 100644 --- a/FBSDKShareKit/Configurations/FBSDKShareKit-Dynamic.xcconfig +++ b/FBSDKShareKit/Configurations/FBSDKShareKit-Dynamic.xcconfig @@ -28,4 +28,4 @@ CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) INFOPLIST_FILE = $(SRCROOT)/FBSDKShareKit/Info.plist MODULEMAP_FILE = $(SRCROOT)/FBSDKShareKit/FBSDKShareKit.modulemap -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 diff --git a/FBSDKShareKit/Configurations/FBSDKShareKitTests.xcconfig b/FBSDKShareKit/Configurations/FBSDKShareKitTests.xcconfig index be3461ce7d..9cc9204d0e 100644 --- a/FBSDKShareKit/Configurations/FBSDKShareKitTests.xcconfig +++ b/FBSDKShareKit/Configurations/FBSDKShareKitTests.xcconfig @@ -24,7 +24,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKShareKitTests INFOPLIST_FILE = $(SRCROOT)/FBSDKShareKitTests/Info.plist -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 HEADER_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) LIBRARY_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index d490e1456a..0c068b6485 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -267,6 +267,10 @@ F46FA683245362880060C902 /* Enums+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA682245362880060C902 /* Enums+Extensions.swift */; }; F46FA684245362880060C902 /* Enums+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA682245362880060C902 /* Enums+Extensions.swift */; }; F4D7A84724520A6700A12EE5 /* FakeSharingDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D7A84624520A6700A12EE5 /* FakeSharingDelegate.m */; }; + F4DC050F251947590073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */; }; + F4DC05172519475A0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */; }; + F4DC05182519475C0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */; }; + F4DC05202519475C0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */; }; F4E7517223EA18C20061BBFC /* FBSDKMessageDialogTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E7516823EA18C10061BBFC /* FBSDKMessageDialogTests.m */; }; F4E7517D23EA19010061BBFC /* FBSDKSendButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E7517423EA19000061BBFC /* FBSDKSendButton.m */; }; F4E7517E23EA19010061BBFC /* FBSDKSendButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E7517423EA19000061BBFC /* FBSDKSendButton.m */; }; @@ -397,7 +401,7 @@ remoteGlobalIDString = 81A07EDF1D1A2E6A0041A29C; remoteInfo = "FBSDKShareKit-Dynamic"; }; - F410D0582370CD66005B9318 /* PBXContainerItemProxy */ = { + F4DE319D24D9F9EC00297C18 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8118B6341D0A49B500962084 /* FBSDKCoreKit.xcodeproj */; proxyType = 1; @@ -546,6 +550,7 @@ F46FA682245362880060C902 /* Enums+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Enums+Extensions.swift"; path = "Swift/Enums+Extensions.swift"; sourceTree = ""; }; F4D7A84524520A6700A12EE5 /* FakeSharingDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeSharingDelegate.h; sourceTree = ""; }; F4D7A84624520A6700A12EE5 /* FakeSharingDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeSharingDelegate.m; sourceTree = ""; }; + F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitInternalImport.h; sourceTree = ""; }; F4E7516823EA18C10061BBFC /* FBSDKMessageDialogTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMessageDialogTests.m; sourceTree = ""; }; F4E7517323EA19000061BBFC /* FBSDKMessageDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMessageDialog.h; sourceTree = ""; }; F4E7517423EA19000061BBFC /* FBSDKSendButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSendButton.m; sourceTree = ""; }; @@ -748,6 +753,7 @@ 8937747A1A3A5F5B00BE2807 /* Internal */ = { isa = PBXGroup; children = ( + F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */, F4E7518F23EA1A130061BBFC /* FBSDKMessengerIcon.h */, F4E7519023EA1A130061BBFC /* FBSDKMessengerIcon.m */, A4F33E731E677A8600747AFD /* FBSDKCameraEffectArguments+Internal.h */, @@ -924,6 +930,7 @@ buildActionMask = 2147483647; files = ( 8144D9031D261D2900C8E4AC /* FBSDKSharePhoto.h in Headers */, + F4DC05202519475C0073B380 /* FBSDKCoreKitInternalImport.h in Headers */, 8144D9041D261D2900C8E4AC /* FBSDKSharePhotoContent.h in Headers */, 8144D9051D261D2900C8E4AC /* FBSDKShareUtility.h in Headers */, F462DBFC23B9526300FFCECA /* FBSDKCoreKit+Internal.h in Headers */, @@ -985,6 +992,7 @@ B3D17FEF212CD045000D28D6 /* FBSDKSharingValidation.h in Headers */, 81A07F331D1A2E6A0041A29C /* FBSDKShareKit.h in Headers */, 81A07F351D1A2E6A0041A29C /* FBSDKGameRequestFrictionlessRecipientCache.h in Headers */, + F4DC05172519475A0073B380 /* FBSDKCoreKitInternalImport.h in Headers */, 81A07F361D1A2E6A0041A29C /* FBSDKHashtag.h in Headers */, 81A07F371D1A2E6A0041A29C /* FBSDKSharePhotoContent.h in Headers */, B331E21B2208C94800F3E4EE /* FBSDKShareExtension.h in Headers */, @@ -1001,6 +1009,7 @@ buildActionMask = 2147483647; files = ( 9D2D99A71BC453DB00929E76 /* FBSDKSharePhoto.h in Headers */, + F4DC05182519475C0073B380 /* FBSDKCoreKitInternalImport.h in Headers */, 9D2D99B51BC4544600929E76 /* FBSDKSharePhotoContent.h in Headers */, 9D2D99A91BC453E700929E76 /* FBSDKShareUtility.h in Headers */, F462DBF223B9526200FFCECA /* FBSDKCoreKit+Internal.h in Headers */, @@ -1062,6 +1071,7 @@ 890414A81A6EB7F900617215 /* FBSDKSharingButton.h in Headers */, 9D46C5F61A11E5D800A0DDB6 /* FBSDKShareKit.h in Headers */, 89F203A11AAA0DF80053499E /* FBSDKGameRequestFrictionlessRecipientCache.h in Headers */, + F4DC050F251947590073B380 /* FBSDKCoreKitInternalImport.h in Headers */, D5158B5C1C5FD492003E32EE /* FBSDKHashtag.h in Headers */, 89FC9C6F1A3FA1E00001910E /* FBSDKSharePhotoContent.h in Headers */, B331E21A2208C94800F3E4EE /* FBSDKShareExtension.h in Headers */, @@ -1164,7 +1174,7 @@ buildRules = ( ); dependencies = ( - F410D0592370CD66005B9318 /* PBXTargetDependency */, + F4DE319E24D9F9EC00297C18 /* PBXTargetDependency */, F410D0572370CD62005B9318 /* PBXTargetDependency */, ); name = FBSDKShareKitTests; @@ -1566,10 +1576,10 @@ target = 81A07EDF1D1A2E6A0041A29C /* FBSDKShareKit-Dynamic */; targetProxy = F410D0562370CD62005B9318 /* PBXContainerItemProxy */; }; - F410D0592370CD66005B9318 /* PBXTargetDependency */ = { + F4DE319E24D9F9EC00297C18 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "FBSDKCoreKit-Dynamic"; - targetProxy = F410D0582370CD66005B9318 /* PBXContainerItemProxy */; + targetProxy = F4DE319D24D9F9EC00297C18 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.m index c8a64b43b7..117761eed4 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.m @@ -29,24 +29,24 @@ #else -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareUtility.h" -#define FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY @"groupDescription" -#define FBSDK_APP_GROUP_CONTENT_NAME_KEY @"name" -#define FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY @"privacy" + #define FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY @"groupDescription" + #define FBSDK_APP_GROUP_CONTENT_NAME_KEY @"name" + #define FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY @"privacy" NSString *NSStringFromFBSDKAppGroupPrivacy(FBSDKAppGroupPrivacy privacy) { switch (privacy) { - case FBSDKAppGroupPrivacyClosed:{ + case FBSDKAppGroupPrivacyClosed: { return @"closed"; } - case FBSDKAppGroupPrivacyOpen:{ + case FBSDKAppGroupPrivacyOpen: { return @"open"; } } @@ -54,7 +54,7 @@ @implementation FBSDKAppGroupContent -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -79,13 +79,13 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToAppGroupContent:(FBSDKAppGroupContent *)content { - return (content && - (_privacy == content.privacy) && - [FBSDKInternalUtility object:_name isEqualToObject:content.name] && - [FBSDKInternalUtility object:_groupDescription isEqualToObject:content.groupDescription]); + return (content + && (_privacy == content.privacy) + && [FBSDKInternalUtility object:_name isEqualToObject:content.name] + && [FBSDKInternalUtility object:_groupDescription isEqualToObject:content.groupDescription]); } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -110,7 +110,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeInteger:_privacy forKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.m index fbd1b3e497..9928131dee 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.m @@ -20,21 +20,20 @@ #if !TARGET_OS_TV -#import "FBSDKAppInviteContent.h" + #import "FBSDKAppInviteContent.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareUtility.h" - -#define FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY @"appLinkURL" -#define FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY @"previewImage" -#define FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY @"promoCode" -#define FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY @"promoText" -#define FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY @"destination" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareUtility.h" + #define FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY @"appLinkURL" + #define FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY @"previewImage" + #define FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY @"promoCode" + #define FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY @"promoText" + #define FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY @"destination" @implementation FBSDKAppInviteContent @@ -48,14 +47,14 @@ - (void)setPreviewImageURL:(NSURL *)previewImageURL self.appInvitePreviewImageURL = previewImageURL; } -#pragma mark - FBSDKSharingValidation + #pragma mark - FBSDKSharingValidation - (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef { - return ([FBSDKShareUtility validateRequiredValue:_appLinkURL name:@"appLinkURL" error:errorRef] && - [FBSDKShareUtility validateNetworkURL:_appLinkURL name:@"appLinkURL" error:errorRef] && - [FBSDKShareUtility validateNetworkURL:_appInvitePreviewImageURL name:@"appInvitePreviewImageURL" error:errorRef] && - [self _validatePromoCodeWithError:errorRef]); + return ([FBSDKShareUtility validateRequiredValue:_appLinkURL name:@"appLinkURL" error:errorRef] + && [FBSDKShareUtility validateNetworkURL:_appLinkURL name:@"appLinkURL" error:errorRef] + && [FBSDKShareUtility validateNetworkURL:_appInvitePreviewImageURL name:@"appInvitePreviewImageURL" error:errorRef] + && [self _validatePromoCodeWithError:errorRef]); } - (BOOL)_validatePromoCodeWithError:(NSError *__autoreleasing *)errorRef @@ -92,7 +91,6 @@ - (BOOL)_validatePromoCodeWithError:(NSError *__autoreleasing *)errorRef } return NO; } - } if (errorRef != NULL) { @@ -102,7 +100,7 @@ - (BOOL)_validatePromoCodeWithError:(NSError *__autoreleasing *)errorRef return YES; } -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -128,16 +126,16 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToAppInviteContent:(FBSDKAppInviteContent *)content { - return (content && - [FBSDKInternalUtility object:_appLinkURL isEqualToObject:content.appLinkURL] && - [FBSDKInternalUtility object:_appInvitePreviewImageURL isEqualToObject:content.appInvitePreviewImageURL] && - [FBSDKInternalUtility object:_promotionText isEqualToObject:content.promotionText] && - [FBSDKInternalUtility object:_promotionCode isEqualToObject:content.promotionText] && - _destination == content.destination - ); + return (content + && [FBSDKInternalUtility object:_appLinkURL isEqualToObject:content.appLinkURL] + && [FBSDKInternalUtility object:_appInvitePreviewImageURL isEqualToObject:content.appInvitePreviewImageURL] + && [FBSDKInternalUtility object:_promotionText isEqualToObject:content.promotionText] + && [FBSDKInternalUtility object:_promotionCode isEqualToObject:content.promotionText] + && _destination == content.destination + ); } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -150,12 +148,11 @@ - (instancetype)initWithCoder:(NSCoder *)decoder _appLinkURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY]; _appInvitePreviewImageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY]; _promotionCode = [decoder decodeObjectOfClass:[NSString class] forKey: - FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY]; + FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY]; _promotionText = [decoder decodeObjectOfClass:[NSString class] forKey: - FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY]; + FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY]; _destination = [decoder decodeIntegerForKey: - FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY]; - + FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY]; } return self; } @@ -169,7 +166,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeInt:(int)_destination forKey:FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectArguments.m b/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectArguments.m index 1ab385bc0c..2030e6400e 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectArguments.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectArguments.m @@ -20,14 +20,14 @@ #if !TARGET_OS_TV -#import "FBSDKCameraEffectArguments.h" + #import "FBSDKCameraEffectArguments.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareUtility.h" static NSString *const FBSDKCameraEffectArgumentsArgumentsKey = @"arguments"; @@ -36,7 +36,7 @@ @implementation FBSDKCameraEffectArguments NSMutableDictionary *_arguments; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)init { @@ -71,7 +71,7 @@ - (void)setArray:(NSArray *)array forKey:(NSString *)key return _arguments; } -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -94,7 +94,7 @@ - (BOOL)isEqualToCameraEffectArguments:(FBSDKCameraEffectArguments *)object return [FBSDKInternalUtility object:_arguments isEqualToObject:[object allArguments]]; } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -115,7 +115,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:_arguments forKey:FBSDKCameraEffectArgumentsArgumentsKey]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { @@ -124,8 +124,7 @@ - (id)copyWithZone:(NSZone *)zone return copy; } - -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_setValue:(id)value forKey:(NSString *)key { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectTextures.m b/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectTextures.m index 4bdac8c5e0..6bea464824 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectTextures.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKCameraEffectTextures.m @@ -20,14 +20,14 @@ #if !TARGET_OS_TV -#import "FBSDKCameraEffectTextures.h" + #import "FBSDKCameraEffectTextures.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareUtility.h" static NSString *const FBSDKCameraEffectTexturesTexturesKey = @"textures"; @@ -36,7 +36,7 @@ @implementation FBSDKCameraEffectTextures NSMutableDictionary *_textures; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)init { @@ -61,7 +61,7 @@ - (UIImage *)imageForKey:(NSString *)key return _textures; } -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -84,7 +84,7 @@ - (BOOL)isEqualToCameraEffectTextures:(FBSDKCameraEffectTextures *)object return [FBSDKInternalUtility object:_textures isEqualToObject:[object allTextures]]; } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -105,7 +105,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:_textures forKey:FBSDKCameraEffectTexturesTexturesKey]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { @@ -114,7 +114,7 @@ - (id)copyWithZone:(NSZone *)zone return copy; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_setValue:(id)value forKey:(NSString *)key { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKCoreKitImport.h b/FBSDKShareKit/FBSDKShareKit/FBSDKCoreKitImport.h index cb1975ff73..aa0979d4e6 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKCoreKitImport.h +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKCoreKitImport.h @@ -24,7 +24,7 @@ // Even though this file is not available from projects using SPM, // it is available when building the packages themselves so we need to include this check. #if FBSDK_SWIFT_PACKAGE -#import + #import #else -#import + #import #endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h index a1898ac938..9c69793dd5 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h @@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN +DEVICE_SHARING_DEPRECATED NS_SWIFT_NAME(FBDeviceShareButton) @interface FBSDKDeviceShareButton : FBSDKDeviceButton diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m index d88ab2e4f1..369eda4f6e 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m @@ -20,16 +20,20 @@ #if TARGET_OS_TV -#import "FBSDKDeviceShareButton.h" -#import "FBSDKDeviceShareViewController.h" + #import "FBSDKDeviceShareButton.h" -#if defined BUCK || defined FBSDKCOCOAPODS || defined __cplusplus -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #import "FBSDKDeviceShareViewController.h" + + #if defined BUCK || defined FBSDKCOCOAPODS || defined __cplusplus + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation FBSDKDeviceShareButton + #pragma clang diagnostic pop - (void)configureButton { @@ -39,9 +43,13 @@ - (void)configureButton highlightedColor:nil]; NSString *title = - NSLocalizedStringWithDefaultValue(@"ShareButton.Share", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Share", - @"The label for FBSDKShareButton"); + NSLocalizedStringWithDefaultValue( + @"ShareButton.Share", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Share", + @"The label for FBSDKShareButton" + ); NSAttributedString *attributedTitle = [self attributedTitleStringFromString:title]; [self setAttributedTitle:attributedTitle forState:UIControlStateNormal]; [self setAttributedTitle:attributedTitle forState:UIControlStateFocused]; @@ -53,7 +61,7 @@ - (void)configureButton [self addTarget:self action:@selector(_buttonPressed:) forControlEvents:UIControlEventPrimaryActionTriggered]; } -#pragma mark - Properties + #pragma mark - Properties - (void)setShareContent:(id)shareContent { @@ -63,7 +71,7 @@ - (void)setShareContent:(id)shareContent } } -#pragma mark - Implementation + #pragma mark - Implementation - (void)_buttonPressed:(id)sender { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h index 091b3c48d0..0bc5b89f40 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h @@ -33,6 +33,7 @@ NS_ASSUME_NONNULL_BEGIN /** A delegate for `FBSDKDeviceShareViewController` */ +DEVICE_SHARING_DEPRECATED NS_SWIFT_NAME(DeviceShareViewControllerDelegate) @protocol FBSDKDeviceShareViewControllerDelegate @@ -64,6 +65,7 @@ NS_SWIFT_NAME(DeviceShareViewControllerDelegate) animated:YES completion:NULL]; */ +DEVICE_SHARING_DEPRECATED NS_SWIFT_NAME(FBDeviceShareViewController) @interface FBSDKDeviceShareViewController : FBSDKDeviceViewControllerBase diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m index a779644ac2..21f05707db 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m @@ -20,22 +20,24 @@ #if TARGET_OS_TV -#import "FBSDKDeviceShareViewController.h" + #import "FBSDKDeviceShareViewController.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareLinkContent.h" -#import "FBSDKShareUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareLinkContent.h" + #import "FBSDKShareUtility.h" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation FBSDKDeviceShareViewController + #pragma clang diagnostic pop - (instancetype)initWithShareContent:(id)shareContent { - if ((self = [super initWithNibName:nil bundle:nil])) - { + if ((self = [super initWithNibName:nil bundle:nil])) { _shareContent = shareContent; } return self; @@ -92,13 +94,14 @@ - (void)viewDidAppear:(BOOL)animated } self.deviceDialogView.confirmationCode = code; __weak typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(expires * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [weakSelf _dismissWithError:nil]; - }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(expires * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ + [weakSelf _dismissWithError:nil]; + }); }]; } -#pragma mark - Private impl + #pragma mark - Private impl - (void)_dismissWithError:(NSError *)error { @@ -140,6 +143,7 @@ - (NSDictionary *)_graphRequestParametersForContent:(id)sha } return nil; } + @end #endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.m index 8da067eab1..f5357a20b7 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.m @@ -20,30 +20,30 @@ #if !TARGET_OS_TV -#import "FBSDKGameRequestContent.h" + #import "FBSDKGameRequestContent.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareConstants.h" -#import "FBSDKShareUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareConstants.h" + #import "FBSDKShareUtility.h" -#define FBSDK_APP_REQUEST_CONTENT_TO_KEY @"to" -#define FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY @"message" -#define FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY @"actionType" -#define FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY @"objectID" -#define FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY @"filters" -#define FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY @"suggestions" -#define FBSDK_APP_REQUEST_CONTENT_DATA_KEY @"data" -#define FBSDK_APP_REQUEST_CONTENT_TITLE_KEY @"title" + #define FBSDK_APP_REQUEST_CONTENT_TO_KEY @"to" + #define FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY @"message" + #define FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY @"actionType" + #define FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY @"objectID" + #define FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY @"filters" + #define FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY @"suggestions" + #define FBSDK_APP_REQUEST_CONTENT_DATA_KEY @"data" + #define FBSDK_APP_REQUEST_CONTENT_TITLE_KEY @"title" @implementation FBSDKGameRequestContent -#pragma mark - Properties + #pragma mark - Properties --(void)setRecipients:(NSArray *)recipients +- (void)setRecipients:(NSArray *)recipients { [FBSDKShareUtility assertCollection:recipients ofClass:[NSString class] name:@"recipients"]; if (![_recipients isEqual:recipients]) { @@ -79,7 +79,7 @@ - (void)setTo:(NSArray *)to self.recipients = to; } -#pragma mark - FBSDKSharingValidation + #pragma mark - FBSDKSharingValidation - (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef { @@ -155,15 +155,15 @@ - (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSErro @(FBSDKGameRequestActionTypeAskFor), @(FBSDKGameRequestActionTypeTurn)] error:errorRef] - && [FBSDKShareUtility validateArgumentWithName:@"filters" - value:_filters - isIn:@[@(FBSDKGameRequestFilterNone), - @(FBSDKGameRequestFilterAppUsers), - @(FBSDKGameRequestFilterAppNonUsers)] - error:errorRef]; + && [FBSDKShareUtility validateArgumentWithName:@"filters" + value:_filters + isIn:@[@(FBSDKGameRequestFilterNone), + @(FBSDKGameRequestFilterAppUsers), + @(FBSDKGameRequestFilterAppNonUsers)] + error:errorRef]; } -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -193,18 +193,18 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToGameRequestContent:(FBSDKGameRequestContent *)content { - return (content && - _actionType == content.actionType && - _filters == content.filters && - [FBSDKInternalUtility object:_data isEqualToObject:content.data] && - [FBSDKInternalUtility object:_message isEqualToObject:content.message] && - [FBSDKInternalUtility object:_objectID isEqualToObject:content.objectID] && - [FBSDKInternalUtility object:_recipientSuggestions isEqualToObject:content.recipientSuggestions] && - [FBSDKInternalUtility object:_title isEqualToObject:content.title] && - [FBSDKInternalUtility object:_recipients isEqualToObject:content.recipients]); + return (content + && _actionType == content.actionType + && _filters == content.filters + && [FBSDKInternalUtility object:_data isEqualToObject:content.data] + && [FBSDKInternalUtility object:_message isEqualToObject:content.message] + && [FBSDKInternalUtility object:_objectID isEqualToObject:content.objectID] + && [FBSDKInternalUtility object:_recipientSuggestions isEqualToObject:content.recipientSuggestions] + && [FBSDKInternalUtility object:_title isEqualToObject:content.title] + && [FBSDKInternalUtility object:_recipients isEqualToObject:content.recipients]); } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -238,7 +238,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:_recipients forKey:FBSDK_APP_REQUEST_CONTENT_TO_KEY]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m index 0d099152f7..2569503f56 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m @@ -20,16 +20,16 @@ #if !TARGET_OS_TV -#import "FBSDKGameRequestDialog.h" + #import "FBSDKGameRequestDialog.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKGameRequestFrictionlessRecipientCache.h" -#import "FBSDKShareConstants.h" -#import "FBSDKShareUtility.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKGameRequestFrictionlessRecipientCache.h" + #import "FBSDKShareConstants.h" + #import "FBSDKShareUtility.h" @interface FBSDKGameRequestDialog () @end @@ -40,9 +40,9 @@ @implementation FBSDKGameRequestDialog FBSDKWebDialog *_webDialog; } -#define FBSDK_APP_REQUEST_METHOD_NAME @"apprequests" + #define FBSDK_APP_REQUEST_METHOD_NAME @"apprequests" -#pragma mark - Class Methods + #pragma mark - Class Methods static FBSDKGameRequestFrictionlessRecipientCache *_recipientCache = nil; @@ -68,7 +68,7 @@ + (instancetype)showWithContent:(FBSDKGameRequestContent *)content delegate:(id< return dialog; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)init { @@ -85,7 +85,7 @@ - (void)dealloc _webDialog.delegate = nil; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (BOOL)canShow { @@ -166,7 +166,7 @@ - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef return NO; } -#pragma mark - FBSDKWebDialogDelegate + #pragma mark - FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { @@ -195,7 +195,7 @@ - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog [self _didCancel]; } -#pragma mark - FBSDKBridgeAPI + #pragma mark - FBSDKBridgeAPI - (BOOL)_launchDialogViaBridgeAPIWithParameters:(NSDictionary *)parameters { @@ -224,8 +224,8 @@ - (BOOL)_launchDialogViaBridgeAPIWithParameters:(NSDictionary *)parameters useSafariViewController:false fromViewController:topMostViewController completionBlock:^(FBSDKBridgeAPIResponse *response) { - [weakSelf _handleBridgeAPIResponse:response]; - }]; + [weakSelf _handleBridgeAPIResponse:response]; + }]; return YES; } @@ -245,7 +245,7 @@ - (void)_handleBridgeAPIResponse:(FBSDKBridgeAPIResponse *)response [self _didCompleteWithResults:response.responseParameters]; } -#pragma mark - Response Handling + #pragma mark - Response Handling - (void)_didCompleteWithResults:(NSDictionary *)results { @@ -262,7 +262,7 @@ - (void)_didCompleteWithResults:(NSDictionary *)results [self _cleanUp]; NSError *error = [FBSDKError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]] - message:[FBSDKTypeUtility stringValue:results[@"error_message"]]]; + message:[FBSDKTypeUtility stringValue:results[@"error_message"]]]; if (!error.code) { // reformat "to[x]" keys into an array. int counter = 0; @@ -299,7 +299,7 @@ - (void)_didCancel [FBSDKInternalUtility unregisterTransientObject:self]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_cleanUp { @@ -312,41 +312,40 @@ - (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSErro return; } switch (error.code) { - case 0:{ + case 0: { [_delegate gameRequestDialog:self didCompleteWithResults:results]; break; } - case 4201:{ + case 4201: { [_delegate gameRequestDialogDidCancel:self]; break; } - default:{ + default: { [_delegate gameRequestDialog:self didFailWithError:error]; break; } } if (error) { return; - } else { - } + } else {} } - (NSString *)_actionTypeNameForActionType:(FBSDKGameRequestActionType)actionType { switch (actionType) { - case FBSDKGameRequestActionTypeNone:{ + case FBSDKGameRequestActionTypeNone: { return nil; } - case FBSDKGameRequestActionTypeSend:{ + case FBSDKGameRequestActionTypeSend: { return @"send"; } - case FBSDKGameRequestActionTypeAskFor:{ + case FBSDKGameRequestActionTypeAskFor: { return @"askfor"; } - case FBSDKGameRequestActionTypeTurn:{ + case FBSDKGameRequestActionTypeTurn: { return @"turn"; } - default:{ + default: { return nil; } } @@ -355,16 +354,16 @@ - (NSString *)_actionTypeNameForActionType:(FBSDKGameRequestActionType)actionTyp - (NSString *)_filtersNameForFilters:(FBSDKGameRequestFilter)filters { switch (filters) { - case FBSDKGameRequestFilterNone:{ + case FBSDKGameRequestFilterNone: { return nil; } - case FBSDKGameRequestFilterAppUsers:{ + case FBSDKGameRequestFilterAppUsers: { return @"app_users"; } - case FBSDKGameRequestFilterAppNonUsers:{ + case FBSDKGameRequestFilterAppNonUsers: { return @"app_non_users"; } - default:{ + default: { return nil; } } diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m b/FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m index a26aad4cd0..71752a5338 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m @@ -19,9 +19,9 @@ #import "FBSDKHashtag.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #define FBSDK_HASHTAG_STRING_KEY @"hashtag" @@ -66,8 +66,8 @@ - (BOOL)isValid NSRange fullString = NSMakeRange(0, _stringRepresentation.length); NSRegularExpression *hashtagRegularExpression = HashtagRegularExpression(); NSUInteger numberOfMatches = [hashtagRegularExpression numberOfMatchesInString:_stringRepresentation - options:0 - range:fullString]; + options:0 + range:fullString]; return numberOfMatches > 0; } @@ -91,8 +91,8 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToHashtag:(FBSDKHashtag *)hashtag { - return (hashtag && - [FBSDKInternalUtility object:_stringRepresentation isEqualToObject:hashtag.stringRepresentation]); + return (hashtag + && [FBSDKInternalUtility object:_stringRepresentation isEqualToObject:hashtag.stringRepresentation]); } #pragma mark - NSCoding diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m index a437d7c902..bed7b8df51 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m @@ -20,27 +20,27 @@ #if !TARGET_OS_TV -#import "FBSDKMessageDialog.h" - -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareCameraEffectContent.h" -#import "FBSDKShareConstants.h" -#import "FBSDKShareDefines.h" -#import "FBSDKShareUtility.h" -#import "FBSDKShareVideoContent.h" - -#define FBSDK_MESSAGE_DIALOG_APP_SCHEME @"fb-messenger-share-api" - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-implementations" + #import "FBSDKMessageDialog.h" + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareCameraEffectContent.h" + #import "FBSDKShareConstants.h" + #import "FBSDKShareDefines.h" + #import "FBSDKShareUtility.h" + #import "FBSDKShareVideoContent.h" + + #define FBSDK_MESSAGE_DIALOG_APP_SCHEME @"fb-messenger-share-api" + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation FBSDKMessageDialog -#pragma clang diagnostic pop + #pragma clang diagnostic pop -#pragma mark - Class Methods + #pragma mark - Class Methods + (void)initialize { @@ -66,13 +66,13 @@ + (instancetype)showWithContent:(id)content delegate:(id -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKMessageDialog.h" -#import "FBSDKMessengerIcon.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKMessageDialog.h" + #import "FBSDKMessengerIcon.h" @interface FBSDKSendButton () @end -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-implementations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-implementations" @implementation FBSDKSendButton -#pragma clang diagnostic pop + #pragma clang diagnostic pop { FBSDKMessageDialog *_dialog; } -#pragma mark - Properties + #pragma mark - Properties - (id)shareContent { @@ -54,7 +54,7 @@ - (void)setShareContent:(id)shareContent [self checkImplicitlyDisabled]; } -#pragma mark - FBSDKButtonImpressionTracking + #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { @@ -71,17 +71,21 @@ - (NSString *)impressionTrackingIdentifier return @"send"; } -#pragma mark - FBSDKButton + #pragma mark - FBSDKButton - (void)configureButton { NSString *title = - NSLocalizedStringWithDefaultValue(@"SendButton.Send", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Send", - @"The label for FBSDKSendButton"); + NSLocalizedStringWithDefaultValue( + @"SendButton.Send", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Send", + @"The label for FBSDKSendButton" + ); - UIColor *backgroundColor = [UIColor colorWithRed:0.0 green:132.0/255.0 blue:1.0 alpha:1.0]; - UIColor *highlightedColor = [UIColor colorWithRed:0.0 green:111.0/255.0 blue:1.0 alpha:1.0]; + UIColor *backgroundColor = [UIColor colorWithRed:0.0 green:132.0 / 255.0 blue:1.0 alpha:1.0]; + UIColor *highlightedColor = [UIColor colorWithRed:0.0 green:111.0 / 255.0 blue:1.0 alpha:1.0]; [self configureWithIcon:[[FBSDKMessengerIcon alloc] init] title:title @@ -97,7 +101,7 @@ - (BOOL)isImplicitlyDisabled return !_dialog.canShow || ![_dialog validateWithError:NULL]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_share:(id)sender { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.m index 0a9856631f..2cdae35535 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.m @@ -20,21 +20,21 @@ #if !TARGET_OS_TV -#import "FBSDKShareButton.h" + #import "FBSDKShareButton.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareDialog.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareDialog.h" @implementation FBSDKShareButton { FBSDKShareDialog *_dialog; } -#pragma mark - Properties + #pragma mark - Properties - (id)shareContent { @@ -47,7 +47,7 @@ - (void)setShareContent:(id)shareContent [self checkImplicitlyDisabled]; } -#pragma mark - FBSDKButtonImpressionTracking + #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { @@ -64,14 +64,18 @@ - (NSString *)impressionTrackingIdentifier return @"share"; } -#pragma mark - FBSDKButton + #pragma mark - FBSDKButton - (void)configureButton { NSString *title = - NSLocalizedStringWithDefaultValue(@"ShareButton.Share", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Share", - @"The label for FBSDKShareButton"); + NSLocalizedStringWithDefaultValue( + @"ShareButton.Share", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Share", + @"The label for FBSDKShareButton" + ); [self configureWithIcon:nil title:title @@ -87,7 +91,7 @@ - (BOOL)isImplicitlyDisabled return ![_dialog canShow] || ![_dialog validateWithError:NULL]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_share:(id)sender { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareCameraEffectContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareCameraEffectContent.m index f7c34ba67e..a13a7c554f 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareCameraEffectContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareCameraEffectContent.m @@ -20,17 +20,17 @@ #if !TARGET_OS_TV -#import "FBSDKShareCameraEffectContent.h" - -#import "FBSDKCameraEffectArguments+Internal.h" -#import "FBSDKCameraEffectTextures+Internal.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKHashtag.h" -#import "FBSDKShareUtility.h" + #import "FBSDKShareCameraEffectContent.h" + + #import "FBSDKCameraEffectArguments+Internal.h" + #import "FBSDKCameraEffectTextures+Internal.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKHashtag.h" + #import "FBSDKShareUtility.h" static NSString *const kFBSDKShareCameraEffectContentEffectIDKey = @"effectID"; static NSString *const kFBSDKShareCameraEffectContentEffectArgumentsKey = @"effectArguments"; @@ -45,7 +45,7 @@ @implementation FBSDKShareCameraEffectContent -#pragma mark - Properties + #pragma mark - Properties @synthesize effectID = _effectID; @synthesize effectArguments = _effectArguments; @@ -58,7 +58,7 @@ @implementation FBSDKShareCameraEffectContent @synthesize pageID = _pageID; @synthesize shareUUID = _shareUUID; -#pragma mark - Initializer + #pragma mark - Initializer - (instancetype)init { @@ -69,15 +69,15 @@ - (instancetype)init return self; } -#pragma mark - FBSDKSharingContent + #pragma mark - FBSDKSharingContent - (NSDictionary *)addParameters:(NSDictionary *)existingParameters bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions { NSMutableDictionary *updatedParameters = [NSMutableDictionary dictionaryWithDictionary:existingParameters]; [FBSDKTypeUtility dictionary:updatedParameters - setObject:_effectID - forKey:@"effect_id"]; + setObject:_effectID + forKey:@"effect_id"]; NSString *effectArgumentsJSON; if (_effectArguments) { @@ -86,8 +86,8 @@ - (instancetype)init invalidObjectHandler:NULL]; } [FBSDKTypeUtility dictionary:updatedParameters - setObject:effectArgumentsJSON - forKey:@"effect_arguments"]; + setObject:effectArgumentsJSON + forKey:@"effect_arguments"]; NSData *effectTexturesData; if (_effectTextures) { @@ -102,20 +102,20 @@ - (instancetype)init texturesDataDict[key] = imageData; } }]; - #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0 - effectTexturesData = [NSKeyedArchiver archivedDataWithRootObject:texturesDataDict requiringSecureCoding:YES error:NULL]; - #else - effectTexturesData = [NSKeyedArchiver archivedDataWithRootObject:texturesDataDict]; - #endif + #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0 + effectTexturesData = [NSKeyedArchiver archivedDataWithRootObject:texturesDataDict requiringSecureCoding:YES error:NULL]; + #else + effectTexturesData = [NSKeyedArchiver archivedDataWithRootObject:texturesDataDict]; + #endif } [FBSDKTypeUtility dictionary:updatedParameters - setObject:effectTexturesData - forKey:@"effect_textures"]; + setObject:effectTexturesData + forKey:@"effect_textures"]; return updatedParameters; } -#pragma mark - FBSDKSharingScheme + #pragma mark - FBSDKSharingScheme - (NSString *)schemeForMode:(FBSDKShareDialogMode)mode { @@ -128,12 +128,12 @@ - (NSString *)schemeForMode:(FBSDKShareDialogMode)mode return nil; } -#pragma mark - FBSDKSharingValidation + #pragma mark - FBSDKSharingValidation - (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef { if (_effectID.length > 0) { - NSCharacterSet* nonDigitCharacters = [NSCharacterSet decimalDigitCharacterSet].invertedSet; + NSCharacterSet *nonDigitCharacters = [NSCharacterSet decimalDigitCharacterSet].invertedSet; if ([_effectID rangeOfCharacterFromSet:nonDigitCharacters].location != NSNotFound) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"effectID" @@ -147,7 +147,7 @@ - (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSErro return YES; } -#pragma mark - Equality + #pragma mark - Equality - (NSUInteger)hash { @@ -179,20 +179,20 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToShareCameraEffectContent:(FBSDKShareCameraEffectContent *)content { - return (content && - [FBSDKInternalUtility object:_effectID isEqualToObject:content.effectID] && - [FBSDKInternalUtility object:_effectArguments isEqualToObject:content.effectArguments] && - [FBSDKInternalUtility object:_effectTextures isEqualToObject:content.effectTextures] && - [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && - [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && - [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && - [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && - [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] && - [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] && - [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID]); + return (content + && [FBSDKInternalUtility object:_effectID isEqualToObject:content.effectID] + && [FBSDKInternalUtility object:_effectArguments isEqualToObject:content.effectArguments] + && [FBSDKInternalUtility object:_effectTextures isEqualToObject:content.effectTextures] + && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] + && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] + && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] + && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] + && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] + && [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] + && [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID]); } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -230,7 +230,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:_shareUUID forKey:kFBSDKShareCameraEffectContentUUIDKey]; } -#pragma mark - NSCopying + #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m index 9431d09434..6a3168d3f5 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m @@ -20,35 +20,35 @@ #if !TARGET_OS_TV -#import "FBSDKShareDialog.h" - -#import - -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareCameraEffectContent.h" -#import "FBSDKShareConstants.h" -#import "FBSDKShareDefines.h" -#import "FBSDKShareExtension.h" -#import "FBSDKShareLinkContent.h" -#import "FBSDKShareMediaContent.h" -#import "FBSDKSharePhoto.h" -#import "FBSDKSharePhotoContent.h" -#import "FBSDKShareUtility.h" -#import "FBSDKShareVideo.h" -#import "FBSDKShareVideoContent.h" - -#define FBSDK_SHARE_FEED_METHOD_NAME @"feed" -#define FBSDK_SHARE_METHOD_CAMERA_MIN_VERSION @"20170417" -#define FBSDK_SHARE_METHOD_MIN_VERSION @"20130410" -#define FBSDK_SHARE_METHOD_PHOTOS_MIN_VERSION @"20140116" -#define FBSDK_SHARE_METHOD_VIDEO_MIN_VERSION @"20150313" -#define FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION @"20150629" -#define FBSDK_SHARE_METHOD_QUOTE_MIN_VERSION @"20160328" -#define FBSDK_SHARE_METHOD_MMP_MIN_VERSION @"20160328" + #import "FBSDKShareDialog.h" + + #import + + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareCameraEffectContent.h" + #import "FBSDKShareConstants.h" + #import "FBSDKShareDefines.h" + #import "FBSDKShareExtension.h" + #import "FBSDKShareLinkContent.h" + #import "FBSDKShareMediaContent.h" + #import "FBSDKSharePhoto.h" + #import "FBSDKSharePhotoContent.h" + #import "FBSDKShareUtility.h" + #import "FBSDKShareVideo.h" + #import "FBSDKShareVideoContent.h" + + #define FBSDK_SHARE_FEED_METHOD_NAME @"feed" + #define FBSDK_SHARE_METHOD_CAMERA_MIN_VERSION @"20170417" + #define FBSDK_SHARE_METHOD_MIN_VERSION @"20130410" + #define FBSDK_SHARE_METHOD_PHOTOS_MIN_VERSION @"20140116" + #define FBSDK_SHARE_METHOD_VIDEO_MIN_VERSION @"20150313" + #define FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION @"20150629" + #define FBSDK_SHARE_METHOD_QUOTE_MIN_VERSION @"20160328" + #define FBSDK_SHARE_METHOD_MMP_MIN_VERSION @"20160328" static inline void FBSDKShareDialogValidateAPISchemeRegisteredForCanOpenUrl() { @@ -66,7 +66,6 @@ static inline void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanO }); } - @interface FBSDKShareDialog () @end @@ -76,7 +75,7 @@ @implementation FBSDKShareDialog NSMutableArray *_temporaryFiles; } -#pragma mark - Class Methods + #pragma mark - Class Methods + (void)initialize { @@ -108,7 +107,7 @@ + (instancetype)showFromViewController:(UIViewController *)viewController return dialog; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (void)dealloc { @@ -122,13 +121,13 @@ - (void)dealloc } } -#pragma mark - Properties + #pragma mark - Properties @synthesize delegate = _delegate; @synthesize shareContent = _shareContent; @synthesize shouldFailOnDataError = _shouldFailOnDataError; -#pragma mark - Public Methods + #pragma mark - Public Methods - (BOOL)canShow { @@ -143,13 +142,13 @@ - (BOOL)canShow case FBSDKShareDialogModeBrowser: case FBSDKShareDialogModeFeedBrowser: case FBSDKShareDialogModeFeedWeb: - case FBSDKShareDialogModeWeb:{ + case FBSDKShareDialogModeWeb: { return YES; } - case FBSDKShareDialogModeNative:{ + case FBSDKShareDialogModeNative: { return [self _canShowNative]; } - case FBSDKShareDialogModeShareSheet:{ + case FBSDKShareDialogModeShareSheet: { return [self _canShowShareSheet]; } } @@ -164,31 +163,31 @@ - (BOOL)show if ([self _validateWithError:&error]) { switch (self.mode) { - case FBSDKShareDialogModeAutomatic:{ + case FBSDKShareDialogModeAutomatic: { didShow = [self _showAutomatic:&error]; break; } - case FBSDKShareDialogModeBrowser:{ + case FBSDKShareDialogModeBrowser: { didShow = [self _showBrowser:&error]; break; } - case FBSDKShareDialogModeFeedBrowser:{ + case FBSDKShareDialogModeFeedBrowser: { didShow = [self _showFeedBrowser:&error]; break; } - case FBSDKShareDialogModeFeedWeb:{ + case FBSDKShareDialogModeFeedWeb: { didShow = [self _showFeedWeb:&error]; break; } - case FBSDKShareDialogModeNative:{ + case FBSDKShareDialogModeNative: { didShow = [self _showNativeWithCanShowError:&error validationError:&validationError]; break; } - case FBSDKShareDialogModeShareSheet:{ + case FBSDKShareDialogModeShareSheet: { didShow = [self _showShareSheetWithCanShowError:&error validationError:&validationError]; break; } - case FBSDKShareDialogModeWeb:{ + case FBSDKShareDialogModeWeb: { didShow = [self _showWeb:&error]; break; } @@ -208,7 +207,7 @@ - (BOOL)validateWithError:(NSError **)errorRef return [self _validateWithError:errorRef] && [self _validateFullyCompatibleWithError:errorRef]; } -#pragma mark - FBSDKWebDialogDelegate + #pragma mark - FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { @@ -223,14 +222,14 @@ - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictiona NSError *error = [FBSDKError errorWithDomain:FBSDKShareErrorDomain code:FBSDKShareErrorUnknown userInfo:@{ - FBSDKGraphRequestErrorGraphErrorCodeKey : @(errorCode) - } + FBSDKGraphRequestErrorGraphErrorCodeKey : @(errorCode) + } message:results[@"error_message"] underlyingError:nil]; - [self _handleWebResponseParameters:nil error:error cancelled: NO]; + [self _handleWebResponseParameters:nil error:error cancelled:NO]; } else { // not all web dialogs report cancellation, so assume that the share has completed with no additional information - [self _handleWebResponseParameters:results error:nil cancelled: NO]; + [self _handleWebResponseParameters:results error:nil cancelled:NO]; } [FBSDKInternalUtility unregisterTransientObject:self]; } @@ -255,9 +254,9 @@ - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog [FBSDKInternalUtility unregisterTransientObject:self]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods --(BOOL)_isDefaultToShareSheet +- (BOOL)_isDefaultToShareSheet { if ([self.shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) { return NO; @@ -266,18 +265,18 @@ -(BOOL)_isDefaultToShareSheet return [configuration.defaultShareMode isEqualToString:@"share_sheet"]; } --(BOOL)_showAutomatic:(NSError **)errorRef +- (BOOL)_showAutomatic:(NSError **)errorRef { BOOL isDefaultToShareSheet = [self _isDefaultToShareSheet]; BOOL useNativeDialog = [self _useNativeDialog]; - return ((isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) || - (useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef]) || - (!isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) || - [self _showFeedBrowser:errorRef] || - [self _showFeedWeb:errorRef] || - [self _showBrowser:errorRef] || - [self _showWeb:errorRef] || - (!useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef])); + return ((isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) + || (useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef]) + || (!isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) + || [self _showFeedBrowser:errorRef] + || [self _showFeedWeb:errorRef] + || [self _showBrowser:errorRef] + || [self _showWeb:errorRef] + || (!useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef])); } - (void)_loadNativeMethodName:(NSString **)methodNameRef methodVersion:(NSString **)methodVersionRef @@ -355,8 +354,8 @@ - (BOOL)_canAttributeThroughShareSheet NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = [scheme stringByAppendingString:minimumVersion]; components.path = @"/"; - return ([[UIApplication sharedApplication] canOpenURL:components.URL] || - [self _canUseFBShareSheet]); + return ([[UIApplication sharedApplication] canOpenURL:components.URL] + || [self _canUseFBShareSheet]); } - (BOOL)_canUseFBShareSheet @@ -497,8 +496,8 @@ - (void)_handleWebResponseParameters:(NSDictionary *)webResponseParameters NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; // the web response comes back with a different payload, so we need to translate it [FBSDKTypeUtility dictionary:results - setObject:webResponseParameters[FBSDK_SHARE_WEB_PARAM_POST_ID_KEY] - forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; + setObject:webResponseParameters[FBSDK_SHARE_WEB_PARAM_POST_ID_KEY] + forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [self _invokeDelegateDidCompleteWithResults:results]; } } @@ -521,10 +520,10 @@ - (BOOL)_showBrowser:(NSError **)errorRef } id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]] && [self _photoContentHasAtLeastOneImage:(FBSDKSharePhotoContent *)shareContent]) { - void(^completion)(BOOL, NSString *, NSDictionary *) = ^(BOOL successfullyBuilt, NSString *cMethodName, NSDictionary *cParameters) { + void (^completion)(BOOL, NSString *, NSDictionary *) = ^(BOOL successfullyBuilt, NSString *cMethodName, NSDictionary *cParameters) { if (successfullyBuilt) { FBSDKBridgeAPIResponseBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { - [self _handleWebResponseParameters:response.responseParameters error:response.error cancelled: response.isCancelled]; + [self _handleWebResponseParameters:response.responseParameters error:response.error cancelled:response.isCancelled]; [FBSDKInternalUtility unregisterTransientObject:self]; }; FBSDKBridgeAPIRequest *request; @@ -535,9 +534,9 @@ - (BOOL)_showBrowser:(NSError **)errorRef parameters:cParameters userInfo:nil]; [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:request - useSafariViewController:[self _useSafariViewController] - fromViewController:self.fromViewController - completionBlock:completionBlock]; + useSafariViewController:[self _useSafariViewController] + fromViewController:self.fromViewController + completionBlock:completionBlock]; } }; @@ -553,7 +552,7 @@ - (BOOL)_showBrowser:(NSError **)errorRef return NO; } FBSDKBridgeAPIResponseBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { - [self _handleWebResponseParameters:response.responseParameters error:response.error cancelled: response.isCancelled]; + [self _handleWebResponseParameters:response.responseParameters error:response.error cancelled:response.isCancelled]; [FBSDKInternalUtility unregisterTransientObject:self]; }; FBSDKBridgeAPIRequest *request; @@ -564,9 +563,9 @@ - (BOOL)_showBrowser:(NSError **)errorRef parameters:parameters userInfo:nil]; [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:request - useSafariViewController:[self _useSafariViewController] - fromViewController:self.fromViewController - completionBlock:completionBlock]; + useSafariViewController:[self _useSafariViewController] + fromViewController:self.fromViewController + completionBlock:completionBlock]; } return YES; } @@ -590,9 +589,9 @@ - (BOOL)_showFeedBrowser:(NSError **)errorRef parameters:parameters userInfo:nil]; [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:request - useSafariViewController:[self _useSafariViewController] - fromViewController:self.fromViewController - completionBlock:completionBlock]; + useSafariViewController:[self _useSafariViewController] + fromViewController:self.fromViewController + completionBlock:completionBlock]; return YES; } @@ -645,31 +644,31 @@ - (BOOL)_showNativeWithCanShowError:(NSError **)canShowErrorRef validationError: FBSDKBridgeAPIResponseBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { if (response.error.code == FBSDKErrorAppVersionUnsupported) { NSError *fallbackError; - if ([self _showShareSheetWithCanShowError:NULL validationError:&fallbackError] || - [self _showFeedBrowser:&fallbackError]) { + if ([self _showShareSheetWithCanShowError:NULL validationError:&fallbackError] + || [self _showFeedBrowser:&fallbackError]) { return; } } NSDictionary *responseParameters = response.responseParameters; NSString *completionGesture = responseParameters[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; - if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL] || - response.isCancelled) { + if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL] + || response.isCancelled) { [self _invokeDelegateDidCancel]; } else if (response.error) { [self _invokeDelegateDidFailWithError:response.error]; } else { NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:results - setObject:responseParameters[FBSDK_SHARE_RESULT_POST_ID_KEY] - forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; + setObject:responseParameters[FBSDK_SHARE_RESULT_POST_ID_KEY] + forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [self _invokeDelegateDidCompleteWithResults:results]; } [FBSDKInternalUtility unregisterTransientObject:self]; }; [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:request - useSafariViewController:[self _useSafariViewController] - fromViewController:self.fromViewController - completionBlock:completionBlock]; + useSafariViewController:[self _useSafariViewController] + fromViewController:self.fromViewController + completionBlock:completionBlock]; return YES; } @@ -729,11 +728,11 @@ - (BOOL)_showShareSheetWithCanShowError:(NSError **)canShowErrorRef validationEr } composeViewController.completionHandler = ^(SLComposeViewControllerResult result) { switch (result) { - case SLComposeViewControllerResultCancelled:{ + case SLComposeViewControllerResultCancelled: { [self _invokeDelegateDidCancel]; break; } - case SLComposeViewControllerResultDone:{ + case SLComposeViewControllerResultDone: { [self _invokeDelegateDidCompleteWithResults:@{}]; break; } @@ -791,12 +790,11 @@ - (BOOL)_validateWithError:(NSError **)errorRef } if (self.shareContent) { - if ([self.shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]] || - [self.shareContent isKindOfClass:[FBSDKShareLinkContent class]] || - [self.shareContent isKindOfClass:[FBSDKShareMediaContent class]] || - [self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]] || - [self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { - } else { + if ([self.shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]] + || [self.shareContent isKindOfClass:[FBSDKShareLinkContent class]] + || [self.shareContent isKindOfClass:[FBSDKShareMediaContent class]] + || [self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]] + || [self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {} else { if (errorRef != NULL) { NSString *message = [NSString stringWithFormat:@"Share dialog does not support %@.", NSStringFromClass(self.shareContent.class)]; @@ -815,27 +813,27 @@ - (BOOL)_validateWithError:(NSError **)errorRef } switch (self.mode) { - case FBSDKShareDialogModeAutomatic:{ + case FBSDKShareDialogModeAutomatic: { return ( - ([self _canShowNative] && [self _validateShareContentForNative:errorRef]) || - ([self _canShowShareSheet] && [self _validateShareContentForShareSheet:errorRef]) || - [self _validateShareContentForFeed:errorRef] || - [self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]); + ([self _canShowNative] && [self _validateShareContentForNative:errorRef]) + || ([self _canShowShareSheet] && [self _validateShareContentForShareSheet:errorRef]) + || [self _validateShareContentForFeed:errorRef] + || [self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]); } - case FBSDKShareDialogModeNative:{ + case FBSDKShareDialogModeNative: { return [self _validateShareContentForNative:errorRef]; } - case FBSDKShareDialogModeShareSheet:{ + case FBSDKShareDialogModeShareSheet: { return [self _validateShareContentForShareSheet:errorRef]; } - case FBSDKShareDialogModeBrowser:{ + case FBSDKShareDialogModeBrowser: { return [self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]; } - case FBSDKShareDialogModeWeb:{ + case FBSDKShareDialogModeWeb: { return [self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsPhotoImageURL error:errorRef]; } case FBSDKShareDialogModeFeedBrowser: - case FBSDKShareDialogModeFeedWeb:{ + case FBSDKShareDialogModeFeedWeb: { return [self _validateShareContentForFeed:errorRef]; } } @@ -865,9 +863,9 @@ - (BOOL)_validateFullyCompatibleWithError:(NSError **)errorRef id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { FBSDKShareLinkContent *shareLinkContent = (FBSDKShareLinkContent *)shareContent; - if (shareLinkContent.quote.length > 0 && - self.mode == FBSDKShareDialogModeShareSheet && - ![self _canUseQuoteInShareSheet]) { + if (shareLinkContent.quote.length > 0 + && self.mode == FBSDKShareDialogModeShareSheet + && ![self _canUseQuoteInShareSheet]) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKError invalidArgumentErrorWithDomain:FBSDKShareErrorDomain name:@"shareContent" @@ -1029,12 +1027,12 @@ - (BOOL)_validateShareContentForShareSheet:(NSError **)errorRef return NO; } } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { - return ([self _canUseFBShareSheet] && - [(FBSDKShareVideoContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]); + return ([self _canUseFBShareSheet] + && [(FBSDKShareVideoContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]); } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { - return ([self _canUseFBShareSheet] && - [self _validateShareMediaContentAvailability:shareContent error:errorRef] && - [(FBSDKShareMediaContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]); + return ([self _canUseFBShareSheet] + && [self _validateShareMediaContentAvailability:shareContent error:errorRef] + && [(FBSDKShareMediaContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]); } else if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { return YES; } else { @@ -1054,9 +1052,9 @@ - (BOOL)_validateShareContentForShareSheet:(NSError **)errorRef - (BOOL)_validateShareMediaContentAvailability:(FBSDKShareMediaContent *)shareContent error:(NSError **)errorRef { - if ([FBSDKShareUtility shareMediaContentContainsPhotosAndVideos:shareContent] && - self.mode == FBSDKShareDialogModeShareSheet && - ![self _canUseMMPInShareSheet]) { + if ([FBSDKShareUtility shareMediaContentContainsPhotosAndVideos:shareContent] + && self.mode == FBSDKShareDialogModeShareSheet + && ![self _canUseMMPInShareSheet]) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKError invalidArgumentErrorWithDomain:FBSDKShareErrorDomain name:@"shareContent" @@ -1070,9 +1068,9 @@ - (BOOL)_validateShareMediaContentAvailability:(FBSDKShareMediaContent *)shareCo - (void)_invokeDelegateDidCancel { - NSDictionary * parameters = @{ - FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Cancelled, - }; + NSDictionary *parameters = @{ + FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Cancelled, + }; [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameFBSDKEventShareDialogResult parameters:parameters @@ -1084,9 +1082,9 @@ - (void)_invokeDelegateDidCancel - (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results { - NSDictionary * parameters = @{ - FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed - }; + NSDictionary *parameters = @{ + FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed + }; [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameFBSDKEventShareDialogResult parameters:parameters @@ -1098,10 +1096,10 @@ - (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results - (void)_invokeDelegateDidFailWithError:(NSError *)error { - NSDictionary * parameters = @{ - FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Failed, - FBSDKAppEventParameterDialogErrorMessage : [NSString stringWithFormat:@"%@", error] - }; + NSDictionary *parameters = @{ + FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Failed, + FBSDKAppEventParameterDialogErrorMessage : [NSString stringWithFormat:@"%@", error] + }; [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameFBSDKEventShareDialogResult parameters:parameters @@ -1129,10 +1127,9 @@ - (void)_logDialogShow } NSDictionary *parameters = @{ - FBSDKAppEventParameterDialogMode : shareMode, - FBSDKAppEventParameterDialogShareContentType : contentType, - - }; + FBSDKAppEventParameterDialogMode : shareMode, + FBSDKAppEventParameterDialogShareContentType : contentType, + }; [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameFBSDKEventShareDialogShow parameters:parameters diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.m index 0e0abb0cab..4603e70786 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.m @@ -19,36 +19,36 @@ #import "FBSDKShareDialogMode.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif NSString *NSStringFromFBSDKShareDialogMode(FBSDKShareDialogMode dialogMode) { switch (dialogMode) { - case FBSDKShareDialogModeAutomatic:{ + case FBSDKShareDialogModeAutomatic: { return FBSDKAppEventsDialogShareModeAutomatic; } - case FBSDKShareDialogModeBrowser:{ + case FBSDKShareDialogModeBrowser: { return FBSDKAppEventsDialogShareModeBrowser; } - case FBSDKShareDialogModeNative:{ + case FBSDKShareDialogModeNative: { return FBSDKAppEventsDialogShareModeNative; } - case FBSDKShareDialogModeShareSheet:{ + case FBSDKShareDialogModeShareSheet: { return FBSDKAppEventsDialogShareModeShareSheet; } - case FBSDKShareDialogModeWeb:{ + case FBSDKShareDialogModeWeb: { return FBSDKAppEventsDialogShareModeWeb; } case FBSDKShareDialogModeFeedBrowser: { return FBSDKAppEventsDialogShareModeFeedBrowser; } - case FBSDKShareDialogModeFeedWeb:{ + case FBSDKShareDialogModeFeedWeb: { return FBSDKAppEventsDialogShareModeFeedWeb; } - default:{ + default: { return FBSDKAppEventsDialogShareModeUnknown; } } diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h b/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h index 61ebccdc5d..f304c6e627 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h @@ -16,8 +16,6 @@ // 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 "TargetConditionals.h" - #import "FBSDKHashtag.h" #import "FBSDKShareConstants.h" #import "FBSDKShareLinkContent.h" @@ -28,21 +26,22 @@ #import "FBSDKShareVideoContent.h" #import "FBSDKSharing.h" #import "FBSDKSharingContent.h" +#import "TargetConditionals.h" #if !TARGET_OS_TV -#import "FBSDKAppGroupContent.h" -#import "FBSDKAppInviteContent.h" -#import "FBSDKGameRequestContent.h" -#import "FBSDKGameRequestDialog.h" -#import "FBSDKLiking.h" -#import "FBSDKLikeObjectType.h" -#import "FBSDKMessageDialog.h" -#import "FBSDKShareButton.h" -#import "FBSDKShareCameraEffectContent.h" -#import "FBSDKShareDialog.h" -#import "FBSDKShareDialogMode.h" -#import "FBSDKSendButton.h" + #import "FBSDKAppGroupContent.h" + #import "FBSDKAppInviteContent.h" + #import "FBSDKGameRequestContent.h" + #import "FBSDKGameRequestDialog.h" + #import "FBSDKLikeObjectType.h" + #import "FBSDKLiking.h" + #import "FBSDKMessageDialog.h" + #import "FBSDKSendButton.h" + #import "FBSDKShareButton.h" + #import "FBSDKShareCameraEffectContent.h" + #import "FBSDKShareDialog.h" + #import "FBSDKShareDialogMode.h" #else -#import "FBSDKDeviceShareViewController.h" -#import "FBSDKDeviceShareButton.h" + #import "FBSDKDeviceShareButton.h" + #import "FBSDKDeviceShareViewController.h" #endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.m index 45ebe8337b..2753ec03cf 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.m @@ -19,9 +19,9 @@ #import "FBSDKShareLinkContent.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKHashtag.h" #import "FBSDKShareUtility.h" @@ -125,15 +125,15 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToShareLinkContent:(FBSDKShareLinkContent *)content { - return (content && - [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && - [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && - [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && - [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && - [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] && - [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID] && - [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID]) && - [FBSDKInternalUtility object:_quote isEqualToObject:content.quote]; + return (content + && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] + && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] + && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] + && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] + && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] + && [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID] + && [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID]) + && [FBSDKInternalUtility object:_quote isEqualToObject:content.quote]; } #pragma mark - NSCoding diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.m index e48dcd088f..59c4d9cab3 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.m @@ -19,9 +19,9 @@ #import "FBSDKShareMediaContent.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKHashtag.h" #import "FBSDKShareConstants.h" @@ -126,7 +126,6 @@ - (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSErro if (![video validateWithOptions:bridgeOptions error:errorRef]) { return NO; } - } else { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithDomain:FBSDKShareErrorDomain @@ -170,15 +169,15 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToShareMediaContent:(FBSDKShareMediaContent *)content { - return (content && - [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && - [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && - [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && - [FBSDKInternalUtility object:_media isEqualToObject:content.media] && - [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && - [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] && - [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] && - [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID]); + return (content + && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] + && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] + && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] + && [FBSDKInternalUtility object:_media isEqualToObject:content.media] + && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] + && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] + && [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] + && [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID]); } #pragma mark - NSCoding diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m b/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m index bb853bf894..a3a61aada4 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m @@ -21,9 +21,9 @@ #import #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKShareConstants.h" @@ -111,12 +111,12 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToSharePhoto:(FBSDKSharePhoto *)photo { - return (photo && - (_userGenerated == photo.userGenerated) && - [FBSDKInternalUtility object:_image isEqualToObject:photo.image] && - [FBSDKInternalUtility object:_imageURL isEqualToObject:photo.imageURL] && - [FBSDKInternalUtility object:_photoAsset isEqualToObject:photo.photoAsset] && - [FBSDKInternalUtility object:_caption isEqualToObject:photo.caption]); + return (photo + && (_userGenerated == photo.userGenerated) + && [FBSDKInternalUtility object:_image isEqualToObject:photo.image] + && [FBSDKInternalUtility object:_imageURL isEqualToObject:photo.imageURL] + && [FBSDKInternalUtility object:_photoAsset isEqualToObject:photo.photoAsset] + && [FBSDKInternalUtility object:_caption isEqualToObject:photo.caption]); } #pragma mark - FBSDKSharingValidation diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.m index 4869bb091c..e66fce116a 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.m @@ -21,9 +21,9 @@ #import #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKHashtag.h" #import "FBSDKSharePhoto.h" @@ -119,8 +119,8 @@ - (void)setPhotos:(NSArray *)photos } if (images.count > 0) { [FBSDKTypeUtility dictionary:updatedParameters - setObject:images - forKey:@"photos"]; + setObject:images + forKey:@"photos"]; } return updatedParameters; @@ -171,15 +171,15 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)content { - return (content && - [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && - [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && - [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && - [FBSDKInternalUtility object:_photos isEqualToObject:content.photos] && - [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && - [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] && - [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] && - [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID]); + return (content + && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] + && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] + && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] + && [FBSDKInternalUtility object:_photos isEqualToObject:content.photos] + && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] + && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] + && [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] + && [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID]); } #pragma mark - NSCoding diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m index 72aeae494b..c5e9153bec 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m @@ -19,9 +19,9 @@ #import "FBSDKShareVideo.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKShareConstants.h" #import "FBSDKSharePhoto.h" @@ -133,11 +133,11 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToShareVideo:(FBSDKShareVideo *)video { - return (video && - [FBSDKInternalUtility object:_data isEqualToObject:video.data] && - [FBSDKInternalUtility object:_videoAsset isEqualToObject:video.videoAsset] && - [FBSDKInternalUtility object:_videoURL isEqualToObject:video.videoURL] && - [FBSDKInternalUtility object:_previewPhoto isEqualToObject:video.previewPhoto]); + return (video + && [FBSDKInternalUtility object:_data isEqualToObject:video.data] + && [FBSDKInternalUtility object:_videoAsset isEqualToObject:video.videoAsset] + && [FBSDKInternalUtility object:_videoURL isEqualToObject:video.videoURL] + && [FBSDKInternalUtility object:_previewPhoto isEqualToObject:video.previewPhoto]); } #pragma mark - FBSDKSharingValidation diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.m index 66afc3810b..7521820928 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.m @@ -21,9 +21,9 @@ #import #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKHashtag.h" #import "FBSDKShareUtility.h" @@ -83,47 +83,47 @@ - (void)setPeopleIDs:(NSArray *)peopleIDs if (bridgeOptions & FBSDKShareBridgeOptionsVideoAsset) { // bridge the PHAsset.localIdentifier [FBSDKTypeUtility dictionary:videoParameters - setObject:_video.videoAsset.localIdentifier - forKey:@"assetIdentifier"]; + setObject:_video.videoAsset.localIdentifier + forKey:@"assetIdentifier"]; } else { // bridge the legacy "assets-library" URL from AVAsset [FBSDKTypeUtility dictionary:videoParameters - setObject:_video.videoAsset.videoURL - forKey:@"assetURL"]; + setObject:_video.videoAsset.videoURL + forKey:@"assetURL"]; } } else if (_video.data) { if (bridgeOptions & FBSDKShareBridgeOptionsVideoData) { // bridge the data [FBSDKTypeUtility dictionary:videoParameters - setObject:_video.data - forKey:@"data"]; + setObject:_video.data + forKey:@"data"]; } } else if (_video.videoURL) { if ([_video.videoURL.scheme.lowercaseString isEqualToString:@"assets-library"]) { // bridge the legacy "assets-library" URL [FBSDKTypeUtility dictionary:videoParameters - setObject:_video.videoURL - forKey:@"assetURL"]; + setObject:_video.videoURL + forKey:@"assetURL"]; } else if (_video.videoURL.isFileURL) { if (bridgeOptions & FBSDKShareBridgeOptionsVideoData) { // load the contents of the file and bridge the data NSData *data = [NSData dataWithContentsOfURL:_video.videoURL options:NSDataReadingMappedIfSafe error:NULL]; [FBSDKTypeUtility dictionary:videoParameters - setObject:data - forKey:@"data"]; + setObject:data + forKey:@"data"]; } } } if (_video.previewPhoto) { [FBSDKTypeUtility dictionary:videoParameters - setObject:[FBSDKShareUtility convertPhoto:_video.previewPhoto] - forKey:@"previewPhoto"]; + setObject:[FBSDKShareUtility convertPhoto:_video.previewPhoto] + forKey:@"previewPhoto"]; } [FBSDKTypeUtility dictionary:updatedParameters - setObject:videoParameters - forKey:@"video"]; + setObject:videoParameters + forKey:@"video"]; return updatedParameters; } @@ -168,15 +168,15 @@ - (BOOL)isEqual:(id)object - (BOOL)isEqualToShareVideoContent:(FBSDKShareVideoContent *)content { - return (content && - [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && - [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && - [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && - [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && - [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] && - [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID] && - [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] && - [FBSDKInternalUtility object:_video isEqualToObject:content.video]); + return (content + && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] + && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] + && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] + && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] + && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] + && [FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID] + && [FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] + && [FBSDKInternalUtility object:_video isEqualToObject:content.video]); } #pragma mark - NSCoding diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectArguments+Internal.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectArguments+Internal.h index dd93c7861f..2419720b89 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectArguments+Internal.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectArguments+Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKCameraEffectArguments.h" + #import "FBSDKCameraEffectArguments.h" @interface FBSDKCameraEffectArguments () diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectTextures+Internal.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectTextures+Internal.h index 9abab1d7c2..e5e1b90f66 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectTextures+Internal.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCameraEffectTextures+Internal.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKCameraEffectTextures.h" + #import "FBSDKCameraEffectTextures.h" @interface FBSDKCameraEffectTextures () diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.m index 2b1d9027d6..0bef89d2f6 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKCheckmarkIcon.h" + #import "FBSDKCheckmarkIcon.h" @implementation FBSDKCheckmarkIcon diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCoreKitInternalImport.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCoreKitInternalImport.h new file mode 100644 index 0000000000..2e3713615b --- /dev/null +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCoreKitInternalImport.h @@ -0,0 +1,26 @@ +// 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. + +// Importing FBSDKCoreKit+Internal is tricky due to build variants. +// SPM, xcodebuild, and BUCK require that it is imported as "FBSDKCoreKit+Internal.h" +// CocoaPods requires that is is imported as +#if defined FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m index 4776c79c7c..b42939200d 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m @@ -20,26 +20,26 @@ #if !TARGET_OS_TV -#import "FBSDKGameRequestFrictionlessRecipientCache.h" + #import "FBSDKGameRequestFrictionlessRecipientCache.h" -#if defined BUCK || defined FBSDKCOCOAPODS -#import -#else + #if defined BUCK || defined FBSDKCOCOAPODS + #import + #else @import FBSDKCoreKit; -#endif + #endif -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif @implementation FBSDKGameRequestFrictionlessRecipientCache { NSSet *_recipientIDs; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)init { @@ -58,7 +58,7 @@ - (void)dealloc [[NSNotificationCenter defaultCenter] removeObserver:self]; } -#pragma mark - Public API + #pragma mark - Public API - (BOOL)recipientsAreFrictionless:(id)recipients { @@ -85,7 +85,7 @@ - (void)updateWithResults:(NSDictionary *)results } } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { @@ -103,9 +103,9 @@ - (void)_updateCache return; } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/apprequestformerrecipients" - parameters:@{@"fields":@""} - flags:(FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | - FBSDKGraphRequestFlagDisableErrorRecovery)]; + parameters:@{@"fields" : @""} + flags:(FBSDKGraphRequestFlagDoNotInvalidateTokenOnError + | FBSDKGraphRequestFlagDisableErrorRecovery)]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { NSArray *items = [FBSDKTypeUtility arrayValue:result[@"data"]]; diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m index 0628bd3198..dd95f9d43c 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m @@ -20,83 +20,81 @@ #if !TARGET_OS_TV -#import "FBSDKLikeActionController.h" + #import "FBSDKLikeActionController.h" -#import + #import -#if defined BUCK || defined FBSDKCOCOAPODS -#import -#else + #if defined BUCK || defined FBSDKCOCOAPODS + #import + #else @import FBSDKCoreKit; -#endif + #endif -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKLikeActionControllerCache.h" -#import "FBSDKLikeDialog.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKLikeActionControllerCache.h" + #import "FBSDKLikeDialog.h" -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSNotificationName const FBSDKLikeActionControllerDidDisableNotification = @"FBSDKLikeActionControllerDidDisableNotification"; NSNotificationName const FBSDKLikeActionControllerDidResetNotification = @"FBSDKLikeActionControllerDidResetNotification"; NSNotificationName const FBSDKLikeActionControllerDidUpdateNotification = @"FBSDKLikeActionControllerDidUpdateNotification"; -#else + #else NSString *const FBSDKLikeActionControllerDidDisableNotification = @"FBSDKLikeActionControllerDidDisableNotification"; NSString *const FBSDKLikeActionControllerDidResetNotification = @"FBSDKLikeActionControllerDidResetNotification"; NSString *const FBSDKLikeActionControllerDidUpdateNotification = @"FBSDKLikeActionControllerDidUpdateNotification"; -#endif + #endif NSString *const FBSDKLikeActionControllerAnimatedKey = @"animated"; -#define FBSDK_LIKE_ACTION_CONTROLLER_ANIMATION_DELAY 0.5 -#define FBSDK_LIKE_ACTION_CONTROLLER_SOUND_DELAY 0.15 -#define FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION @"v2.1" + #define FBSDK_LIKE_ACTION_CONTROLLER_ANIMATION_DELAY 0.5 + #define FBSDK_LIKE_ACTION_CONTROLLER_SOUND_DELAY 0.15 + #define FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION @"v2.1" -#define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY @"like" -#define FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY @"refresh" + #define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY @"like" + #define FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY @"refresh" -#define FBSDK_LIKE_ACTION_CONTROLLER_LAST_UPDATE_TIME_KEY @"lastUpdateTime" -#define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITH_LIKE_KEY @"likeCountStringWithLike" -#define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITHOUT_LIKE_KEY @"likeCountStringWithoutLike" -#define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_ID_KEY @"objectID" -#define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_IS_LIKED_KEY @"objectIsLiked" -#define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_TYPE_KEY @"objectType" -#define FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITH_LIKE_KEY @"socialSentenceWithLike" -#define FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITHOUT_LIKE_KEY @"socialSentenceWithoutLike" -#define FBSDK_LIKE_ACTION_CONTROLLER_UNLIKE_TOKEN_KEY @"unlikeToken" -#define FBSDK_LIKE_ACTION_CONTROLLER_VERSION_KEY @"version" + #define FBSDK_LIKE_ACTION_CONTROLLER_LAST_UPDATE_TIME_KEY @"lastUpdateTime" + #define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITH_LIKE_KEY @"likeCountStringWithLike" + #define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITHOUT_LIKE_KEY @"likeCountStringWithoutLike" + #define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_ID_KEY @"objectID" + #define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_IS_LIKED_KEY @"objectIsLiked" + #define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_TYPE_KEY @"objectType" + #define FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITH_LIKE_KEY @"socialSentenceWithLike" + #define FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITHOUT_LIKE_KEY @"socialSentenceWithoutLike" + #define FBSDK_LIKE_ACTION_CONTROLLER_UNLIKE_TOKEN_KEY @"unlikeToken" + #define FBSDK_LIKE_ACTION_CONTROLLER_VERSION_KEY @"version" -#define FBSDK_LIKE_ACTION_CONTROLLER_VERSION 4 + #define FBSDK_LIKE_ACTION_CONTROLLER_VERSION 4 -typedef NS_ENUM(NSUInteger, FBSDKLikeActionControllerRefreshMode) -{ +typedef NS_ENUM(NSUInteger, FBSDKLikeActionControllerRefreshMode) { FBSDKLikeActionControllerRefreshModeInitial, FBSDKLikeActionControllerRefreshModeForce, }; -typedef NS_ENUM(NSUInteger, FBSDKLikeActionControllerRefreshState) -{ +typedef NS_ENUM(NSUInteger, FBSDKLikeActionControllerRefreshState) { FBSDKLikeActionControllerRefreshStateNone, FBSDKLikeActionControllerRefreshStateActive, FBSDKLikeActionControllerRefreshStateComplete, }; -typedef void(^fbsdk_like_action_block)(FBSDKTriStateBOOL objectIsLiked, - NSString *likeCountStringWithLike, - NSString *likeCountStringWithoutLike, - NSString *socialSentenceWithLike, - NSString *socialSentenceWithoutLike, - NSString *unlikeToken, - BOOL likeStateChanged, - BOOL animated); +typedef void (^fbsdk_like_action_block)(FBSDKTriStateBOOL objectIsLiked, + NSString *likeCountStringWithLike, + NSString *likeCountStringWithoutLike, + NSString *socialSentenceWithLike, + NSString *socialSentenceWithoutLike, + NSString *unlikeToken, + BOOL likeStateChanged, + BOOL animated); -typedef void(^fbsdk_like_action_controller_ensure_verified_object_id_completion_block)(NSString *verifiedObjectID); +typedef void (^fbsdk_like_action_controller_ensure_verified_object_id_completion_block)(NSString *verifiedObjectID); @interface FBSDKLikeActionController () @end @@ -120,7 +118,7 @@ @implementation FBSDKLikeActionController NSString *_verifiedObjectID; } -#pragma mark - Class Methods + #pragma mark - Class Methods static BOOL _fbsdkLikeActionControllerDisabled = YES; @@ -139,17 +137,16 @@ + (void)initialize NSURL *fileURL = [self _cacheFileURL]; NSData *data = [[NSData alloc] initWithContentsOfURL:fileURL]; if (data) { - #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0 - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:NULL]; - #else - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - #endif + #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0 + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:NULL]; + #else + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + #endif unarchiver.requiresSecureCoding = YES; @try { _cache = [unarchiver decodeObjectOfClass:[FBSDKLikeActionControllerCache class] forKey:NSKeyedArchiveRootObjectKey]; - } - @catch (NSException *ex) { + } @catch (NSException *ex) { // ignore decoding exceptions from previous versions of the archive, etc } if (![_cache.accessTokenString isEqualToString:accessTokenString]) { @@ -210,7 +207,6 @@ + (NSURL *)_cacheFileURL return [directoryURL URLByAppendingPathComponent:@"com-facebook-sdk-like-data"]; } - + (instancetype)likeActionControllerForObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType { if (!objectID) { @@ -230,7 +226,7 @@ + (instancetype)likeActionControllerForObjectID:(NSString *)objectID objectType: } } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType @@ -251,7 +247,7 @@ - (instancetype)init return [self initWithObjectID:nil objectType:FBSDKLikeObjectTypeUnknown accessToken:nil]; } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -306,7 +302,7 @@ - (void)encodeWithCoder:(NSCoder *)coder [coder encodeInteger:FBSDK_LIKE_ACTION_CONTROLLER_VERSION forKey:FBSDK_LIKE_ACTION_CONTROLLER_VERSION_KEY]; } -#pragma mark - Properties + #pragma mark - Properties - (NSString *)likeCountString { @@ -318,14 +314,14 @@ - (NSString *)socialSentence return (_objectIsLiked ? _socialSentenceWithLike : _socialSentenceWithoutLike); } -#pragma mark - Public API + #pragma mark - Public API - (void)refresh { [self _refreshWithMode:FBSDKLikeActionControllerRefreshModeForce]; } -#pragma mark - NSDiscardableContent + #pragma mark - NSDiscardableContent - (BOOL)beginContentAccess { @@ -351,7 +347,7 @@ - (BOOL)isContentDiscarded return _contentDiscarded; } -#pragma mark - FBSDKLikeDialogDelegate + #pragma mark - FBSDKLikeDialogDelegate - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didCompleteWithResults:(NSDictionary *)results { @@ -365,14 +361,16 @@ - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didCompleteWithResults:(NSDicti if (updateBlock != NULL) { // we do not need to specify values for with/without like, since we will fast-app-switch to change // the value - updateBlock(objectIsLiked, - likeCountString, - likeCountString, - socialSentence, - socialSentence, - unlikeToken, - likeStateChanged, - YES); + updateBlock( + objectIsLiked, + likeCountString, + likeCountString, + socialSentence, + socialSentence, + unlikeToken, + likeStateChanged, + YES + ); } [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY]; } @@ -399,14 +397,14 @@ - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didFailWithError:(NSError *)err [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_configure { NSPointerFunctionsOptions keyOptions = (NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality); - NSPointerFunctionsOptions valueOptions = (NSPointerFunctionsStrongMemory | - NSPointerFunctionsObjectPersonality | - NSPointerFunctionsCopyIn); + NSPointerFunctionsOptions valueOptions = (NSPointerFunctionsStrongMemory + | NSPointerFunctionsObjectPersonality + | NSPointerFunctionsCopyIn); _dialogToAnalyticsParametersMap = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; _dialogToUpdateBlockMap = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; @@ -420,25 +418,25 @@ static void FBSDKLikeActionControllerLogError(NSString *currentAction, NSError *error) { NSDictionary *parameters = @{ - @"object_id": objectID, - @"object_type": NSStringFromFBSDKLikeObjectType(objectType), - @"current_action": currentAction, - @"error": error.description ?: @"", - }; - NSString *eventName = ([FBSDKError isNetworkError:error] ? - FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable : - FBSDKAppEventNameFBSDKLikeControlError); + @"object_id" : objectID, + @"object_type" : NSStringFromFBSDKLikeObjectType(objectType), + @"current_action" : currentAction, + @"error" : error.description ?: @"", + }; + NSString *eventName = ([FBSDKError isNetworkError:error] + ? FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable + : FBSDKAppEventNameFBSDKLikeControlError); [FBSDKAppEvents logInternalEvent:eventName parameters:parameters isImplicitlyLogged:YES accessToken:accessToken]; } -typedef void(^fbsdk_like_action_controller_get_engagement_completion_block)(BOOL success, - NSString *likeCountStringWithLike, - NSString *likeCountStringWithoutLike, - NSString *socialSentenceWithLike, - NSString *socialSentenceWithoutLike); +typedef void (^fbsdk_like_action_controller_get_engagement_completion_block)(BOOL success, + NSString *likeCountStringWithLike, + NSString *likeCountStringWithoutLike, + NSString *socialSentenceWithLike, + NSString *socialSentenceWithoutLike); static void FBSDKLikeActionControllerAddGetEngagementRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, @@ -451,9 +449,8 @@ static void FBSDKLikeActionControllerAddGetEngagementRequest(FBSDKAccessToken *a NSString *fields = @"engagement.fields(count_string_with_like,count_string_without_like,social_sentence_with_like," @"social_sentence_without_like)"; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:objectID - parameters:@{ @"fields": fields, - @"locale": [NSLocale currentLocale].localeIdentifier - } + parameters:@{ @"fields" : fields, + @"locale" : [NSLocale currentLocale].localeIdentifier} tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -478,17 +475,19 @@ static void FBSDKLikeActionControllerAddGetEngagementRequest(FBSDKAccessToken *a socialSentenceWithLike = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"engagement.social_sentence_with_like"]]; socialSentenceWithoutLike = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"engagement.social_sentence_without_like"]]; } - completionHandler(success, - likeCountStringWithLike, - likeCountStringWithoutLike, - socialSentenceWithLike, - socialSentenceWithoutLike); + completionHandler( + success, + likeCountStringWithLike, + likeCountStringWithoutLike, + socialSentenceWithLike, + socialSentenceWithoutLike + ); }]; } -typedef void(^fbsdk_like_action_controller_get_object_id_completion_block)(BOOL success, - NSString *verifiedObjectID, - BOOL objectIsPage); +typedef void (^fbsdk_like_action_controller_get_object_id_completion_block)(BOOL success, + NSString *verifiedObjectID, + BOOL objectIsPage); static void FBSDKLikeActionControllerAddGetObjectIDRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, @@ -499,12 +498,12 @@ static void FBSDKLikeActionControllerAddGetObjectIDRequest(FBSDKAccessToken *acc } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"" parameters:@{ - @"fields": @"id", - @"id": objectID, - @"metadata": @"1", - @"type": @"og", - @"locale": [NSLocale currentLocale].localeIdentifier - } + @"fields" : @"id", + @"id" : objectID, + @"metadata" : @"1", + @"type" : @"og", + @"locale" : [NSLocale currentLocale].localeIdentifier + } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -527,10 +526,10 @@ static void FBSDKLikeActionControllerAddGetObjectIDWithObjectURLRequest(FBSDKAcc } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"" parameters:@{ - @"fields": @"og_object.fields(id)", - @"id": objectID, - @"locale": [NSLocale currentLocale].localeIdentifier - } + @"fields" : @"og_object.fields(id)", + @"id" : objectID, + @"locale" : [NSLocale currentLocale].localeIdentifier + } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -541,9 +540,9 @@ static void FBSDKLikeActionControllerAddGetObjectIDWithObjectURLRequest(FBSDKAcc }]; } -typedef void(^fbsdk_like_action_controller_get_og_object_like_completion_block)(BOOL success, - FBSDKTriStateBOOL objectIsLiked, - NSString *unlikeToken); +typedef void (^fbsdk_like_action_controller_get_og_object_like_completion_block)(BOOL success, + FBSDKTriStateBOOL objectIsLiked, + NSString *unlikeToken); static void FBSDKLikeActionControllerAddGetOGObjectLikeRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, @@ -555,10 +554,10 @@ static void FBSDKLikeActionControllerAddGetOGObjectLikeRequest(FBSDKAccessToken } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/og.likes" parameters:@{ - @"fields": @"id,application", - @"object": objectID, - @"locale": [NSLocale currentLocale].localeIdentifier - } + @"fields" : @"id,application", + @"object" : objectID, + @"locale" : [NSLocale currentLocale].localeIdentifier + } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -588,7 +587,7 @@ static void FBSDKLikeActionControllerAddGetOGObjectLikeRequest(FBSDKAccessToken }]; } -typedef void(^fbsdk_like_action_controller_publish_like_completion_block)(BOOL success, NSString *unlikeToken); +typedef void (^fbsdk_like_action_controller_publish_like_completion_block)(BOOL success, NSString *unlikeToken); static void FBSDKLikeActionControllerAddPublishLikeRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, @@ -596,9 +595,8 @@ static void FBSDKLikeActionControllerAddPublishLikeRequest(FBSDKAccessToken *acc fbsdk_like_action_controller_publish_like_completion_block completionHandler) { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/og.likes" - parameters:@{ @"object": objectID, - @"locale": [NSLocale currentLocale].localeIdentifier - } + parameters:@{ @"object" : objectID, + @"locale" : [NSLocale currentLocale].localeIdentifier} tokenString:accessToken.tokenString version:nil HTTPMethod:@"POST"]; @@ -620,7 +618,7 @@ static void FBSDKLikeActionControllerAddPublishLikeRequest(FBSDKAccessToken *acc }]; } -typedef void(^fbsdk_like_action_controller_publish_unlike_completion_block)(BOOL success); +typedef void (^fbsdk_like_action_controller_publish_unlike_completion_block)(BOOL success); static void FBSDKLikeActionControllerAddPublishUnlikeRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *unlikeToken, @@ -663,15 +661,17 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access __block NSString *socialSentenceWithoutLike = nil; __block NSString *unlikeToken = nil; - void(^handleResults)(void) = ^{ - completionHandler(objectIsLiked, - likeCountStringWithLike, - likeCountStringWithoutLike, - socialSentenceWithLike, - socialSentenceWithoutLike, - unlikeToken, - NO, - NO); + void (^handleResults)(void) = ^{ + completionHandler( + objectIsLiked, + likeCountStringWithLike, + likeCountStringWithoutLike, + socialSentenceWithLike, + socialSentenceWithoutLike, + unlikeToken, + NO, + NO + ); }; fbsdk_like_action_controller_get_og_object_like_completion_block getLikeStateCompletionBlock = ^(BOOL success, @@ -684,11 +684,13 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access } } }; - FBSDKLikeActionControllerAddGetOGObjectLikeRequest(accessToken, - connection, - objectID, - objectType, - getLikeStateCompletionBlock); + FBSDKLikeActionControllerAddGetOGObjectLikeRequest( + accessToken, + connection, + objectID, + objectType, + getLikeStateCompletionBlock + ); fbsdk_like_action_controller_get_engagement_completion_block engagementCompletionBlock = ^(BOOL success, NSString *innerLikeCountStringWithLike, @@ -705,14 +707,15 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access handleResults(); } }; - FBSDKLikeActionControllerAddGetEngagementRequest(accessToken, - connection, - objectID, - objectType, - engagementCompletionBlock); + FBSDKLikeActionControllerAddGetEngagementRequest( + accessToken, + connection, + objectID, + objectType, + engagementCompletionBlock + ); } - - (void)_ensureVerifiedObjectID:(fbsdk_like_action_controller_ensure_verified_object_id_completion_block)completion { if (completion == NULL) { @@ -721,31 +724,35 @@ - (void)_ensureVerifiedObjectID:(fbsdk_like_action_controller_ensure_verified_ob FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection overrideGraphAPIVersion:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; if ([_objectID rangeOfString:@"://"].location != NSNotFound) { - FBSDKLikeActionControllerAddGetObjectIDWithObjectURLRequest(_accessToken, connection, _objectID, ^(BOOL success, - NSString *innerVerifiedObjectID, - BOOL innerObjectIsPage) { - if (success) { - self->_verifiedObjectID = [innerVerifiedObjectID copy]; - self->_objectIsPage = innerObjectIsPage; - } - }); + FBSDKLikeActionControllerAddGetObjectIDWithObjectURLRequest(_accessToken, + connection, + _objectID, ^(BOOL success, + NSString *innerVerifiedObjectID, + BOOL innerObjectIsPage) { + if (success) { + self->_verifiedObjectID = [innerVerifiedObjectID copy]; + self->_objectIsPage = innerObjectIsPage; + } + }); } - FBSDKLikeActionControllerAddGetObjectIDRequest(_accessToken, connection, _objectID, ^(BOOL success, - NSString *innerVerifiedObjectID, - BOOL innerObjectIsPage) { - if (success) { - // if this was an URL based request, then we want to use the objectID from that request - this value will just - // be an echo of the URL - if (!self->_verifiedObjectID) { - self->_verifiedObjectID = [innerVerifiedObjectID copy]; - } - self->_objectIsPage = innerObjectIsPage; - } - if (self->_verifiedObjectID) { - completion(self->_verifiedObjectID); - } - }); + FBSDKLikeActionControllerAddGetObjectIDRequest(_accessToken, + connection, + _objectID, ^(BOOL success, + NSString *innerVerifiedObjectID, + BOOL innerObjectIsPage) { + if (success) { + // if this was an URL based request, then we want to use the objectID from that request - this value will just + // be an echo of the URL + if (!self->_verifiedObjectID) { + self->_verifiedObjectID = [innerVerifiedObjectID copy]; + } + self->_objectIsPage = innerObjectIsPage; + } + if (self->_verifiedObjectID) { + completion(self->_verifiedObjectID); + } + }); [connection start]; } @@ -793,34 +800,38 @@ - (void)_publishLikeWithUpdateBlock:(fbsdk_like_action_block)updateBlock [connection overrideGraphAPIVersion:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; fbsdk_like_action_controller_publish_like_completion_block completionHandler = ^(BOOL success, NSString *unlikeToken) { - self->_objectIsLikedIsPending = NO; - if (success) { - [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameFBSDKLikeControlDidLike - parameters:analyticsParameters - isImplicitlyLogged:YES - accessToken:self->_accessToken]; - self->_objectIsLikedOnServer = YES; - self->_unlikeToken = [unlikeToken copy]; - if (updateBlock != NULL) { - updateBlock(FBSDKTriStateBOOLFromBOOL(self.objectIsLiked), - self->_likeCountStringWithLike, - self->_likeCountStringWithoutLike, - self->_socialSentenceWithLike, - self->_socialSentenceWithoutLike, - self->_unlikeToken, - NO, - NO); - } - [self _publishIfNeededWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; - } else { - [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; - } - }; - FBSDKLikeActionControllerAddPublishLikeRequest(self->_accessToken, - connection, - verifiedObjectID, - self->_objectType, - completionHandler); + self->_objectIsLikedIsPending = NO; + if (success) { + [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameFBSDKLikeControlDidLike + parameters:analyticsParameters + isImplicitlyLogged:YES + accessToken:self->_accessToken]; + self->_objectIsLikedOnServer = YES; + self->_unlikeToken = [unlikeToken copy]; + if (updateBlock != NULL) { + updateBlock( + FBSDKTriStateBOOLFromBOOL(self.objectIsLiked), + self->_likeCountStringWithLike, + self->_likeCountStringWithoutLike, + self->_socialSentenceWithLike, + self->_socialSentenceWithoutLike, + self->_unlikeToken, + NO, + NO + ); + } + [self _publishIfNeededWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; + } else { + [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; + } + }; + FBSDKLikeActionControllerAddPublishLikeRequest( + self->_accessToken, + connection, + verifiedObjectID, + self->_objectType, + completionHandler + ); [connection start]; }]; } @@ -842,39 +853,43 @@ - (void)_publishUnlikeWithUpdateBlock:(fbsdk_like_action_block)updateBlock self->_objectIsLikedOnServer = NO; self->_unlikeToken = nil; if (updateBlock != NULL) { - updateBlock(FBSDKTriStateBOOLFromBOOL(self.objectIsLiked), - self->_likeCountStringWithLike, - self->_likeCountStringWithoutLike, - self->_socialSentenceWithLike, - self->_socialSentenceWithoutLike, - self->_unlikeToken, - NO, - NO); + updateBlock( + FBSDKTriStateBOOLFromBOOL(self.objectIsLiked), + self->_likeCountStringWithLike, + self->_likeCountStringWithoutLike, + self->_socialSentenceWithLike, + self->_socialSentenceWithoutLike, + self->_unlikeToken, + NO, + NO + ); } [self _publishIfNeededWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } else { [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } }; - FBSDKLikeActionControllerAddPublishUnlikeRequest(_accessToken, - connection, - _unlikeToken, - _objectType, - completionHandler); + FBSDKLikeActionControllerAddPublishUnlikeRequest( + _accessToken, + connection, + _unlikeToken, + _objectType, + completionHandler + ); [connection start]; } - (void)_refreshWithMode:(FBSDKLikeActionControllerRefreshMode)mode { switch (mode) { - case FBSDKLikeActionControllerRefreshModeForce:{ + case FBSDKLikeActionControllerRefreshModeForce: { // if we're already refreshing, skip if (_refreshState == FBSDKLikeActionControllerRefreshStateActive) { return; } break; } - case FBSDKLikeActionControllerRefreshModeInitial:{ + case FBSDKLikeActionControllerRefreshModeInitial: { // if we've already started any refresh, skip this if (_refreshState != FBSDKLikeActionControllerRefreshStateNone) { return; @@ -895,28 +910,28 @@ - (void)_refreshWithMode:(FBSDKLikeActionControllerRefreshMode)mode FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection overrideGraphAPIVersion:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; FBSDKLikeActionControllerAddRefreshRequests(self->_accessToken, - connection, - verifiedObjectID, - self->_objectType, - ^(FBSDKTriStateBOOL objectIsLiked, - NSString *likeCountStringWithLike, - NSString *likeCountStringWithoutLike, - NSString *socialSentenceWithLike, - NSString *socialSentenceWithoutLike, - NSString *unlikeToken, - BOOL likeStateChanged, - BOOL animated) { - [self _updateWithObjectIsLiked:objectIsLiked - likeCountStringWithLike:likeCountStringWithLike - likeCountStringWithoutLike:likeCountStringWithoutLike - socialSentenceWithLike:socialSentenceWithLike - socialSentenceWithoutLike:socialSentenceWithoutLike - unlikeToken:unlikeToken - animated:NO - deferred:NO]; - [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY]; - self->_refreshState = FBSDKLikeActionControllerRefreshStateComplete; - }); + connection, + verifiedObjectID, + self->_objectType, + ^(FBSDKTriStateBOOL objectIsLiked, + NSString *likeCountStringWithLike, + NSString *likeCountStringWithoutLike, + NSString *socialSentenceWithLike, + NSString *socialSentenceWithoutLike, + NSString *unlikeToken, + BOOL likeStateChanged, + BOOL animated) { + [self _updateWithObjectIsLiked:objectIsLiked + likeCountStringWithLike:likeCountStringWithLike + likeCountStringWithoutLike:likeCountStringWithoutLike + socialSentenceWithLike:socialSentenceWithLike + socialSentenceWithoutLike:socialSentenceWithoutLike + unlikeToken:unlikeToken + animated:NO + deferred:NO]; + [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY]; + self->_refreshState = FBSDKLikeActionControllerRefreshStateComplete; + }); [connection start]; }]; } @@ -963,17 +978,17 @@ - (void)_updateWithObjectIsLiked:(FBSDKTriStateBOOL)objectIsLikedTriState // If the new like state is unknown, we don't consider the state to have changed. BOOL objectIsLikedChanged = (objectIsLikedTriState != FBSDKTriStateBOOLValueUnknown) && (self.objectIsLiked != objectIsLiked); - if (!objectIsLikedChanged && - [FBSDKInternalUtility object:_likeCountStringWithLike isEqualToObject:likeCountStringWithLike] && - [FBSDKInternalUtility object:_likeCountStringWithoutLike isEqualToObject:likeCountStringWithoutLike] && - [FBSDKInternalUtility object:_socialSentenceWithLike isEqualToObject:socialSentenceWithLike] && - [FBSDKInternalUtility object:_socialSentenceWithoutLike isEqualToObject:socialSentenceWithoutLike] && - [FBSDKInternalUtility object:_unlikeToken isEqualToObject:unlikeToken]) { + if (!objectIsLikedChanged + && [FBSDKInternalUtility object:_likeCountStringWithLike isEqualToObject:likeCountStringWithLike] + && [FBSDKInternalUtility object:_likeCountStringWithoutLike isEqualToObject:likeCountStringWithoutLike] + && [FBSDKInternalUtility object:_socialSentenceWithLike isEqualToObject:socialSentenceWithLike] + && [FBSDKInternalUtility object:_socialSentenceWithoutLike isEqualToObject:socialSentenceWithoutLike] + && [FBSDKInternalUtility object:_unlikeToken isEqualToObject:unlikeToken]) { // check if the like state changed and only animate if it did return; } - void(^updateBlock)(void) = ^{ + void (^updateBlock)(void) = ^{ if (objectIsLikedChanged) { self->_objectIsLiked = objectIsLiked; } @@ -994,8 +1009,8 @@ - (void)_updateWithObjectIsLiked:(FBSDKTriStateBOOL)objectIsLikedTriState self->_unlikeToken = [unlikeToken copy]; } - void(^notificationBlock)(void) = ^{ - NSDictionary *userInfo = @{FBSDKLikeActionControllerAnimatedKey: @(animated)}; + void (^notificationBlock)(void) = ^{ + NSDictionary *userInfo = @{FBSDKLikeActionControllerAnimatedKey : @(animated)}; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKLikeActionControllerDidUpdateNotification object:self userInfo:userInfo]; @@ -1016,10 +1031,10 @@ - (void)_updateWithObjectIsLiked:(FBSDKTriStateBOOL)objectIsLikedTriState - (BOOL)_useOGLike { - return (_accessToken && - !_objectIsPage && - _verifiedObjectID && - [_accessToken.permissions containsObject:@"publish_actions"]); + return (_accessToken + && !_objectIsPage + && _verifiedObjectID + && [_accessToken.permissions containsObject:@"publish_actions"]); } @end diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.m index adad1db4ec..8b9a115dbc 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.m @@ -20,18 +20,18 @@ #if !TARGET_OS_TV -#import "FBSDKLikeActionControllerCache.h" + #import "FBSDKLikeActionControllerCache.h" -#import + #import -#import "FBSDKLikeActionController.h" -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKitInternalImport.h" + #import "FBSDKLikeActionController.h" // after 1 day, expire the cached states -#define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT 60 * 24 + #define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT 60 * 24 -#define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY @"accessTokenString" -#define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY @"items" + #define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY @"accessTokenString" + #define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY @"items" @implementation FBSDKLikeActionControllerCache { @@ -39,7 +39,7 @@ @implementation FBSDKLikeActionControllerCache NSMutableDictionary *_items; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithAccessTokenString:(NSString *)accessTokenString { @@ -50,7 +50,7 @@ - (instancetype)initWithAccessTokenString:(NSString *)accessTokenString return self; } -#pragma mark - NSCoding + #pragma mark - NSCoding + (BOOL)supportsSecureCoding { @@ -77,7 +77,7 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:_items forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY]; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (id)objectForKeyedSubscript:(id)key { @@ -95,20 +95,20 @@ - (void)setObject:(id)object forKeyedSubscript:(id)key [FBSDKTypeUtility dictionary:_items setObject:object forKey:key]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_prune { NSMutableArray *keysToRemove = [[NSMutableArray alloc] init]; [FBSDKTypeUtility dictionary:_items enumerateKeysAndObjectsUsingBlock:^(NSString *objectID, - FBSDKLikeActionController *likeActionController, - BOOL *stop) { - NSDate *lastUpdateTime = likeActionController.lastUpdateTime; - if (!lastUpdateTime || - ([[NSDate date] timeIntervalSinceDate:lastUpdateTime] > FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT)) { - [keysToRemove addObject:objectID]; - } - }]; + FBSDKLikeActionController *likeActionController, + BOOL *stop) { + NSDate *lastUpdateTime = likeActionController.lastUpdateTime; + if (!lastUpdateTime + || ([[NSDate date] timeIntervalSinceDate:lastUpdateTime] > FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT)) { + [keysToRemove addObject:objectID]; + } + }]; [_items removeObjectsForKeys:keysToRemove]; } diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.m index 937a98a7ea..ec63e96d03 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.m @@ -20,22 +20,22 @@ #if !TARGET_OS_TV -#import "FBSDKLikeBoxBorderView.h" + #import "FBSDKLikeBoxBorderView.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif -#define FBSDK_LIKE_BOX_BORDER_CARET_WIDTH 6.0 -#define FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT 3.0 -#define FBSDK_LIKE_BOX_BORDER_CARET_PADDING 3.0 -#define FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING 4.0 + #define FBSDK_LIKE_BOX_BORDER_CARET_WIDTH 6.0 + #define FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT 3.0 + #define FBSDK_LIKE_BOX_BORDER_CARET_PADDING 3.0 + #define FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING 4.0 @implementation FBSDKLikeBoxBorderView -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { @@ -53,7 +53,7 @@ - (id)initWithCoder:(NSCoder *)decoder return self; } -#pragma mark - Properties + #pragma mark - Properties - (void)setBackgroundColor:(UIColor *)backgroundColor { @@ -93,10 +93,12 @@ - (void)setCaretPosition:(FBSDKLikeBoxCaretPosition)caretPosition - (UIEdgeInsets)contentInsets { UIEdgeInsets borderInsets = [self _borderInsets]; - return UIEdgeInsetsMake(borderInsets.top + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, - borderInsets.left + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, - borderInsets.bottom + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, - borderInsets.right + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING); + return UIEdgeInsetsMake( + borderInsets.top + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, + borderInsets.left + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, + borderInsets.bottom + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, + borderInsets.right + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING + ); } - (void)setContentView:(UIView *)contentView @@ -126,7 +128,7 @@ - (void)setForegroundColor:(UIColor *)foregroundColor } } -#pragma mark - Layout + #pragma mark - Layout - (CGSize)intrinsicContentSize { @@ -149,7 +151,7 @@ - (CGSize)sizeThatFits:(CGSize)size return size; } -#pragma mark - Drawing + #pragma mark - Drawing - (void)drawRect:(CGRect)rect { @@ -210,12 +212,18 @@ - (void)drawRect:(CGRect)rect switch (self.caretPosition) { case FBSDKLikeBoxCaretPositionTop: CGContextMoveToPoint(context, topRightArc[end].x, topRightArc[end].y); - caretPoints[0] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), - CGRectGetMinY(borderFrame)); - caretPoints[1] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)), - CGRectGetMinY(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT); - caretPoints[2] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), - CGRectGetMinY(borderFrame)); + caretPoints[0] = CGPointMake( + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), + CGRectGetMinY(borderFrame) + ); + caretPoints[1] = CGPointMake( + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)), + CGRectGetMinY(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + ); + caretPoints[2] = CGPointMake( + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), + CGRectGetMinY(borderFrame) + ); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y); @@ -227,12 +235,18 @@ - (void)drawRect:(CGRect)rect break; case FBSDKLikeBoxCaretPositionLeft: CGContextMoveToPoint(context, topLeftArc[end].x, topLeftArc[end].y); - caretPoints[0] = CGPointMake(CGRectGetMinX(borderFrame), - FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); - caretPoints[1] = CGPointMake(CGRectGetMinX(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT, - FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame))); - caretPoints[2] = CGPointMake(CGRectGetMinX(borderFrame), - FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); + caretPoints[0] = CGPointMake( + CGRectGetMinX(borderFrame), + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)) + ); + caretPoints[1] = CGPointMake( + CGRectGetMinX(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT, + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame)) + ); + caretPoints[2] = CGPointMake( + CGRectGetMinX(borderFrame), + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)) + ); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y); @@ -244,12 +258,18 @@ - (void)drawRect:(CGRect)rect break; case FBSDKLikeBoxCaretPositionBottom: CGContextMoveToPoint(context, bottomLeftArc[end].x, bottomLeftArc[end].y); - caretPoints[0] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), - CGRectGetMaxY(borderFrame)); - caretPoints[1] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)), - CGRectGetMaxY(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT); - caretPoints[2] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), - CGRectGetMaxY(borderFrame)); + caretPoints[0] = CGPointMake( + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), + CGRectGetMaxY(borderFrame) + ); + caretPoints[1] = CGPointMake( + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)), + CGRectGetMaxY(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + ); + caretPoints[2] = CGPointMake( + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), + CGRectGetMaxY(borderFrame) + ); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y); @@ -261,12 +281,18 @@ - (void)drawRect:(CGRect)rect break; case FBSDKLikeBoxCaretPositionRight: CGContextMoveToPoint(context, bottomRightArc[end].x, bottomRightArc[end].y); - caretPoints[0] = CGPointMake(CGRectGetMaxX(borderFrame), - FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); - caretPoints[1] = CGPointMake(CGRectGetMaxX(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT, - FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame))); - caretPoints[2] = CGPointMake(CGRectGetMaxX(borderFrame), - FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); + caretPoints[0] = CGPointMake( + CGRectGetMaxX(borderFrame), + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)) + ); + caretPoints[1] = CGPointMake( + CGRectGetMaxX(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT, + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame)) + ); + caretPoints[2] = CGPointMake( + CGRectGetMaxX(borderFrame), + FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)) + ); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y); @@ -285,7 +311,7 @@ - (void)drawRect:(CGRect)rect CGContextRestoreGState(context); } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (UIEdgeInsets)_borderInsets { @@ -296,19 +322,19 @@ - (UIEdgeInsets)_borderInsets // adjust the insets for the caret position switch (self.caretPosition) { - case FBSDKLikeBoxCaretPositionTop:{ + case FBSDKLikeBoxCaretPositionTop: { borderInsets.top += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } - case FBSDKLikeBoxCaretPositionLeft:{ + case FBSDKLikeBoxCaretPositionLeft: { borderInsets.left += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } - case FBSDKLikeBoxCaretPositionBottom:{ + case FBSDKLikeBoxCaretPositionBottom: { borderInsets.bottom += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } - case FBSDKLikeBoxCaretPositionRight:{ + case FBSDKLikeBoxCaretPositionRight: { borderInsets.right += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.m index 9610449059..39f7d7f0ce 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.m @@ -20,14 +20,14 @@ #if !TARGET_OS_TV -#import "FBSDKLikeBoxView.h" + #import "FBSDKLikeBoxView.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKLikeBoxBorderView.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKLikeBoxBorderView.h" @implementation FBSDKLikeBoxView { @@ -35,7 +35,7 @@ @implementation FBSDKLikeBoxView UILabel *_likeCountLabel; } -#pragma mark - Object Lifecycle + #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { @@ -53,7 +53,7 @@ - (id)initWithCoder:(NSCoder *)decoder return self; } -#pragma mark - Properties + #pragma mark - Properties - (void)setCaretPosition:(FBSDKLikeBoxCaretPosition)caretPosition { @@ -79,7 +79,7 @@ - (void)setText:(NSString *)text } } -#pragma mark - Layout + #pragma mark - Layout - (CGSize)intrinsicContentSize { @@ -99,7 +99,7 @@ - (CGSize)sizeThatFits:(CGSize)size return [_borderView sizeThatFits:size]; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (void)_initializeContent { diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButton+Internal.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButton+Internal.h index 6646d9277d..472a72b39e 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButton+Internal.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButton+Internal.h @@ -20,12 +20,12 @@ #if !TARGET_OS_TV -#import + #import -#import + #import -#import "FBSDKLikeActionController.h" -#import "FBSDKLikeButton.h" + #import "FBSDKLikeActionController.h" + #import "FBSDKLikeButton.h" @interface FBSDKLikeButton () diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.m index 14ce20f498..7eee7f2b77 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.m @@ -20,24 +20,24 @@ #if !TARGET_OS_TV -#import "FBSDKLikeDialog.h" + #import "FBSDKLikeDialog.h" -#ifdef FBSDKCOCOAPODS -#import -#else -#import "FBSDKCoreKit+Internal.h" -#endif -#import "FBSDKShareConstants.h" -#import "FBSDKShareDefines.h" + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif + #import "FBSDKShareConstants.h" + #import "FBSDKShareDefines.h" @implementation FBSDKLikeDialog -#define FBSDK_LIKE_METHOD_MIN_VERSION @"20140410" -#define FBSDK_LIKE_METHOD_NAME @"like" -#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_LIKE @"like" -#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_UNLIKE @"unlike" + #define FBSDK_LIKE_METHOD_MIN_VERSION @"20140410" + #define FBSDK_LIKE_METHOD_NAME @"like" + #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_LIKE @"like" + #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_UNLIKE @"unlike" -#pragma mark - Class Methods + #pragma mark - Class Methods + (void)initialize { @@ -58,7 +58,7 @@ + (instancetype)likeWithObjectID:(NSString *)objectID return dialog; } -#pragma mark - Public Methods + #pragma mark - Public Methods - (BOOL)canLike { @@ -83,14 +83,14 @@ - (BOOL)like NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:parameters setObject:self.objectID forKey:@"object_id"]; [FBSDKTypeUtility dictionary:parameters - setObject:NSStringFromFBSDKLikeObjectType(self.objectType) - forKey:@"object_type"]; - FBSDKBridgeAPIRequest * webRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb - scheme:FBSDK_SHARE_JS_DIALOG_SCHEME - methodName:FBSDK_LIKE_METHOD_NAME - methodVersion:nil - parameters:parameters - userInfo:nil]; + setObject:NSStringFromFBSDKLikeObjectType(self.objectType) + forKey:@"object_type"]; + FBSDKBridgeAPIRequest *webRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb + scheme:FBSDK_SHARE_JS_DIALOG_SCHEME + methodName:FBSDK_LIKE_METHOD_NAME + methodVersion:nil + parameters:parameters + userInfo:nil]; FBSDKBridgeAPIResponseBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleCompletionWithDialogResults:response.responseParameters error:response.error]; }; @@ -107,22 +107,22 @@ - (BOOL)like void (^networkCompletionBlock)(FBSDKBridgeAPIResponse *) = ^(FBSDKBridgeAPIResponse *response) { if (response.error.code == FBSDKErrorAppVersionUnsupported) { [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:webRequest - useSafariViewController:useSafariViewController - fromViewController:self.fromViewController - completionBlock:completionBlock]; + useSafariViewController:useSafariViewController + fromViewController:self.fromViewController + completionBlock:completionBlock]; } else { completionBlock(response); } }; [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:nativeRequest - useSafariViewController:useSafariViewController - fromViewController:self.fromViewController - completionBlock:networkCompletionBlock]; + useSafariViewController:useSafariViewController + fromViewController:self.fromViewController + completionBlock:networkCompletionBlock]; } else { [[FBSDKBridgeAPI sharedInstance] openBridgeAPIRequest:webRequest - useSafariViewController:useSafariViewController - fromViewController:self.fromViewController - completionBlock:completionBlock]; + useSafariViewController:useSafariViewController + fromViewController:self.fromViewController + completionBlock:completionBlock]; } return YES; @@ -144,7 +144,7 @@ - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef return YES; } -#pragma mark - Helper Methods + #pragma mark - Helper Methods - (BOOL)_canLikeNative { diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.m index 42bb55fddd..a3fc2fb2aa 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKMessengerIcon.h" + #import "FBSDKMessengerIcon.h" @implementation FBSDKMessengerIcon diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.h index 96523d3e4e..05a26a8a84 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.h @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import + #import NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.m index b6403d3959..b2713ebca7 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareExtension.m @@ -20,7 +20,7 @@ #if !TARGET_OS_TV -#import "FBSDKShareExtension.h" + #import "FBSDKShareExtension.h" NSString *const FBSDKShareExtensionParamAppID = @"app_id"; // application identifier string NSString *const FBSDKShareExtensionParamHashtags = @"hashtags"; // array of hashtag strings (max 1) diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h index 31dad70250..54ba0a46fc 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h @@ -18,8 +18,7 @@ #import -#import "FBSDKShareKit.h" - #import "FBSDKShareDefines.h" +#import "FBSDKShareKit.h" #import "FBSDKShareUtility.h" #import "FBSDKVideoUploader.h" diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m index 631fdfbaab..c88d0fdfe6 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m @@ -21,9 +21,9 @@ #import "FBSDKHashtag.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKShareConstants.h" #import "FBSDKShareLinkContent.h" @@ -118,19 +118,19 @@ + (NSString *)buildWebShareTags:(NSArray *)peopleIDs + (void)buildAsyncWebPhotoContent:(FBSDKSharePhotoContent *)content completionHandler:(FBSDKWebPhotoContentBlock)completion { - void(^stageImageCompletion)(NSArray *) = ^(NSArray *stagedURIs) { + void (^stageImageCompletion)(NSArray *) = ^(NSArray *stagedURIs) { NSString *const methodName = @"share"; NSMutableDictionary *const parameters = - [[FBSDKShareUtility parametersForShareContent:content - bridgeOptions:FBSDKShareBridgeOptionsWebHashtag - shouldFailOnDataError:NO] mutableCopy]; + [[FBSDKShareUtility parametersForShareContent:content + bridgeOptions:FBSDKShareBridgeOptionsWebHashtag + shouldFailOnDataError:NO] mutableCopy]; [parameters removeObjectForKey:@"photos"]; NSString *const stagedURIJSONString = [FBSDKBasicUtility JSONStringForObject:stagedURIs error:nil invalidObjectHandler:NULL]; [FBSDKTypeUtility dictionary:parameters - setObject:stagedURIJSONString - forKey:@"media"]; + setObject:stagedURIJSONString + forKey:@"media"]; [FBSDKTypeUtility dictionary:parameters setObject:[FBSDKShareUtility buildWebShareTags:content.peopleIDs] forKey:@"tags"]; if (completion != NULL) { completion(YES, methodName, [parameters copy]); @@ -175,10 +175,12 @@ + (UIImage *)imageWithCircleColor:(UIColor *)color canvasSize:(CGSize)canvasSize circleSize:(CGSize)circleSize { - CGRect circleFrame = CGRectMake((canvasSize.width - circleSize.width) / 2.0, - (canvasSize.height - circleSize.height) / 2.0, - circleSize.width, - circleSize.height); + CGRect circleFrame = CGRectMake( + (canvasSize.width - circleSize.width) / 2.0, + (canvasSize.height - circleSize.height) / 2.0, + circleSize.width, + circleSize.height + ); UIGraphicsBeginImageContextWithOptions(canvasSize, NO, 0); CGContextRef context = UIGraphicsGetCurrentContext(); [color setFill]; @@ -280,8 +282,7 @@ + (BOOL)validateShareContent:(id)shareContent { if (![self validateRequiredValue:shareContent name:@"shareContent" error:errorRef]) { return NO; - } - else if ([shareContent respondsToSelector:@selector(validateWithOptions:error:)]) { + } else if ([shareContent respondsToSelector:@selector(validateWithOptions:error:)]) { return [shareContent validateWithOptions:bridgeOptions error:errorRef]; } else { if (errorRef != NULL) { @@ -332,7 +333,7 @@ + (id)_convertObject:(id)object } + (void)_stageImagesForPhotoContent:(FBSDKSharePhotoContent *)content - withCompletionHandler:(void(^)(NSArray *))completion + withCompletionHandler:(void (^)(NSArray *))completion { __block NSMutableArray *stagedURIs = [NSMutableArray array]; dispatch_group_t group = dispatch_group_create(); @@ -340,8 +341,8 @@ + (void)_stageImagesForPhotoContent:(FBSDKSharePhotoContent *)content if (photo.image != nil) { dispatch_group_enter(group); NSDictionary *stagingParameters = @{ - @"file" : photo.image, - }; + @"file" : photo.image, + }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/staging_resources" parameters:stagingParameters HTTPMethod:@"POST"]; @@ -355,11 +356,12 @@ + (void)_stageImagesForPhotoContent:(FBSDKSharePhotoContent *)content } } - dispatch_group_notify(group, dispatch_get_main_queue(), ^{ - if (completion != NULL) { - completion([stagedURIs copy]); - } - }); + dispatch_group_notify(group, + dispatch_get_main_queue(), ^{ + if (completion != NULL) { + completion([stagedURIs copy]); + } + }); } + (void)_testObject:(id)object containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef containsVideos:(BOOL *)containsVideosRef @@ -483,10 +485,10 @@ + (BOOL)validateNetworkURL:(NSURL *)URL name:(NSString *)name error:(NSError *__ + (BOOL)validateRequiredValue:(id)value name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { - if (!value || - ([value isKindOfClass:[NSString class]] && !((NSString *)value).length) || - ([value isKindOfClass:[NSArray class]] && !((NSArray *)value).count) || - ([value isKindOfClass:[NSDictionary class]] && !((NSDictionary *)value).count)) { + if (!value + || ([value isKindOfClass:[NSString class]] && !((NSString *)value).length) + || ([value isKindOfClass:[NSArray class]] && !((NSArray *)value).count) + || ([value isKindOfClass:[NSDictionary class]] && !((NSDictionary *)value).count)) { if (errorRef != NULL) { *errorRef = [FBSDKError requiredArgumentErrorWithDomain:FBSDKShareErrorDomain name:name diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m index e2dc1abfc2..99564ff9b5 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m @@ -20,14 +20,15 @@ #import -#ifdef FBSDKCOCOAPODS -#import +#import "FBSDKCoreKitInternalImport.h" + +#if defined FBSDK_SWIFT_PACKAGE + #import #else -#import "FBSDKCoreKit+Internal.h" + #import #endif #import "FBSDKShareDefines.h" -#import "FBSDKShareConstants.h" static NSString *const FBSDKVideoUploaderDefaultGraphNode = @"me"; static NSString *const FBSDKVideoUploaderEdge = @"videos"; @@ -58,16 +59,15 @@ - (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)vi - (void)start { - _graphPath = [self _graphPathWithSuffix:FBSDKVideoUploaderEdge, nil]; - [self _postStartRequest]; + _graphPath = [self _graphPathWithSuffix:FBSDKVideoUploaderEdge, nil]; + [self _postStartRequest]; } #pragma Helper Method - (void)_postStartRequest { - FBSDKGraphRequestBlock startRequestCompletionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) - { + FBSDKGraphRequestBlock startRequestCompletionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (error) { [self.delegate videoUploader:self didFailWithError:error]; return; @@ -99,9 +99,9 @@ - (void)_postStartRequest } [[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath parameters:@{ - FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START, - FBSDK_SHARE_VIDEO_SIZE: [NSString stringWithFormat:@"%tu", _videoSize], - } + FBSDK_SHARE_VIDEO_UPLOAD_PHASE : FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START, + FBSDK_SHARE_VIDEO_SIZE : [NSString stringWithFormat:@"%tu", _videoSize], + } HTTPMethod:@"POST"] startWithCompletionHandler:startRequestCompletionHandler]; } @@ -128,9 +128,9 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona [FBSDKError errorWithDomain:FBSDKShareErrorDomain code:FBSDKShareErrorUnknown message:[NSString - stringWithFormat:@"Fail to get video chunk with start offset: %lu, end offset : %lu.", - (unsigned long)startOffset, - (unsigned long)endOffset]]]; + 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(), ^{ @@ -139,11 +139,11 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona contentType:@""]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:self->_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: self->_uploadSessionID, - FBSDK_SHARE_VIDEO_FILE_CHUNK: dataAttachment, - } + 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 : self->_uploadSessionID, + FBSDK_SHARE_VIDEO_FILE_CHUNK : dataAttachment, + } HTTPMethod:@"POST"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *innerError) { if (innerError) { @@ -166,7 +166,7 @@ - (void)_postFinishRequest NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKTypeUtility dictionary:parameters setObject:FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH - forKey: FBSDK_SHARE_VIDEO_UPLOAD_PHASE]; + forKey:FBSDK_SHARE_VIDEO_UPLOAD_PHASE]; [FBSDKTypeUtility dictionary:parameters setObject:_uploadSessionID forKey:FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID]; @@ -174,24 +174,24 @@ - (void)_postFinishRequest [[[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: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown - message:@"Failed to finish uploading."]]; - return; - } - NSMutableDictionary *shareResult = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:shareResult setObject:result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] forKey:FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS]; - [FBSDKTypeUtility dictionary:shareResult setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; - [FBSDKTypeUtility dictionary:shareResult setObject:self->_videoID forKey:FBSDK_SHARE_VIDEO_ID]; - [self.delegate videoUploader:self didCompleteWithResults:shareResult]; - } - }]; + 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: + [FBSDKError errorWithDomain:FBSDKShareErrorDomain + code:FBSDKShareErrorUnknown + message:@"Failed to finish uploading."]]; + return; + } + NSMutableDictionary *shareResult = [[NSMutableDictionary alloc] init]; + [FBSDKTypeUtility dictionary:shareResult setObject:result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] forKey:FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS]; + [FBSDKTypeUtility dictionary:shareResult setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; + [FBSDKTypeUtility dictionary:shareResult setObject:self->_videoID forKey:FBSDK_SHARE_VIDEO_ID]; + [self.delegate videoUploader:self didCompleteWithResults:shareResult]; + } + }]; } - (NSDictionary *)_extractOffsetsFromResultDictionary:(id)result diff --git a/FBSDKShareKit/FBSDKShareKitTests/FBSDKMessageDialogTests.m b/FBSDKShareKit/FBSDKShareKitTests/FBSDKMessageDialogTests.m index 576564bb04..afb150373d 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/FBSDKMessageDialogTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/FBSDKMessageDialogTests.m @@ -16,31 +16,29 @@ // 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 #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif -#import "FBSDKMessageDialog.h" -#import "FakeSharingDelegate.h" - #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKMessageDialog.h" #import "FBSDKShareKitTestUtility.h" #import "FBSDKShareModelTestUtility.h" +#import "FakeSharingDelegate.h" @interface FBSDKMessageDialogTests : XCTestCase @end @implementation FBSDKMessageDialogTests -- (void)_mockApplicationForURL:(NSURL *)URL canOpen:(BOOL)canOpen usingBlock:(void(^)(void))block +- (void)_mockApplicationForURL:(NSURL *)URL canOpen:(BOOL)canOpen usingBlock:(void (^)(void))block { if (block != NULL) { id applicationMock = OCMClassMock(UIApplication.class); @@ -85,31 +83,47 @@ - (void)testValidate FBSDKMessageDialog *dialog = [[FBSDKMessageDialog alloc] init]; NSError *error; dialog.shareContent = [FBSDKShareModelTestUtility linkContent]; - XCTAssertTrue([dialog validateWithError:&error], - @"Known valid content should pass validation without issue if this test fails then the criteria for the fixture may no longer be valid"); - XCTAssertNil(error, - @"A successful validation should not populate the error reference that was passed to it"); + XCTAssertTrue( + [dialog validateWithError:&error], + @"Known valid content should pass validation without issue if this test fails then the criteria for the fixture may no longer be valid" + ); + XCTAssertNil( + error, + @"A successful validation should not populate the error reference that was passed to it" + ); dialog.shareContent = [FBSDKShareModelTestUtility photoContentWithImages]; error = nil; - XCTAssertTrue([dialog validateWithError:&error], - @"Known valid content should pass validation without issue if this test fails then the criteria for the fixture may no longer be valid"); - XCTAssertNil(error, - @"A successful validation should not populate the error reference that was passed to it"); + XCTAssertTrue( + [dialog validateWithError:&error], + @"Known valid content should pass validation without issue if this test fails then the criteria for the fixture may no longer be valid" + ); + XCTAssertNil( + error, + @"A successful validation should not populate the error reference that was passed to it" + ); dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; error = nil; - XCTAssertTrue([dialog validateWithError:&error], - @"Known valid content should pass validation without issue if this test fails then the criteria for the fixture may no longer be valid"); - XCTAssertNil(error, - @"A successful validation should not populate the error reference that was passed to it"); + XCTAssertTrue( + [dialog validateWithError:&error], + @"Known valid content should pass validation without issue if this test fails then the criteria for the fixture may no longer be valid" + ); + XCTAssertNil( + error, + @"A successful validation should not populate the error reference that was passed to it" + ); dialog.shareContent = [FBSDKShareModelTestUtility cameraEffectContent]; error = nil; - XCTAssertFalse([dialog validateWithError:&error], - @"Should not successfully validate share content that is known to be missing content"); - XCTAssertNotNil(error, - @"A failed validation should populate the error reference that was passed to it"); + XCTAssertFalse( + [dialog validateWithError:&error], + @"Should not successfully validate share content that is known to be missing content" + ); + XCTAssertNotNil( + error, + @"A failed validation should populate the error reference that was passed to it" + ); } - (void)testShowInvokesDelegateWhenCannotShow @@ -121,13 +135,21 @@ - (void)testShowInvokesDelegateWhenCannotShow [dialog show]; - XCTAssertEqualObjects(delegate.capturedError.domain, FBSDKShareErrorDomain, - "Failure to show a message dialog should present an error with the expected domain."); - XCTAssertEqual(delegate.capturedError.code, FBSDKShareErrorDialogNotAvailable, - "Failure to show a message dialog should present an error with the expected code."); - XCTAssertEqualObjects(delegate.capturedError.userInfo[FBSDKErrorDeveloperMessageKey], - @"Message dialog is not available.", - "Failure to show a message dialog should present an error with the expected message."); + XCTAssertEqualObjects( + delegate.capturedError.domain, + FBSDKShareErrorDomain, + "Failure to show a message dialog should present an error with the expected domain." + ); + XCTAssertEqual( + delegate.capturedError.code, + FBSDKShareErrorDialogNotAvailable, + "Failure to show a message dialog should present an error with the expected code." + ); + XCTAssertEqualObjects( + delegate.capturedError.userInfo[FBSDKErrorDeveloperMessageKey], + @"Message dialog is not available.", + "Failure to show a message dialog should present an error with the expected message." + ); }]; } @@ -140,13 +162,21 @@ - (void)testShowInvokesDelegateWhenMissingContent [dialog show]; - XCTAssertEqualObjects(delegate.capturedError.domain, FBSDKShareErrorDomain, - "Failure to show a message dialog should present an error with the expected domain."); - XCTAssertEqual(delegate.capturedError.code, FBSDKErrorInvalidArgument, - "Failure to show a message dialog should present an error with the expected code."); - XCTAssertEqualObjects(delegate.capturedError.userInfo[FBSDKErrorDeveloperMessageKey], - @"Value for shareContent is required.", - "Failure to show a message dialog should present an error with the expected message."); + XCTAssertEqualObjects( + delegate.capturedError.domain, + FBSDKShareErrorDomain, + "Failure to show a message dialog should present an error with the expected domain." + ); + XCTAssertEqual( + delegate.capturedError.code, + FBSDKErrorInvalidArgument, + "Failure to show a message dialog should present an error with the expected code." + ); + XCTAssertEqualObjects( + delegate.capturedError.userInfo[FBSDKErrorDeveloperMessageKey], + @"Value for shareContent is required.", + "Failure to show a message dialog should present an error with the expected message." + ); }]; } @@ -161,13 +191,21 @@ - (void)testShowInvokesDelegateWhenCannotValidate [dialog show]; - XCTAssertEqualObjects(delegate.capturedError.domain, FBSDKShareErrorDomain, - "Failure to show a message dialog should present an error with the expected domain."); - XCTAssertEqual(delegate.capturedError.code, FBSDKErrorInvalidArgument, - "Failure to show a message dialog should present an error with the expected code."); - XCTAssertEqualObjects(delegate.capturedError.userInfo[FBSDKErrorDeveloperMessageKey], - @"Message dialog does not support FBSDKShareCameraEffectContent.", - "Failure to show a message dialog should present an error with the expected message."); + XCTAssertEqualObjects( + delegate.capturedError.domain, + FBSDKShareErrorDomain, + "Failure to show a message dialog should present an error with the expected domain." + ); + XCTAssertEqual( + delegate.capturedError.code, + FBSDKErrorInvalidArgument, + "Failure to show a message dialog should present an error with the expected code." + ); + XCTAssertEqualObjects( + delegate.capturedError.userInfo[FBSDKErrorDeveloperMessageKey], + @"Message dialog does not support FBSDKShareCameraEffectContent.", + "Failure to show a message dialog should present an error with the expected message." + ); }]; } diff --git a/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m b/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m index f5079892e3..6871241227 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m @@ -16,23 +16,21 @@ // 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 -#import - #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif -#import "FBSDKHashtag.h" -#import "FBSDKShareDialog.h" - #import "FBSDKCoreKit+Internal.h" +#import "FBSDKHashtag.h" #import "FBSDKShareDefines.h" +#import "FBSDKShareDialog.h" #import "FBSDKShareKitTestUtility.h" #import "FBSDKShareModelTestUtility.h" @@ -41,7 +39,7 @@ @interface FBSDKShareDialogTests : XCTestCase @implementation FBSDKShareDialogTests -- (void)_mockApplicationForURL:(NSURL *)URL canOpen:(BOOL)canOpen usingBlock:(void(^)(void))block +- (void)_mockApplicationForURL:(NSURL *)URL canOpen:(BOOL)canOpen usingBlock:(void (^)(void))block { if (block != NULL) { id applicationMock = [OCMockObject mockForClass:[UIApplication class]]; @@ -56,7 +54,7 @@ - (void)_mockApplicationForURL:(NSURL *)URL canOpen:(BOOL)canOpen usingBlock:(vo } } -- (void)_mockUseNativeDialogUsingBlock:(void(^)(void))block +- (void)_mockUseNativeDialogUsingBlock:(void (^)(void))block { if (block != NULL) { id configurationMock = [OCMockObject mockForClass:[FBSDKServerConfiguration class]]; @@ -77,56 +75,70 @@ - (void)setUp #pragma mark - Native -- (void)testCanShowNativeDialogWithoutShareContent { +- (void)testCanShowNativeDialogWithoutShareContent +{ FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeNative; [self _mockApplicationForURL:OCMOCK_ANY canOpen:YES usingBlock:^{ [self _mockUseNativeDialogUsingBlock:^{ - XCTAssertTrue([dialog canShow], - @"A dialog without share content should be showable on a native dialog"); + XCTAssertTrue( + [dialog canShow], + @"A dialog without share content should be showable on a native dialog" + ); }]; }]; } -- (void)testCanShowNativeLinkContent { +- (void)testCanShowNativeLinkContent +{ FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeNative; [self _mockUseNativeDialogUsingBlock:^{ - dialog.shareContent = [FBSDKShareModelTestUtility linkContent]; - XCTAssertTrue([dialog canShow], - @"A dialog with valid link content should be showable on a native dialog"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with valid link content should be showable on a native dialog" + ); }]; } -- (void)testCanShowNativePhotoContent { +- (void)testCanShowNativePhotoContent +{ FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeNative; [self _mockUseNativeDialogUsingBlock:^{ dialog.shareContent = [FBSDKShareModelTestUtility photoContent]; - XCTAssertFalse([dialog canShow], - @"Photo content with photos that have web urls should not be showable on a native dialog"); + XCTAssertFalse( + [dialog canShow], + @"Photo content with photos that have web urls should not be showable on a native dialog" + ); }]; } -- (void)testCanShowNativePhotoContentWithFileURL { +- (void)testCanShowNativePhotoContentWithFileURL +{ FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeNative; [self _mockUseNativeDialogUsingBlock:^{ dialog.shareContent = [FBSDKShareModelTestUtility photoContentWithFileURLs]; - XCTAssertTrue([dialog canShow], - @"Photo content with photos that have file urls should be showable on a native dialog"); + XCTAssertTrue( + [dialog canShow], + @"Photo content with photos that have file urls should be showable on a native dialog" + ); }]; } -- (void)testCanShowNativeVideoContentWithoutPreviewPhoto { +- (void)testCanShowNativeVideoContentWithoutPreviewPhoto +{ FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeNative; [self _mockApplicationForURL:OCMOCK_ANY canOpen:YES usingBlock:^{ [self _mockUseNativeDialogUsingBlock:^{ dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; - XCTAssertTrue([dialog canShow], - @"Video content without a preview photo should be showable on a native dialog"); + XCTAssertTrue( + [dialog canShow], + @"Video content without a preview photo should be showable on a native dialog" + ); }]; }]; } @@ -137,8 +149,10 @@ - (void)testCanShowNative dialog.mode = FBSDKShareDialogModeNative; [self _mockApplicationForURL:OCMOCK_ANY canOpen:NO usingBlock:^{ [self _mockUseNativeDialogUsingBlock:^{ - XCTAssertFalse([dialog canShow], - @"A native dialog should not be showable if the application is unable to open a url, this can also occur if the api scheme is not whitelisted in the third party app or if the application cannot handle the share API scheme"); + XCTAssertFalse( + [dialog canShow], + @"A native dialog should not be showable if the application is unable to open a url, this can also occur if the api scheme is not whitelisted in the third party app or if the application cannot handle the share API scheme" + ); }]; }]; } @@ -180,19 +194,27 @@ - (void)testCanShowBrowser { FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeBrowser; - XCTAssertTrue([dialog canShow], - @"A dialog without share content should be showable in a browser"); + XCTAssertTrue( + [dialog canShow], + @"A dialog without share content should be showable in a browser" + ); dialog.shareContent = [FBSDKShareModelTestUtility linkContent]; - XCTAssertTrue([dialog canShow], - @"A dialog with link content should be showable in a browser"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with link content should be showable in a browser" + ); [self _performBlockWithAccessToken:^{ dialog.shareContent = [FBSDKShareModelTestUtility photoContentWithFileURLs]; - XCTAssertTrue([dialog canShow], - @"A dialog with photo content with file urls should be showable in a browser when there is a current access token"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with photo content with file urls should be showable in a browser when there is a current access token" + ); dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; - XCTAssertTrue([dialog canShow], - @"A dialog with video content without a preview photo should be showable in a browser when there is a current access token"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with video content without a preview photo should be showable in a browser when there is a current access token" + ); }]; } @@ -224,18 +246,26 @@ - (void)testCanShowWeb { FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeWeb; - XCTAssertTrue([dialog canShow], - @"A dialog without share content should be showable on web"); + XCTAssertTrue( + [dialog canShow], + @"A dialog without share content should be showable on web" + ); dialog.shareContent = [FBSDKShareModelTestUtility linkContent]; - XCTAssertTrue([dialog canShow], - @"A dialog with link content should be showable on web"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with link content should be showable on web" + ); [self _performBlockWithAccessToken:^{ dialog.shareContent = [FBSDKShareModelTestUtility photoContent]; - XCTAssertFalse([dialog canShow], - @"A dialog with photos should not be showable on web"); + XCTAssertFalse( + [dialog canShow], + @"A dialog with photos should not be showable on web" + ); dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; - XCTAssertFalse([dialog canShow], - @"A dialog with content that contains local media should not be showable on web"); + XCTAssertFalse( + [dialog canShow], + @"A dialog with content that contains local media should not be showable on web" + ); }]; } @@ -250,34 +280,54 @@ - (void)testValidateWeb [self _performBlockWithAccessToken:^{ dialog.shareContent = [FBSDKShareModelTestUtility photoContent]; - XCTAssertFalse([dialog validateWithError:&error], - @"A dialog with photo content that points to remote urls should not be considered valid on web"); - XCTAssertNotNil(error, - @"Validating a dialog with photo content on web should provide a meaningful error"); + XCTAssertFalse( + [dialog validateWithError:&error], + @"A dialog with photo content that points to remote urls should not be considered valid on web" + ); + XCTAssertNotNil( + error, + @"Validating a dialog with photo content on web should provide a meaningful error" + ); dialog.shareContent = [FBSDKShareModelTestUtility photoContentWithImages]; - XCTAssertFalse([dialog validateWithError:&error], - @"A dialog with photo content that is already loaded should not be considered valid on web"); - XCTAssertNotNil(error, - @"Validating a dialog with photo content that is already loaded on web should provide a meaningful error"); + XCTAssertFalse( + [dialog validateWithError:&error], + @"A dialog with photo content that is already loaded should not be considered valid on web" + ); + XCTAssertNotNil( + error, + @"Validating a dialog with photo content that is already loaded on web should provide a meaningful error" + ); dialog.shareContent = [FBSDKShareModelTestUtility photoContentWithFileURLs]; - XCTAssertFalse([dialog validateWithError:&error], - @"A dialog with photo content that points to file urls should not be considered valid on web"); - XCTAssertNotNil(error, - @"Validating a dialog with photo content that points to file urls on web should provide a meaningful error"); + XCTAssertFalse( + [dialog validateWithError:&error], + @"A dialog with photo content that points to file urls should not be considered valid on web" + ); + XCTAssertNotNil( + error, + @"Validating a dialog with photo content that points to file urls on web should provide a meaningful error" + ); dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; - XCTAssertFalse([dialog validateWithError:&error], - @"A dialog that includes local media should not be considered valid on web"); - XCTAssertNotNil(error, - @"Validating a dialog that includes local media should provide a meaningful error"); + XCTAssertFalse( + [dialog validateWithError:&error], + @"A dialog that includes local media should not be considered valid on web" + ); + XCTAssertNotNil( + error, + @"Validating a dialog that includes local media should provide a meaningful error" + ); }]; [self _performBlockWithNilAccessToken:^{ - XCTAssertFalse([dialog validateWithError:&error], - @"A dialog with content but no access token should not be considered valid on web"); - XCTAssertNotNil(error, - @"Validating a dialog with content but no access token should provide a meaningful error"); + XCTAssertFalse( + [dialog validateWithError:&error], + @"A dialog with content but no access token should not be considered valid on web" + ); + XCTAssertNotNil( + error, + @"Validating a dialog with content but no access token should provide a meaningful error" + ); }]; } @@ -287,17 +337,25 @@ - (void)testCanShowFeedBrowser { FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeFeedBrowser; - XCTAssertTrue([dialog canShow], - @"A dialog without content should be showable in a browser feed"); + XCTAssertTrue( + [dialog canShow], + @"A dialog without content should be showable in a browser feed" + ); dialog.shareContent = [FBSDKShareModelTestUtility linkContent]; - XCTAssertTrue([dialog canShow], - @"A dialog with link content should be showable in a browser feed"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with link content should be showable in a browser feed" + ); dialog.shareContent = [FBSDKShareModelTestUtility photoContent]; - XCTAssertFalse([dialog canShow], - @"A dialog with photo content should not be showable in a browser feed"); + XCTAssertFalse( + [dialog canShow], + @"A dialog with photo content should not be showable in a browser feed" + ); dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; - XCTAssertFalse([dialog canShow], - @"A dialog with video content that has no preview photo should not be showable in a browser feed"); + XCTAssertFalse( + [dialog canShow], + @"A dialog with video content that has no preview photo should not be showable in a browser feed" + ); } - (void)testValidateFeedBrowser @@ -322,17 +380,25 @@ - (void)testCanShowFeedWeb { FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; dialog.mode = FBSDKShareDialogModeFeedWeb; - XCTAssertTrue([dialog canShow], - @"A dialog without content should be showable in a web feed"); + XCTAssertTrue( + [dialog canShow], + @"A dialog without content should be showable in a web feed" + ); dialog.shareContent = [FBSDKShareModelTestUtility linkContent]; - XCTAssertTrue([dialog canShow], - @"A dialog with link content should be showable in a web feed"); + XCTAssertTrue( + [dialog canShow], + @"A dialog with link content should be showable in a web feed" + ); dialog.shareContent = [FBSDKShareModelTestUtility photoContent]; - XCTAssertFalse([dialog canShow], - @"A dialog with photo content should not be showable in a web feed"); + XCTAssertFalse( + [dialog canShow], + @"A dialog with photo content should not be showable in a web feed" + ); dialog.shareContent = [FBSDKShareModelTestUtility videoContentWithoutPreviewPhoto]; - XCTAssertFalse([dialog canShow], - @"A dialog with video content and no preview photo should not be showable in a web feed"); + XCTAssertFalse( + [dialog canShow], + @"A dialog with video content and no preview photo should not be showable in a web feed" + ); } - (void)testValidateFeedWeb @@ -359,12 +425,12 @@ - (void)testThatInitialTextIsSetCorrectlyWhenShareExtensionIsAvailable content.quote = @"a quote"; dialog.shareContent = content; - NSDictionary *expectedJSON = @{@"app_id":@"appID", @"hashtags":@[@"#hashtag"], @"quotes":@[@"a quote"]}; + NSDictionary *expectedJSON = @{@"app_id" : @"appID", @"hashtags" : @[@"#hashtag"], @"quotes" : @[@"a quote"]}; [self _showDialog:dialog - appID:@"appID" -shareSheetAvailable:YES -expectedPreJSONtext:@"fb-app-id:appID #hashtag" - expectedJSON:expectedJSON]; + appID:@"appID" + shareSheetAvailable:YES + expectedPreJSONtext:@"fb-app-id:appID #hashtag" + expectedJSON:expectedJSON]; } #pragma mark - Camera Share @@ -451,9 +517,9 @@ - (void)testThatInitialTextIsSetCorrectlyWhenShareExtensionIsNOTAvailable content.hashtag = [FBSDKHashtag hashtagWithString:@"#hashtag"]; dialog.shareContent = content; [self _showDialog:dialog - appID:@"appID" -shareSheetAvailable:NO -expectedPreJSONtext:@"#hashtag" expectedJSON:nil]; + appID:@"appID" + shareSheetAvailable:NO + expectedPreJSONtext:@"#hashtag" expectedJSON:nil]; } - (void)testThatValidateWithErrorReturnsNOForLinkQuoteIfAValidShareExtensionVersionIsNotAvailable @@ -472,7 +538,6 @@ - (void)testThatValidateWithErrorReturnsYESForLinkQuoteIfAValidShareExtensionVer expectShow:YES mode:FBSDKShareDialogModeShareSheet nonSupportedScheme:nil]; - } - (void)testThatValidateWithErrorReturnsNOForMMPIfAValidShareExtensionVersionIsNotAvailable @@ -512,7 +577,7 @@ - (void)_testValidateShareContent:(id)shareContent { id mockApplication = [OCMockObject niceMockForClass:[UIApplication class]]; [[[mockApplication stub] andReturn:mockApplication] sharedApplication]; - [[[mockApplication stub] andReturnValue:@YES] canOpenURL:[OCMArg checkWithBlock:^BOOL(NSURL *url) { + [[[mockApplication stub] andReturnValue:@YES] canOpenURL:[OCMArg checkWithBlock:^BOOL (NSURL *url) { return ![url.absoluteString isEqualToString:nonSupportedScheme]; }]]; NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; @@ -542,11 +607,11 @@ - (void)_testValidateShareContent:(id)shareContent [mockSLController stopMocking]; } -- (void)_showDialog:(FBSDKShareDialog *)dialog - appID:(NSString *)appID -shareSheetAvailable:(BOOL)shareSheetAvailable -expectedPreJSONtext:(NSString *)expectedPreJSONText - expectedJSON:(NSDictionary *)expectedJSON +- (void) _showDialog:(FBSDKShareDialog *)dialog + appID:(NSString *)appID + shareSheetAvailable:(BOOL)shareSheetAvailable + expectedPreJSONtext:(NSString *)expectedPreJSONText + expectedJSON:(NSDictionary *)expectedJSON { id mockApplication = [OCMockObject niceMockForClass:[UIApplication class]]; [[[mockApplication stub] andReturn:mockApplication] sharedApplication]; @@ -559,7 +624,7 @@ - (void)_showDialog:(FBSDKShareDialog *)dialog id mockSLController = [OCMockObject niceMockForClass:[fbsdkdfl_SLComposeViewControllerClass() class]]; [[[mockSLController stub] andReturn:mockSLController] composeViewControllerForServiceType:OCMOCK_ANY]; [[[mockSLController stub] andReturnValue:@YES] isAvailableForServiceType:OCMOCK_ANY]; - [[mockSLController expect] setInitialText:[OCMArg checkWithBlock:^BOOL(NSString *text) { + [[mockSLController expect] setInitialText:[OCMArg checkWithBlock:^BOOL (NSString *text) { NSRange JSONDelimiterRange = [text rangeOfString:@"|"]; NSString *preJSONText; NSDictionary *json; @@ -567,11 +632,11 @@ - (void)_showDialog:(FBSDKShareDialog *)dialog preJSONText = text; } else { preJSONText = [text substringToIndex:JSONDelimiterRange.location]; - NSString *jsonText = [text substringFromIndex:JSONDelimiterRange.location+1]; + NSString *jsonText = [text substringFromIndex:JSONDelimiterRange.location + 1]; json = [FBSDKTypeUtility JSONObjectWithData:[jsonText dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; } - return ((expectedPreJSONText == nil && preJSONText == nil) || [expectedPreJSONText isEqualToString:preJSONText]) && - ((expectedJSON == nil && json == nil) || [expectedJSON isEqual:json]); + return ((expectedPreJSONText == nil && preJSONText == nil) || [expectedPreJSONText isEqualToString:preJSONText]) + && ((expectedJSON == nil && json == nil) || [expectedJSON isEqual:json]); }]]; UIViewController *vc = [UIViewController new]; @@ -593,7 +658,7 @@ - (void)_showNativeDialog:(FBSDKShareDialog *)dialog { id mockApplication = [OCMockObject niceMockForClass:[UIApplication class]]; [[[mockApplication stub] andReturn:mockApplication] sharedApplication]; - [[[mockApplication stub] andReturnValue:@YES] canOpenURL:[OCMArg checkWithBlock:^BOOL(NSURL *url) { + [[[mockApplication stub] andReturnValue:@YES] canOpenURL:[OCMArg checkWithBlock:^BOOL (NSURL *url) { return ![url.absoluteString isEqualToString:nonSupportedScheme]; }]]; id settingsClassMock = [OCMockObject niceMockForClass:[FBSDKSettings class]]; @@ -604,14 +669,14 @@ - (void)_showNativeDialog:(FBSDKShareDialog *)dialog id mockSDKBridgeAPI = [OCMockObject niceMockForClass:[FBSDKBridgeAPI class]]; [[[mockSDKBridgeAPI stub] andReturn:mockSDKBridgeAPI] sharedInstance]; // Check API bridge request - [[mockSDKBridgeAPI expect] openBridgeAPIRequest:[OCMArg checkWithBlock:^BOOL(FBSDKBridgeAPIRequest *request) { + [[mockSDKBridgeAPI expect] openBridgeAPIRequest:[OCMArg checkWithBlock:^BOOL (FBSDKBridgeAPIRequest *request) { XCTAssertEqualObjects(request.scheme, scheme); XCTAssertEqualObjects(request.methodName, methodName); return YES; }] - useSafariViewController:(BOOL)OCMOCK_ANY - fromViewController:OCMOCK_ANY - completionBlock:OCMOCK_ANY]; + useSafariViewController:(BOOL)OCMOCK_ANY + fromViewController:OCMOCK_ANY + completionBlock:OCMOCK_ANY]; UIViewController *vc = [UIViewController new]; dialog.fromViewController = vc; @@ -622,6 +687,7 @@ - (void)_showNativeDialog:(FBSDKShareDialog *)dialog [settingsClassMock stopMocking]; [mockApplication stopMocking]; } + - (void)_performBlockWithAccessToken:(dispatch_block_t)block { FBSDKAccessToken *accessToken = [[FBSDKAccessToken alloc] initWithTokenString:@"FBSDKShareDialogTests" diff --git a/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareKitTestUtility.m b/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareKitTestUtility.m index 02663359e7..b00dce863e 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareKitTestUtility.m +++ b/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareKitTestUtility.m @@ -18,12 +18,11 @@ #import "FBSDKShareKitTestUtility.h" -#import - #import +#import #import -#import +#import #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareDialog.h" diff --git a/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.h b/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.h index 040d51fee1..ba3c50d5ed 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.h +++ b/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface FakeSharingDelegate : NSObject +@interface FakeSharingDelegate : NSObject @property (nonatomic) NSDictionary *capturedResults; @property (nonatomic) NSError *capturedError; diff --git a/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.m b/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.m index 6cc669fdde..cf8ae8ada1 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.m +++ b/FBSDKShareKit/FBSDKShareKitTests/FakeSharingDelegate.m @@ -20,15 +20,18 @@ @implementation FakeSharingDelegate -- (void)sharer:(nonnull id)sharer didCompleteWithResults:(nonnull NSDictionary *)results { +- (void)sharer:(nonnull id)sharer didCompleteWithResults:(nonnull NSDictionary *)results +{ self.capturedResults = results; } -- (void)sharer:(nonnull id)sharer didFailWithError:(nonnull NSError *)error { +- (void)sharer:(nonnull id)sharer didFailWithError:(nonnull NSError *)error +{ self.capturedError = error; } -- (void)sharerDidCancel:(nonnull id)sharer { +- (void)sharerDidCancel:(nonnull id)sharer +{ self.didCancel = true; } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Internal/FBSDKShareUtilityTests.m b/FBSDKShareKit/FBSDKShareKitTests/Internal/FBSDKShareUtilityTests.m index d580793cd6..2c69401cc2 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Internal/FBSDKShareUtilityTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Internal/FBSDKShareUtilityTests.m @@ -20,7 +20,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKAppInviteContentTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKAppInviteContentTests.m index e5140586c2..48067c8925 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKAppInviteContentTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKAppInviteContentTests.m @@ -19,7 +19,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKCameraEffectArgumentsTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKCameraEffectArgumentsTests.m index 1f8df9abb4..d1a58f09ac 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKCameraEffectArgumentsTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKCameraEffectArgumentsTests.m @@ -20,7 +20,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif @@ -45,9 +45,9 @@ - (void)testCoding FBSDKCameraEffectArguments *arguments = [FBSDKShareModelTestUtility cameraEffectArguments]; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arguments]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_11_0 - FBSDKCameraEffectArguments *unarchivedArguments = [NSKeyedUnarchiver unarchivedObjectOfClass:[FBSDKCameraEffectArguments class] fromData:data error:nil]; + FBSDKCameraEffectArguments *unarchivedArguments = [NSKeyedUnarchiver unarchivedObjectOfClass:[FBSDKCameraEffectArguments class] fromData:data error:nil]; #else - FBSDKCameraEffectArguments *unarchivedArguments = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + FBSDKCameraEffectArguments *unarchivedArguments = [NSKeyedUnarchiver unarchiveObjectWithData:data]; #endif XCTAssertEqualObjects(unarchivedArguments, arguments); } @@ -59,8 +59,8 @@ - (void)testTypes // Supported types [arguments setString:@"1234" forKey:@"string"]; XCTAssertEqualObjects([arguments stringForKey:@"string"], @"1234"); - [arguments setArray:@[@"a",@"b",@"c"] forKey:@"string_array"]; - XCTAssertEqualObjects([arguments arrayForKey:@"string_array"], (@[@"a",@"b",@"c"])); + [arguments setArray:@[@"a", @"b", @"c"] forKey:@"string_array"]; + XCTAssertEqualObjects([arguments arrayForKey:@"string_array"], (@[@"a", @"b", @"c"])); [arguments setArray:@[] forKey:@"empty_array"]; XCTAssertEqualObjects([arguments arrayForKey:@"empty_array"], @[]); [arguments setString:nil forKey:@"nil_string"]; diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKGameRequestContentTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKGameRequestContentTests.m index 49e70311d2..48852e7049 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKGameRequestContentTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKGameRequestContentTests.m @@ -19,7 +19,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif @@ -58,7 +58,7 @@ - (void)testCoding NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [unarchiver setRequiresSecureCoding:YES]; FBSDKGameRequestContent *unarchivedObject = [unarchiver decodeObjectOfClass:[FBSDKGameRequestContent class] - forKey:NSKeyedArchiveRootObjectKey]; + forKey:NSKeyedArchiveRootObjectKey]; XCTAssertEqualObjects(unarchivedObject, content); } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareLinkContentTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareLinkContentTests.m index 660b38f815..e8821731ad 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareLinkContentTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareLinkContentTests.m @@ -19,15 +19,14 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif -#import "FBSDKShareLinkContent.h" - #import +#import "FBSDKShareLinkContent.h" #import "FBSDKShareModelTestUtility.h" #import "FBSDKShareUtility.h" @@ -68,19 +67,21 @@ - (void)testWithInvalidPeopleIDs { FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init]; NSArray *array = @[ - @"one", - @2, - @"three", - ]; + @"one", + @2, + @"three", + ]; XCTAssertThrowsSpecificNamed([content setPeopleIDs:array], NSException, NSInvalidArgumentException); } - (void)testValidationWithValidContent { NSError *error; - XCTAssertTrue([FBSDKShareUtility validateShareContent:[FBSDKShareModelTestUtility linkContent] - bridgeOptions:FBSDKShareBridgeOptionsDefault - error:&error]); + XCTAssertTrue( + [FBSDKShareUtility validateShareContent:[FBSDKShareModelTestUtility linkContent] + bridgeOptions:FBSDKShareBridgeOptionsDefault + error:&error] + ); XCTAssertNil(error); } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareModelTestUtility.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareModelTestUtility.m index ea11ed3875..02c0bf5fe1 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareModelTestUtility.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareModelTestUtility.m @@ -150,33 +150,33 @@ + (FBSDKSharePhoto *)photoWithImageURL + (NSArray *)photos { return @[ - [FBSDKSharePhoto photoWithImageURL:[NSURL URLWithString:@"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yC/r/YRwxe7CPWSs.png"] - userGenerated:NO], - [FBSDKSharePhoto photoWithImageURL:[NSURL URLWithString:@"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yS/r/9f82O0jy9RH.png"] - userGenerated:NO], - [FBSDKSharePhoto photoWithImageURL:[NSURL URLWithString:@"https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xaf1/t39.2178-6/10173500_1398474223767412_616498772_n.png"] - userGenerated:YES], - ]; + [FBSDKSharePhoto photoWithImageURL:[NSURL URLWithString:@"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yC/r/YRwxe7CPWSs.png"] + userGenerated:NO], + [FBSDKSharePhoto photoWithImageURL:[NSURL URLWithString:@"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yS/r/9f82O0jy9RH.png"] + userGenerated:NO], + [FBSDKSharePhoto photoWithImageURL:[NSURL URLWithString:@"https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xaf1/t39.2178-6/10173500_1398474223767412_616498772_n.png"] + userGenerated:YES], + ]; } + (NSArray *)photosWithFileUrls { return @[ - [FBSDKShareModelTestUtility photoWithFileURL], - ]; + [FBSDKShareModelTestUtility photoWithFileURL], + ]; } + (NSArray *)photosWithImages { - // equality checks are pointer equality for UIImage, so just return the same instance each time + // equality checks are pointer equality for UIImage, so just return the same instance each time static NSArray *_photos = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _photos = @[ - [FBSDKSharePhoto photoWithImage:[self _generateImage] userGenerated:YES], - [FBSDKSharePhoto photoWithImage:[self _generateImage] userGenerated:YES], - [FBSDKSharePhoto photoWithImage:[self _generateImage] userGenerated:YES], - ]; + [FBSDKSharePhoto photoWithImage:[self _generateImage] userGenerated:YES], + [FBSDKSharePhoto photoWithImage:[self _generateImage] userGenerated:YES], + [FBSDKSharePhoto photoWithImage:[self _generateImage] userGenerated:YES], + ]; }); return _photos; } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoContentTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoContentTests.m index ea0d461d0f..6298962579 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoContentTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoContentTests.m @@ -20,7 +20,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif @@ -65,9 +65,9 @@ - (void)testWithInvalidPhotos { FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init]; NSArray *photos = @[ - [FBSDKShareModelTestUtility photoWithImageURL], - [FBSDKShareModelTestUtility photoImageURL], - ]; + [FBSDKShareModelTestUtility photoWithImageURL], + [FBSDKShareModelTestUtility photoImageURL], + ]; XCTAssertThrowsSpecificNamed([content setPhotos:photos], NSException, NSInvalidArgumentException); } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoTests.m index 17c29d0694..b8f8ddc2bd 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKSharePhotoTests.m @@ -20,7 +20,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif @@ -92,10 +92,10 @@ - (void)testWithInvalidPhotos { FBSDKSharePhotoContent *content = [[FBSDKSharePhotoContent alloc] init]; NSArray *photos = @[ - [FBSDKShareModelTestUtility photoWithImageURL], - [FBSDKShareModelTestUtility photoWithImage], - @"my photo", - ]; + [FBSDKShareModelTestUtility photoWithImageURL], + [FBSDKShareModelTestUtility photoWithImage], + @"my photo", + ]; XCTAssertThrowsSpecificNamed([content setPhotos:photos], NSException, NSInvalidArgumentException); } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m index b99065a568..108699a1cb 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoContentTests.m @@ -20,7 +20,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif @@ -96,8 +96,11 @@ - (void)testValidationWithNilVideoURL XCTAssertFalse([FBSDKShareUtility validateShareContent:content bridgeOptions:FBSDKShareBridgeOptionsDefault error:&error]); XCTAssertNotNil(error); XCTAssertEqual(error.code, FBSDKErrorInvalidArgument); - XCTAssertEqualObjects(error.userInfo[FBSDKErrorArgumentNameKey], @"video", - @"Attempting to validate video share content with a missing url should return a general video error"); + XCTAssertEqualObjects( + error.userInfo[FBSDKErrorArgumentNameKey], + @"video", + @"Attempting to validate video share content with a missing url should return a general video error" + ); } - (void)testValidationWithInvalidVideoURL @@ -110,8 +113,11 @@ - (void)testValidationWithInvalidVideoURL XCTAssertFalse([FBSDKShareUtility validateShareContent:content bridgeOptions:FBSDKShareBridgeOptionsDefault error:&error]); XCTAssertNotNil(error); XCTAssertEqual(error.code, FBSDKErrorInvalidArgument); - XCTAssertEqualObjects(error.userInfo[FBSDKErrorArgumentNameKey], @"videoURL", - @"Attempting to validate video share content with an empty url should return a video url specific error"); + XCTAssertEqualObjects( + error.userInfo[FBSDKErrorArgumentNameKey], + @"videoURL", + @"Attempting to validate video share content with an empty url should return a video url specific error" + ); } - (void)testValidationWithNonVideoURL @@ -124,8 +130,11 @@ - (void)testValidationWithNonVideoURL XCTAssertFalse([FBSDKShareUtility validateShareContent:content bridgeOptions:FBSDKShareBridgeOptionsDefault error:&error]); XCTAssertNotNil(error); XCTAssertEqual(error.code, FBSDKErrorInvalidArgument); - XCTAssertEqualObjects(error.userInfo[FBSDKErrorArgumentNameKey], @"videoURL", - @"Attempting to validate video share content with a non-video url should return a video url specific error"); + XCTAssertEqualObjects( + error.userInfo[FBSDKErrorArgumentNameKey], + @"videoURL", + @"Attempting to validate video share content with a non-video url should return a video url specific error" + ); } - (void)testValidationWithNetworkVideoURL @@ -149,10 +158,13 @@ - (void)testValidationWithValidFileVideoURLWhenBridgeOptionIsDefault content.video = video; XCTAssertNotNil(content); NSError *error; - XCTAssertFalse([FBSDKShareUtility validateShareContent:content bridgeOptions: FBSDKShareBridgeOptionsDefault error:&error]); + XCTAssertFalse([FBSDKShareUtility validateShareContent:content bridgeOptions:FBSDKShareBridgeOptionsDefault error:&error]); XCTAssertEqual(error.code, FBSDKErrorInvalidArgument); - XCTAssertEqualObjects(error.userInfo[FBSDKErrorArgumentNameKey], @"videoURL", - @"Attempting to validate video share content with a valid file url should return a video url specific error when there is no specified bridge option to handle video data"); + XCTAssertEqualObjects( + error.userInfo[FBSDKErrorArgumentNameKey], + @"videoURL", + @"Attempting to validate video share content with a valid file url should return a video url specific error when there is no specified bridge option to handle video data" + ); } - (void)testValidationWithValidFileVideoURLWhenBridgeOptionIsVideoData @@ -164,7 +176,7 @@ - (void)testValidationWithValidFileVideoURLWhenBridgeOptionIsVideoData content.video = video; XCTAssertNotNil(content); NSError *error; - XCTAssertTrue([FBSDKShareUtility validateShareContent:content bridgeOptions: FBSDKShareBridgeOptionsVideoData error:&error]); + XCTAssertTrue([FBSDKShareUtility validateShareContent:content bridgeOptions:FBSDKShareBridgeOptionsVideoData error:&error]); XCTAssertNil(error); } diff --git a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoTests.m b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoTests.m index 1a693b88f6..8d862f874a 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/Models/FBSDKShareVideoTests.m @@ -20,7 +20,7 @@ #import #ifdef BUCK -#import + #import #else @import FBSDKCoreKit; #endif diff --git a/FBSDKTVOSKit/Configurations/FBSDKTVOSKitTests.xcconfig b/FBSDKTVOSKit/Configurations/FBSDKTVOSKitTests.xcconfig index c91be838eb..a937279c08 100644 --- a/FBSDKTVOSKit/Configurations/FBSDKTVOSKitTests.xcconfig +++ b/FBSDKTVOSKit/Configurations/FBSDKTVOSKitTests.xcconfig @@ -24,7 +24,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKTVOSKitTests INFOPLIST_FILE = $(SRCROOT)/FBSDKTVOSKitTests/Info.plist -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 HEADER_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) LIBRARY_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginButton.m b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginButton.m index 31ea758ad4..8bbc618640 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginButton.m +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginButton.m @@ -19,13 +19,13 @@ #import "FBSDKDeviceLoginButton.h" #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKDeviceLoginViewController.h" -@interface FBSDKDeviceLoginButton() +@interface FBSDKDeviceLoginButton () @end @@ -60,10 +60,13 @@ - (CGSize)sizeThatFits:(CGSize)size CGSize selectedSize = [self sizeThatFits:size attributedTitle:[self _logOutTitle]]; CGSize normalSize = [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, size.height) attributedTitle:[self _longLogInTitle]]; if (normalSize.width > size.width) { - return normalSize = [self sizeThatFits:size attributedTitle:[self _shortLogInTitle]]; + normalSize = [self sizeThatFits:size attributedTitle:[self _shortLogInTitle]]; + return normalSize; } - CGSize maxSize = CGSizeMake(MAX(normalSize.width, selectedSize.width), - MAX(normalSize.height, selectedSize.height)); + CGSize maxSize = CGSizeMake( + MAX(normalSize.width, selectedSize.width), + MAX(normalSize.height, selectedSize.height) + ); return CGSizeMake(maxSize.width, maxSize.height); } @@ -84,13 +87,13 @@ - (void)configureButton NSAttributedString *logOutTitle = [self _logOutTitle]; [self configureWithIcon:nil - title:nil - backgroundColor:[super defaultBackgroundColor] - highlightedColor:nil - selectedTitle:nil - selectedIcon:nil - selectedColor:[super defaultBackgroundColor] - selectedHighlightedColor:nil]; + title:nil + backgroundColor:[super defaultBackgroundColor] + highlightedColor:nil + selectedTitle:nil + selectedIcon:nil + selectedColor:[super defaultBackgroundColor] + selectedHighlightedColor:nil]; [self setAttributedTitle:logInTitle forState:UIControlStateNormal]; [self setAttributedTitle:logInTitle forState:UIControlStateFocused]; [self setAttributedTitle:logOutTitle forState:UIControlStateSelected]; @@ -123,33 +126,49 @@ - (void)_buttonPressed:(id)sender if (_userName) { NSString *localizedFormatString = - NSLocalizedStringWithDefaultValue(@"LoginButton.LoggedInAs", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Logged in as %@", - @"The format string for the FBSDKLoginButton label when the user is logged in"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.LoggedInAs", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Logged in as %@", + @"The format string for the FBSDKLoginButton label when the user is logged in" + ); title = [NSString localizedStringWithFormat:localizedFormatString, _userName]; } else { NSString *localizedLoggedIn = - NSLocalizedStringWithDefaultValue(@"LoginButton.LoggedIn", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Logged in using Facebook", - @"The fallback string for the FBSDKLoginButton label when the user name is not available yet"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.LoggedIn", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Logged in using Facebook", + @"The fallback string for the FBSDKLoginButton label when the user name is not available yet" + ); title = localizedLoggedIn; } NSString *cancelTitle = - NSLocalizedStringWithDefaultValue(@"LoginButton.CancelLogout", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Cancel", - @"The label for the FBSDKLoginButton action sheet to cancel logging out"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.CancelLogout", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Cancel", + @"The label for the FBSDKLoginButton action sheet to cancel logging out" + ); NSString *logOutTitle = - NSLocalizedStringWithDefaultValue(@"LoginButton.ConfirmLogOut", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log Out", - @"The label for the FBSDKLoginButton action sheet to confirm logging out"); + NSLocalizedStringWithDefaultValue( + @"LoginButton.ConfirmLogOut", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log Out", + @"The label for the FBSDKLoginButton action sheet to confirm logging out" + ); UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:title preferredStyle:UIAlertControllerStyleActionSheet]; [alertController addAction:[UIAlertAction actionWithTitle:logOutTitle - style:UIAlertActionStyleDestructive - handler:^(UIAlertAction * _Nonnull action) { - [FBSDKAccessToken setCurrentAccessToken:nil]; - [self.delegate deviceLoginButtonDidLogOut:self]; - }]]; + style:UIAlertActionStyleDestructive + handler:^(UIAlertAction *_Nonnull action) { + [FBSDKAccessToken setCurrentAccessToken:nil]; + [self.delegate deviceLoginButtonDidLogOut:self]; + }]]; [alertController addAction:[UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:NULL]]; [parentViewController presentViewController:alertController animated:YES completion:NULL]; } else { @@ -165,33 +184,45 @@ - (NSAttributedString *)_loginTitle { CGSize size = self.bounds.size; CGSize longTitleSize = [super sizeThatFits:size attributedTitle:[self _longLogInTitle]]; - NSAttributedString *title = (longTitleSize.width <= size.width ? - [self _longLogInTitle] : - [self _shortLogInTitle]); + NSAttributedString *title = (longTitleSize.width <= size.width + ? [self _longLogInTitle] + : [self _shortLogInTitle]); return title; } - (NSAttributedString *)_logOutTitle { - NSString *string = NSLocalizedStringWithDefaultValue(@"LoginButton.LogOut", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log out", - @"The label for the FBSDKLoginButton when the user is currently logged in"); + NSString *string = NSLocalizedStringWithDefaultValue( + @"LoginButton.LogOut", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log out", + @"The label for the FBSDKLoginButton when the user is currently logged in" + ); return [self attributedTitleStringFromString:string]; } - (NSAttributedString *)_longLogInTitle { - NSString *string = NSLocalizedStringWithDefaultValue(@"LoginButton.LogInLong", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log in with Facebook", - @"The long label for the FBSDKLoginButton when the user is currently logged out"); + NSString *string = NSLocalizedStringWithDefaultValue( + @"LoginButton.LogInLong", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log in with Facebook", + @"The long label for the FBSDKLoginButton when the user is currently logged out" + ); return [self attributedTitleStringFromString:string]; } - (NSAttributedString *)_shortLogInTitle { - NSString *string = NSLocalizedStringWithDefaultValue(@"LoginButton.LogIn", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Log in", - @"The short label for the FBSDKLoginButton when the user is currently logged out"); + NSString *string = NSLocalizedStringWithDefaultValue( + @"LoginButton.LogIn", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Log in", + @"The short label for the FBSDKLoginButton when the user is currently logged out" + ); return [self attributedTitleStringFromString:string]; } diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginViewController.m b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginViewController.m index 9004685137..717cc2c4ef 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginViewController.m +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKDeviceLoginViewController.m @@ -21,17 +21,18 @@ #import #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif -@interface FBSDKDeviceLoginViewController() < +@interface FBSDKDeviceLoginViewController () < FBSDKDeviceLoginManagerDelegate > @end -@implementation FBSDKDeviceLoginViewController { +@implementation FBSDKDeviceLoginViewController +{ FBSDKDeviceLoginManager *_loginManager; BOOL _isRetry; } @@ -70,9 +71,9 @@ - (void)deviceLoginManager:(FBSDKDeviceLoginManager *)loginManager completedWith self.delegate = nil; FBSDKAccessToken *token = result.accessToken; - BOOL requireConfirm = (([FBSDKServerConfigurationManager cachedServerConfiguration].smartLoginOptions & FBSDKServerConfigurationSmartLoginOptionsRequireConfirmation) && - (token != nil) && - !_isRetry); + BOOL requireConfirm = (([FBSDKServerConfigurationManager cachedServerConfiguration].smartLoginOptions & FBSDKServerConfigurationSmartLoginOptionsRequireConfirmation) + && (token != nil) + && !_isRetry); if (requireConfirm) { FBSDKGraphRequest *graphRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{ @"fields" : @"name" } @@ -87,16 +88,24 @@ - (void)deviceLoginManager:(FBSDKDeviceLoginManager *)loginManager completedWith }); }]; } else if ([self isNetworkError:error]) { - NSString *networkErrorMessage = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Network", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"Unable to connect to Facebook. Check your network connection and try again.", - @"The user facing error message when the Accounts framework encounters a network error."); + NSString *networkErrorMessage = NSLocalizedStringWithDefaultValue( + @"LoginError.SystemAccount.Network", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Unable to connect to Facebook. Check your network connection and try again.", + @"The user facing error message when the Accounts framework encounters a network error." + ); UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:networkErrorMessage preferredStyle:UIAlertControllerStyleAlert]; - NSString *localizedOK = NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Alert.OK", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], - @"OK", - @"The title of the label to dismiss the alert when presenting user facing error messages"); + NSString *localizedOK = NSLocalizedStringWithDefaultValue( + @"ErrorRecovery.Alert.OK", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"OK", + @"The title of the label to dismiss the alert when presenting user facing error messages" + ); UIAlertAction *okAction = [UIAlertAction actionWithTitle:localizedOK style:UIAlertActionStyleCancel - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *_Nonnull action) { [self dismissViewControllerAnimated:YES completion:^{ [delegate deviceLoginViewController:self didFailWithError:error]; }]; @@ -141,7 +150,7 @@ - (BOOL)isNetworkError:(NSError *)error #pragma mark - Private impl - (void)_notifySuccessForDelegate:(id)delegate - token:(FBSDKAccessToken *)token + token:(FBSDKAccessToken *)token { [FBSDKAccessToken setCurrentAccessToken:token]; [delegate deviceLoginViewControllerDidFinish:self]; @@ -152,30 +161,42 @@ - (void)_presentConfirmationForDelegate:(id for the alert when smart login requires confirmation"); + NSLocalizedStringWithDefaultValue( + @"SmartLogin.Continue", + @"FacebookSDK", + [FBSDKInternalUtility bundleForStrings], + @"Continue as %@", + @"The format string to continue as for the alert when smart login requires confirmation" + ); NSString *continueTitle = [NSString stringWithFormat:continueTitleFormatString, name]; UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:title preferredStyle:UIAlertControllerStyleActionSheet]; [alertController addAction:[UIAlertAction actionWithTitle:continueTitle style:UIAlertActionStyleDestructive - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *_Nonnull action) { [self dismissViewControllerAnimated:YES completion:^{ [self _notifySuccessForDelegate:delegate token:token]; }]; }]]; [alertController addAction:[UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel - handler:^(UIAlertAction * _Nonnull action) { + handler:^(UIAlertAction *_Nonnull action) { self->_isRetry = YES; FBSDKDeviceDialogView *view = [[FBSDKDeviceDialogView alloc] initWithFrame:self.view.frame]; view.delegate = self; @@ -185,20 +206,19 @@ - (void)_presentConfirmationForDelegate:(id - #import #ifdef FBSDKCOCOAPODS -#import + #import #else -#import "FBSDKCoreKit+Internal.h" + #import "FBSDKCoreKit+Internal.h" #endif #import "FBSDKDeviceLoginButton.h" #import "FBSDKTVLoginButtonElement.h" @@ -56,7 +55,8 @@ static Class FBSDKDynamicallyLoadShareKitClassFromString(NSString *className) return clazz; } -@implementation FBSDKTVInterfaceFactory { +@implementation FBSDKTVInterfaceFactory +{ id _interfaceCreator; } @@ -85,7 +85,10 @@ - (UIView *)viewForElement:(TVViewElement *)element button.redirectURL = [NSURL URLWithString:element.attributes[@"redirectURL"]]; return button; } else if ([element isKindOfClass:[FBSDKTVShareButtonElement class]]) { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" FBSDKDeviceShareButton *button = [[FBSDKDynamicallyLoadShareKitClassFromString(@"FBSDKDeviceShareButton") alloc] initWithFrame:CGRectZero]; + #pragma clang diagnostic pop id content = nil; if (element.attributes[@"href"]) { content = [[FBSDKDynamicallyLoadShareKitClassFromString(@"FBSDKShareLinkContent") alloc] init]; @@ -101,7 +104,6 @@ - (UIView *)viewForElement:(TVViewElement *)element reason:message userInfo:nil]; } - } if ([_interfaceCreator respondsToSelector:@selector(viewForElement:existingView:)]) { return [_interfaceCreator viewForElement:element existingView:existingView]; diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginButtonElement.m b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginButtonElement.m index 54d3dd43c8..66c941fd95 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginButtonElement.m +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginButtonElement.m @@ -30,14 +30,16 @@ - (void)deviceLoginButtonDidCancel:(FBSDKDeviceLoginButton *)button extraInfo:nil completion:NULL]; } + - (void)deviceLoginButton:(FBSDKDeviceLoginButton *)button didFailWithError:(NSError *)error { [self dispatchEventWithName:@"onFacebookLoginError" canBubble:YES cancellable:YES - extraInfo: @{ @"error": error } + extraInfo:@{ @"error" : error } completion:NULL]; } + - (void)deviceLoginButtonDidLogIn:(FBSDKDeviceLoginButton *)button { [self dispatchEventWithName:@"onFacebookLogin" @@ -46,6 +48,7 @@ - (void)deviceLoginButtonDidLogIn:(FBSDKDeviceLoginButton *)button extraInfo:nil completion:NULL]; } + - (void)deviceLoginButtonDidLogOut:(FBSDKDeviceLoginButton *)button { [self dispatchEventWithName:@"onFacebookLogout" @@ -54,4 +57,5 @@ - (void)deviceLoginButtonDidLogOut:(FBSDKDeviceLoginButton *)button extraInfo:nil completion:NULL]; } + @end diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginViewControllerElement.m b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginViewControllerElement.m index 16881231e0..bc58ac74d6 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginViewControllerElement.m +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVLoginViewControllerElement.m @@ -43,7 +43,7 @@ - (void)deviceLoginViewController:(FBSDKDeviceLoginViewController *)viewControll [self dispatchEventWithName:@"onFacebookLoginViewControllerError" canBubble:YES cancellable:YES - extraInfo: @{ @"error": error } + extraInfo:@{ @"error" : error } completion:NULL]; } diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h index fd848a0749..4e36ab3c27 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h @@ -16,8 +16,6 @@ // 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 @@ -26,3 +24,5 @@ #import #import #import + +#import diff --git a/FBSDKTVOSKit/FBSDKTVOSKitTests/FBSDKTVOSKitTests.m b/FBSDKTVOSKit/FBSDKTVOSKitTests/FBSDKTVOSKitTests.m index e9c7f7517c..95a2f4713d 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKitTests/FBSDKTVOSKitTests.m +++ b/FBSDKTVOSKit/FBSDKTVOSKitTests/FBSDKTVOSKitTests.m @@ -24,9 +24,10 @@ @interface FBSDKTVOSKitTests : XCTestCase @implementation FBSDKTVOSKitTests -- (void)testExample { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. +- (void)testExample +{ + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. } @end diff --git a/Package.swift b/Package.swift index 2d50cbfd5d..a1e75d07b3 100644 --- a/Package.swift +++ b/Package.swift @@ -24,7 +24,7 @@ import PackageDescription let package = Package( name: "Facebook", platforms: [ - .iOS(.v8), + .iOS(.v9), .tvOS(.v10) ], products: [ @@ -47,9 +47,12 @@ let package = Package( ], dependencies: [], targets: [ + .target( + name: "FBSDKCoreKit_Basics" + ), .target( name: "FBSDKCoreKit", - dependencies: [], + dependencies: ["FBSDKCoreKit_Basics"], path: "FBSDKCoreKit/FBSDKCoreKit", exclude: ["Swift"], cSettings: [ @@ -63,8 +66,6 @@ let package = Package( .headerSearchPath("AppEvents/Internal/SuggestedEvents"), .headerSearchPath("AppLink"), .headerSearchPath("AppLink/Internal"), - .headerSearchPath("Basics/Instrument"), - .headerSearchPath("Basics/Internal"), .headerSearchPath("GraphAPI"), .headerSearchPath("Internal"), .headerSearchPath("Internal/Base64"), @@ -131,7 +132,8 @@ let package = Package( cSettings: [ .headerSearchPath("Internal"), .headerSearchPath("../../FBSDKCoreKit/FBSDKCoreKit/Internal"), - .headerSearchPath("../../FBSDKShareKit/FBSDKShareKit/Internal") + .headerSearchPath("../../FBSDKShareKit/FBSDKShareKit/Internal"), + .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) ] ), .target( diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKBasicUtility.m b/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m similarity index 87% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKBasicUtility.m rename to Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m index 7d18965daa..fe61144e78 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKBasicUtility.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m @@ -16,9 +16,11 @@ // 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 "FBSDKBasicUtility.h" + +#import #import -#import "FBSDKBasicUtility.h" #import "FBSDKTypeUtility.h" #define kChunkSize 1024 @@ -59,10 +61,10 @@ + (NSString *)JSONStringForObject:(id)object return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } -+ (BOOL)dictionary:(NSMutableDictionary *)dictionary -setJSONStringForObject:(id)object - forKey:(id)key - error:(NSError *__autoreleasing *)errorRef ++ (BOOL) dictionary:(NSMutableDictionary *)dictionary + setJSONStringForObject:(id)object + forKey:(id)key + error:(NSError *__autoreleasing *)errorRef { if (!object || !key) { return YES; @@ -86,10 +88,10 @@ + (id)_convertObjectToJSONObject:(id)object object = ((NSURL *)object).absoluteString; } else if ([object isKindOfClass:[NSDictionary class]]) { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:(NSDictionary *)object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *dictionaryStop) { + [FBSDKTypeUtility dictionary:(NSDictionary *) object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *dictionaryStop) { [FBSDKTypeUtility dictionary:dictionary - setObject:[self _convertObjectToJSONObject:obj invalidObjectHandler:invalidObjectHandler stop:&stop] - forKey:[FBSDKTypeUtility stringValue:key]]; + setObject:[self _convertObjectToJSONObject:obj invalidObjectHandler:invalidObjectHandler stop:&stop] + forKey:[FBSDKTypeUtility stringValue:key]]; if (stop) { *dictionaryStop = YES; } @@ -135,7 +137,7 @@ + (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary if (dictionary) { NSMutableArray *keys = [dictionary.allKeys mutableCopy]; // remove non-string keys, as they are not valid - [keys filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { + [keys filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL (id evaluatedObject, NSDictionary *bindings) { return [evaluatedObject isKindOfClass:[NSString class]]; }]]; // sort the keys so that the query string order is deterministic @@ -181,11 +183,13 @@ + (id)convertRequestValue:(id)value #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (NSString *)URLEncode:(NSString *)value { - return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, - (CFStringRef)value, - NULL, // characters to leave unescaped - CFSTR(":!*();@/&?+$,='"), - kCFStringEncodingUTF8); + return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes( + NULL, + (CFStringRef)value, + NULL, // characters to leave unescaped + CFSTR(":!*();@/&?+$,='"), + kCFStringEncodingUTF8 + ); } #pragma clang diagnostic pop @@ -224,10 +228,10 @@ + (NSString *)URLEncode:(NSString *)value + (NSString *)URLDecode:(NSString *)value { value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "]; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -#pragma clang diagnostic pop + #pragma clang diagnostic pop return value; } @@ -323,4 +327,28 @@ + (void)persistAnonymousID:(NSString *)anonymousID error:nil]; } ++ (NSString *)SHA256Hash:(NSObject *)input +{ + NSData *data = nil; + + if ([input isKindOfClass:[NSData class]]) { + data = (NSData *)input; + } else if ([input isKindOfClass:[NSString class]]) { + data = [(NSString *)input dataUsingEncoding:NSUTF8StringEncoding]; + } + + if (!data) { + return nil; + } + + uint8_t digest[CC_SHA256_DIGEST_LENGTH]; + CC_SHA256(data.bytes, (CC_LONG)data.length, digest); + NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; + for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { + [hashed appendFormat:@"%02x", digest[i]]; + } + + return [hashed copy]; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m similarity index 82% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashHandler.m rename to Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index 33c5b8c9f1..30fca2d7fd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -18,22 +18,38 @@ #import "FBSDKCrashHandler.h" -#import - #import #include +#import -#import "FBSDKBasicUtility.h" #import "FBSDKLibAnalyzer.h" #import "FBSDKTypeUtility.h" #define FBSDK_MAX_CRASH_LOGS 5 #define FBSDK_CRASH_PATH_NAME @"instrument" #ifndef FBSDK_VERSION_STRING -#define FBSDK_VERSION_STRING @"7.1.1" + #define FBSDK_VERSION_STRING @"7.1.1" #endif +static const int fatalSignals[] = +{ + SIGBUS, + SIGFPE, + SIGILL, + SIGPIPE, + SIGSEGV, + SIGSYS, + SIGTRAP, +}; +static const int fatalSignalsCount = sizeof(fatalSignals) / sizeof(int); +static struct sigaction *previousSignalHandlers = NULL; + +static void installSignalsHandler(void); +static void uninstallSignalsHandler(void); +static void FBSDKSignalHandler(int signal, siginfo_t *signalInfo, void *userContext); +static int signalIndex(int signal); + static NSUncaughtExceptionHandler *previousExceptionHandler = NULL; static NSString *mappingTableIdentifier = NULL; static NSString *directoryPath; @@ -54,8 +70,6 @@ @implementation FBSDKCrashHandler static NSArray *> *_processedCrashLogs; static BOOL _isTurnedOff; -void FBSDKSignalHandler(int signal); - # pragma mark - Class Methods + (void)initialize @@ -110,6 +124,7 @@ + (void)disable { _isTurnedOff = YES; [FBSDKCrashHandler uninstallExceptionsHandler]; + uninstallSignalsHandler(); _observers = nil; } @@ -121,12 +136,14 @@ + (void)addObserver:(id)observer static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ [FBSDKCrashHandler installExceptionsHandler]; - [FBSDKCrashHandler installSignalHandler]; + installSignalsHandler(); _processedCrashLogs = [self getProcessedCrashLogs]; }); if (![_observers containsObject:observer]) { [_observers addObject:observer]; - [self generateMethodMapping:observer]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) { + [self generateMethodMapping:observer]; + }); [self sendCrashLogs]; } } @@ -137,6 +154,7 @@ + (void)removeObserver:(id)observer [_observers removeObject:observer]; if (_observers.count == 0) { [FBSDKCrashHandler uninstallExceptionsHandler]; + uninstallSignalsHandler(); } } } @@ -167,17 +185,33 @@ static void FBSDKExceptionHandler(NSException *exception) } } -+ (void)installSignalHandler +static void installSignalsHandler() { - signal(SIGBUS, FBSDKSignalHandler); - signal(SIGFPE, FBSDKSignalHandler); - signal(SIGILL, FBSDKSignalHandler); - signal(SIGPIPE, FBSDKSignalHandler); - signal(SIGSEGV, FBSDKSignalHandler); - signal(SIGSYS, FBSDKSignalHandler); + previousSignalHandlers = malloc(sizeof(*previousSignalHandlers) * (unsigned)fatalSignalsCount); + struct sigaction action = {{0}, 0, 0}; + action.sa_flags = SA_SIGINFO | SA_ONSTACK; +#if defined(__LP64__) && __LP64__ + action.sa_flags |= SA_64REGSET; +#endif + sigemptyset(&action.sa_mask); + for (size_t i = 0; i < fatalSignalsCount; i++) { + sigaddset(&action.sa_mask, fatalSignals[i]); + } + action.sa_sigaction = &FBSDKSignalHandler; + + for (int i = 0; i < fatalSignalsCount; i++) { + sigaction(fatalSignals[i], &action, &previousSignalHandlers[i]); + } } -void FBSDKSignalHandler(int sig) +static void uninstallSignalsHandler() +{ + for (int i = 0; i < fatalSignalsCount; i++) { + sigaction(fatalSignals[i], &previousSignalHandlers[i], NULL); + } +} + +static void FBSDKSignalHandler(int signal, siginfo_t *signalInfo, void *userContext) { NSMutableArray *callStack = [[NSThread callStackSymbols] mutableCopy]; if (callStack) { @@ -186,12 +220,27 @@ void FBSDKSignalHandler(int sig) [callStack removeObjectsAtIndexes:indexSet]; } } - [FBSDKCrashHandler saveSignal:sig withCallStack:callStack]; + [FBSDKCrashHandler saveSignal:signal withCallStack:callStack]; + + int index = signalIndex(signal); + if (index > 0) { + if (previousSignalHandlers[index].sa_handler != SIG_IGN) { + void (*previousSignalHandler)(int, siginfo_t *, void *) = previousSignalHandlers[index].sa_sigaction; + if (previousSignalHandler != NULL) { + previousSignalHandler(signal, signalInfo, userContext); + } + } + } +} - // reset to default handler - signal(sig, SIG_DFL); - // re-signal to default handler - raise(sig); +static int signalIndex(int signal) +{ + for (int i = 0; i < fatalSignalsCount; i++) { + if (signal == fatalSignals[i]) { + return i; + } + } + return -1; } #pragma mark - Storage @@ -201,9 +250,9 @@ + (void)saveException:(NSException *)exception if (exception.callStackSymbols && exception.name) { NSArray *stackSymbols = [NSArray arrayWithArray:exception.callStackSymbols]; [self saveCrashLog:@{ - kFBSDKCallstack : stackSymbols, - kFBSDKCrashReason : exception.name, - }]; + kFBSDKCallstack : stackSymbols, + kFBSDKCrashReason : exception.name, + }]; } } @@ -212,9 +261,9 @@ + (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack if (callStack) { NSString *signalDescription = [NSString stringWithCString:strsignal(signal) encoding:NSUTF8StringEncoding] ?: [NSString stringWithFormat:@"SIGNUM(%i)", signal]; [self saveCrashLog:@{ - kFBSDKCallstack : callStack, - kFBSDKCrashReason : signalDescription, - }]; + kFBSDKCallstack : callStack, + kFBSDKCrashReason : signalDescription, + }]; } } @@ -233,9 +282,9 @@ + (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack if (!data) { continue; } - NSDictionary *methodMapping = [FBSDKTypeUtility JSONObjectWithData:data - options:kNilOptions - error:nil]; + NSDictionary *methodMapping = [FBSDKTypeUtility JSONObjectWithData:data + options:kNilOptions + error:nil]; NSArray *symbolicatedCallstack = [FBSDKLibAnalyzer symbolicateCallstack:callstack methodMapping:methodMapping]; NSMutableDictionary *symbolicatedCrashLog = [NSMutableDictionary dictionaryWithDictionary:crashLog]; if (symbolicatedCallstack) { @@ -250,7 +299,7 @@ + (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack + (NSArray *> *)loadCrashLogs { NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:NULL]; - NSArray *fileNames = [[self getCrashLogFileNames:files] sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2){ + NSArray *fileNames = [[self getCrashLogFileNames:files] sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { return [obj2 compare:obj1]; }]; NSMutableArray *> *crashLogArray = [NSMutableArray array]; @@ -260,9 +309,9 @@ + (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack if (!data) { continue; } - NSDictionary* crashLog = [FBSDKTypeUtility JSONObjectWithData:data - options:kNilOptions - error:nil]; + NSDictionary *crashLog = [FBSDKTypeUtility JSONObjectWithData:data + options:kNilOptions + error:nil]; if (crashLog) { [FBSDKTypeUtility array:crashLogArray addObject:crashLog]; } @@ -333,10 +382,10 @@ + (void)generateMethodMapping:(id)observer [[NSUserDefaults standardUserDefaults] setObject:mappingTableIdentifier forKey:kFBSDKMappingTableIdentifier]; NSDictionary *methodMapping = [FBSDKLibAnalyzer getMethodsTable:observer.prefixes frameworks:observer.frameworks]; - if (methodMapping.count > 0){ + if (methodMapping.count > 0) { NSData *data = [FBSDKTypeUtility dataWithJSONObject:methodMapping options:0 error:nil]; [data writeToFile:[self getPathToLibDataFile:mappingTableIdentifier] - atomically:YES]; + atomically:YES]; } } @@ -356,7 +405,6 @@ + (NSString *)getPathToLibDataFile:(NSString *)identifier { return [directoryPath stringByAppendingPathComponent: [NSString stringWithFormat:@"crash_lib_data_%@.json", identifier]]; - } + (BOOL)isSafeToGenerateMapping @@ -365,7 +413,7 @@ + (BOOL)isSafeToGenerateMapping return YES; #else NSString *identifier = [[NSUserDefaults standardUserDefaults] objectForKey:kFBSDKMappingTableIdentifier]; - //first app start + // first app start if (!identifier) { return YES; } diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.m b/Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.m new file mode 100644 index 0000000000..f73f2fd4ea --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.m @@ -0,0 +1,232 @@ +// 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 "FBSDKJSONValue.h" + +#import + +#import "FBSDKBasicUtility.h" +#import "FBSDKSafeCast.h" +#import "FBSDKTypeUtility.h" + +@interface FBSDKJSONField () +- (instancetype)initWithPotentialJSONField:(id)obj; +@end + +static NSArray *createArray(id obj) +{ + NSArray *const original = FBSDK_CAST_TO_CLASS_OR_NIL(obj, NSArray); + if (!original) { + return @[]; + } + + NSMutableArray *const fields = + [[NSMutableArray alloc] initWithCapacity:original.count]; + + for (id field in original) { + FBSDKJSONField *const f = [[FBSDKJSONField alloc] initWithPotentialJSONField:field]; + if (f) { + [fields addObject:f]; + } + } + + return fields; +} + +static NSDictionary *createDictionary(id obj) +{ + NSDictionary *const original = FBSDK_CAST_TO_CLASS_OR_NIL(obj, NSDictionary); + if (!original) { + return @{}; + } + + NSMutableDictionary *const fields = + [[NSMutableDictionary alloc] initWithCapacity:original.count]; + + for (id key in original) { + // This is just a sanity check. Apple should only give us string keys + // anyway. + if (![key respondsToSelector:@selector(isKindOfClass:)] || ![key isKindOfClass:NSString.class]) { + continue; + } + NSString *const stringKey = (NSString *)key; + + FBSDKJSONField *const typedField = [[FBSDKJSONField alloc] initWithPotentialJSONField:original[key]]; + if (typedField) { + fields[stringKey] = typedField; + } + } + + return fields; +} + +@implementation FBSDKJSONValue + +- (instancetype)initWithPotentialJSONObject:(id)obj +{ + // If this isn't a real JSON object, dump it. + if (![FBSDKTypeUtility isValidJSONObject:obj]) { + return nil; + } + _rawObject = obj; + + return self; +} + +- (void)matchArray:(void (^)(NSArray *))arrayMatcher + dictionary:(void (^)(NSDictionary *))dictMatcher +{ + if (arrayMatcher && [_rawObject isKindOfClass:[NSArray class]]) { + arrayMatcher(createArray(_rawObject)); + } else if (dictMatcher && [_rawObject isKindOfClass:[NSDictionary class]]) { + dictMatcher(createDictionary(_rawObject)); + } +} + +- (NSDictionary *_Nullable)matchDictionaryOrNil +{ + __block NSDictionary *result = nil; + [self matchArray:nil dictionary:^(NSDictionary *_Nonnull value) { + result = value; + }]; + return result; +} + +- (NSDictionary *_Nullable)unsafe_matchDictionaryOrNil +{ + return [_rawObject isKindOfClass:NSDictionary.class] ? _rawObject : nil; +} + +- (NSArray *_Nullable)matchArrayOrNil +{ + __block NSArray *result = nil; + [self matchArray:^(NSArray *_Nonnull value) { + result = value; + } dictionary:nil]; + return result; +} + +- (NSArray *_Nullable)unsafe_matchArrayOrNil +{ + __block BOOL isArray = NO; + [self matchArray:^(NSArray *_Nonnull _) { + isArray = YES; + } dictionary:nil]; + + return [_rawObject isKindOfClass:NSArray.class] ? _rawObject : nil; +} + +@end + +@implementation FBSDKJSONField + +- (instancetype)initWithPotentialJSONField:(id)obj +{ + // If this is nil, don't wrap it. + if (obj == nil) { + return nil; + } + + // Per Apple's Docs, these are the only types FBSDKTypeUtility can return. + if ( + ![obj isKindOfClass:NSString.class] + && ![obj isKindOfClass:NSNumber.class] + && ![obj isKindOfClass:NSNull.class] + && ![obj isKindOfClass:NSDictionary.class] + && ![obj isKindOfClass:NSArray.class]) { + return nil; + } + + if (self = [super init]) { + _rawObject = obj; + } + + return self; +} + +- (void)matchArray:(void (^)(NSArray *))arrayMatcher + dictionary:(void (^)(NSDictionary *_Nonnull))dictionaryMatcher + string:(void (^)(NSString *_Nonnull))stringMatcher + number:(void (^)(NSNumber *_Nonnull))numberMatcher + null:(void (^)(void))nullMatcher +{ + if (nullMatcher && [_rawObject isKindOfClass:NSNull.class]) { + nullMatcher(); + } else if (numberMatcher && [_rawObject isKindOfClass:NSNumber.class]) { + numberMatcher(_rawObject); + } else if (stringMatcher && [_rawObject isKindOfClass:NSString.class]) { + stringMatcher(_rawObject); + } else if (arrayMatcher && [_rawObject isKindOfClass:NSArray.class]) { + arrayMatcher(createArray(_rawObject)); + } else if (dictionaryMatcher && [_rawObject isKindOfClass:NSDictionary.class]) { + dictionaryMatcher(createDictionary(_rawObject)); + } +} + +- (NSArray *_Nullable)arrayOrNil +{ + __block NSArray *result = nil; + [self matchArray:^(NSArray *_Nonnull a) { + result = [a copy]; + } dictionary:nil string:nil number:nil null:nil]; + return result; +} + +- (NSDictionary *_Nullable)dictionaryOrNil +{ + __block NSDictionary *result = nil; + [self matchArray:nil dictionary:^(NSDictionary *_Nonnull d) { + result = [d copy]; + } string:nil number:nil null:nil]; + return result; +} + +- (NSString *_Nullable)stringOrNil +{ + __block NSString *result = nil; + [self matchArray:nil dictionary:nil string:^(NSString *_Nonnull s) { + result = [s copy]; + } number:nil null:nil]; + return result; +} + +- (NSNumber *_Nullable)numberOrNil +{ + __block NSNumber *result = nil; + [self matchArray:nil dictionary:nil string:nil number:^(NSNumber *_Nonnull n) { + result = n; + } null:nil]; + return result; +} + +- (NSNull *_Nullable)nullOrNil +{ + __block NSNull *result = nil; + [self matchArray:nil dictionary:nil string:nil number:nil null:^{ + result = [NSNull null]; + }]; + return result; +} + +@end + +FBSDKJSONValue *_Nullable FBSDKCreateJSONFromString(NSString *_Nullable string, NSError *__autoreleasing *errorRef) +{ + return + [[FBSDKJSONValue alloc] initWithPotentialJSONObject:[FBSDKBasicUtility objectForJSONString:string error:errorRef]]; +} diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKLibAnalyzer.m b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m similarity index 95% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKLibAnalyzer.m rename to Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m index 2d0567063c..7da024782d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKLibAnalyzer.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m @@ -17,10 +17,11 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLibAnalyzer.h" -#import "FBSDKTypeUtility.h" #import +#import "FBSDKTypeUtility.h" + @implementation FBSDKLibAnalyzer static NSMutableDictionary *_methodMapping; @@ -41,7 +42,7 @@ + (void)initialize [self addClass:object_getClass(class) isClassMethod:YES]; } } - @synchronized (_methodMapping) { + @synchronized(_methodMapping) { return [_methodMapping copy]; } } @@ -80,7 +81,7 @@ + (void)initialize NSMutableArray *classNames = [NSMutableArray array]; unsigned int count = 0; const char **classes = objc_copyClassNamesForImage([image UTF8String], &count); - for (unsigned int i = 0; i < count; i++){ + for (unsigned int i = 0; i < count; i++) { NSString *className = [NSString stringWithUTF8String:classes[i]]; if (prefixes.count > 0) { for (NSString *prefix in prefixes) { @@ -119,7 +120,7 @@ + (void)addClass:(Class)class NSStringFromSelector(selector)]; if (methodAddress && methodName) { - @synchronized (_methodMapping) { + @synchronized(_methodMapping) { [FBSDKTypeUtility dictionary:_methodMapping setObject:methodName forKey:methodAddress]; } } @@ -129,12 +130,12 @@ + (void)addClass:(Class)class } + (NSArray *)symbolicateCallstack:(NSArray *)callstack - methodMapping:(NSDictionary *)methodMapping + methodMapping:(NSDictionary *)methodMapping { if (!callstack || !methodMapping) { return nil; } - NSArray *sortedAllAddress = [methodMapping.allKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { + NSArray *sortedAllAddress = [methodMapping.allKeys sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { return [obj1 compare:obj2]; }]; @@ -142,9 +143,9 @@ + (void)addClass:(Class)class NSInteger nonSDKMethodCount = 0; NSMutableArray *symbolicatedCallstack = [NSMutableArray array]; - for (NSUInteger i = 0; i < callstack.count; i++){ + for (NSUInteger i = 0; i < callstack.count; i++) { NSString *rawAddress = [self getAddress:[FBSDKTypeUtility array:callstack objectAtIndex:i]]; - NSString *addressString = [NSString stringWithFormat:@"0x%@",[rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]]; + NSString *addressString = [NSString stringWithFormat:@"0x%@", [rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]]; NSString *methodAddress = [self searchMethod:addressString sortedAllAddress:sortedAllAddress]; if (methodAddress) { @@ -219,7 +220,7 @@ + (NSString *)searchMethod:(NSString *)address NSUInteger index = [sortedAllAddress indexOfObject:address inSortedRange:NSMakeRange(0, sortedAllAddress.count - 1) options:NSBinarySearchingInsertionIndex - usingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { + usingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { return [obj1 compare:obj2]; }]; return [FBSDKTypeUtility array:sortedAllAddress objectAtIndex:index - 1]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKSafeCast.m b/Sources/FBSDKCoreKit_Basics/FBSDKSafeCast.m similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKSafeCast.m rename to Sources/FBSDKCoreKit_Basics/FBSDKSafeCast.m diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKTypeUtility.m b/Sources/FBSDKCoreKit_Basics/FBSDKTypeUtility.m similarity index 90% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKTypeUtility.m rename to Sources/FBSDKCoreKit_Basics/FBSDKTypeUtility.m index 80e3b18032..572ab02ae8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKTypeUtility.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKTypeUtility.m @@ -43,7 +43,8 @@ + (void)array:(NSMutableArray *)array addObject:(id)object } } -+ (void)array:(NSMutableArray *)array addObject:(nullable id)object atIndex:(NSUInteger)index { ++ (void)array:(NSMutableArray *)array addObject:(nullable id)object atIndex:(NSUInteger)index +{ if (object && [array isKindOfClass:NSMutableArray.class]) { if (index < array.count) { [array insertObject:object atIndex:index]; @@ -89,7 +90,7 @@ + (void)dictionary:(NSMutableDictionary *)dictionary setObject:(id)object forKey } } -+ (void)dictionary:(NSDictionary *)dictionary enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(id key, id obj, BOOL *stop))block ++ (void)dictionary:(NSDictionary *)dictionary enumerateKeysAndObjectsUsingBlock:(void(NS_NOESCAPE ^)(id key, id obj, BOOL *stop))block { NSDictionary *validDictionary = [self dictionaryValue:dictionary]; if (validDictionary) { @@ -173,20 +174,19 @@ + (BOOL)isValidJSONObject:(id)obj return [NSJSONSerialization isValidJSONObject:obj]; } -+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError *__autoreleasing _Nullable *)error ++ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError *__autoreleasing _Nullable *)error { NSData *data; @try { data = [NSJSONSerialization dataWithJSONObject:obj options:opt error:error]; - } - @catch (NSException *exception) { - NSLog(@"FBSDKJSONSerialization - dataWithJSONObject:options:error failed: %@", exception.reason); + } @catch (NSException *exception) { + NSLog(@"FBSDKJSONSerialization - dataWithJSONObject:options:error failed: %@", exception.reason); } return data; } -+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError *__autoreleasing _Nullable *)error ++ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError *__autoreleasing _Nullable *)error { if (![data isKindOfClass:NSData.class]) { return nil; @@ -194,10 +194,9 @@ + (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error: id object; @try { - object = [NSJSONSerialization JSONObjectWithData:data options:opt error:error]; - } - @catch (NSException *exception) { - NSLog(@"FBSDKJSONSerialization - JSONObjectWithData:options:error failed: %@", exception.reason); + object = [NSJSONSerialization JSONObjectWithData:data options:opt error:error]; + } @catch (NSException *exception) { + NSLog(@"FBSDKJSONSerialization - JSONObjectWithData:options:error failed: %@", exception.reason); } return object; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSession.m b/Sources/FBSDKCoreKit_Basics/FBSDKURLSession.m similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSession.m rename to Sources/FBSDKCoreKit_Basics/FBSDKURLSession.m diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSessionTask.m b/Sources/FBSDKCoreKit_Basics/FBSDKURLSessionTask.m similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSessionTask.m rename to Sources/FBSDKCoreKit_Basics/FBSDKURLSessionTask.m diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKUserDataStore.m b/Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m similarity index 88% rename from FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKUserDataStore.m rename to Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m index e4428309a8..e6da0e1334 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKUserDataStore.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m @@ -18,14 +18,11 @@ #import "FBSDKUserDataStore.h" -#import "FBSDKAppEventsUtility.h" -#import "FBSDKLogger.h" -#import "FBSDKSettings.h" -#import "FBSDKUtility.h" +#import "FBSDKBasicUtility.h" #import "FBSDKTypeUtility.h" -static NSString *const FBSDKUserDataKey = @"com.facebook.appevents.UserDataStore.userData"; -static NSString *const FBSDKInternalUserDataKey = @"com.facebook.appevents.UserDataStore.internalUserData"; +static NSString *const FBSDKUserDataKey = @"com.facebook.appevents.UserDataStore.userData"; +static NSString *const FBSDKInternalUserDataKey = @"com.facebook.appevents.UserDataStore.internalUserData"; static NSMutableDictionary *hashedUserData; static NSMutableDictionary *internalHashedUserData; @@ -33,6 +30,21 @@ static dispatch_queue_t serialQueue; +// +// Public event user data types +// + +FBSDKAppEventUserDataType FBSDKAppEventEmail = @"em"; +FBSDKAppEventUserDataType FBSDKAppEventFirstName = @"fn"; +FBSDKAppEventUserDataType FBSDKAppEventLastName = @"ln"; +FBSDKAppEventUserDataType FBSDKAppEventPhone = @"ph"; +FBSDKAppEventUserDataType FBSDKAppEventDateOfBirth = @"dob"; +FBSDKAppEventUserDataType FBSDKAppEventGender = @"ge"; +FBSDKAppEventUserDataType FBSDKAppEventCity = @"ct"; +FBSDKAppEventUserDataType FBSDKAppEventState = @"st"; +FBSDKAppEventUserDataType FBSDKAppEventZip = @"zp"; +FBSDKAppEventUserDataType FBSDKAppEventCountry = @"country"; + @implementation FBSDKUserDataStore + (void)initialize @@ -173,8 +185,8 @@ + (NSString *)getInternalHashedDataForType:(FBSDKAppEventUserDataType)type NSMutableDictionary *hashedUD = nil; if (userData) { hashedUD = (NSMutableDictionary *)[FBSDKTypeUtility JSONObjectWithData:[userData dataUsingEncoding:NSUTF8StringEncoding] - options:NSJSONReadingMutableContainers - error:nil]; + options: NSJSONReadingMutableContainers + error: nil]; } if (!hashedUD) { hashedUD = [[NSMutableDictionary alloc] init]; @@ -186,13 +198,12 @@ + (NSString *)stringByHashedData:(id)hashedData { NSError *error; NSData *jsonData = [FBSDKTypeUtility dataWithJSONObject:hashedData - options:0 - error:&error]; + options:0 + error:&error]; if (jsonData) { return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } else { - [FBSDKAppEventsUtility logAndNotify:[NSString stringWithFormat:@"Invalid json object: %@", error]]; return @""; } } @@ -203,7 +214,7 @@ + (NSString *)encryptData:(NSString *)data if (data.length == 0 || [FBSDKUserDataStore maybeSHA256Hashed:data]) { return data; } - return [FBSDKUtility SHA256Hash:[FBSDKUserDataStore normalizeData:data type:type]]; + return [FBSDKBasicUtility SHA256Hash:[FBSDKUserDataStore normalizeData:data type:type]]; } + (NSString *)normalizeData:(NSString *)data @@ -220,16 +231,16 @@ + (NSString *)normalizeData:(NSString *)data NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9]" options:NSRegularExpressionCaseInsensitive error:&error - ]; + ]; normalizedData = [regex stringByReplacingMatchesInString:data options:0 range:NSMakeRange(0, data.length) withTemplate:@"" - ]; + ]; } else if ([type isEqualToString:FBSDKAppEventGender]) { NSString *temp = [data stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; temp = temp.lowercaseString; - normalizedData = temp.length > 0 ? [temp substringToIndex:1]: @""; + normalizedData = temp.length > 0 ? [temp substringToIndex:1] : @""; } return normalizedData; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKBasicUtility.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h similarity index 98% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKBasicUtility.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h index cebaffb0d9..718c3229d3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKBasicUtility.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h @@ -112,6 +112,7 @@ setJSONStringForObject:(id)object + (NSString *)anonymousID; + (NSString *)persistenceFilePath:(NSString *)filename; ++ (nullable NSString *)SHA256Hash:(nullable NSObject *)input; @end diff --git a/Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h new file mode 100644 index 0000000000..e645f91073 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h @@ -0,0 +1,41 @@ +// 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. + +#ifdef BUCK + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import +#else + #import "FBSDKBasicUtility.h" + #import "FBSDKCrashHandler.h" + #import "FBSDKCrashObserving.h" + #import "FBSDKJSONValue.h" + #import "FBSDKLibAnalyzer.h" + #import "FBSDKSafeCast.h" + #import "FBSDKTypeUtility.h" + #import "FBSDKURLSession.h" + #import "FBSDKURLSessionTask.h" + #import "FBSDKUserDataStore.h" +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashHandler.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKCrashHandler.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashHandler.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKCrashHandler.h diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashObserving.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKCrashObserving.h similarity index 95% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashObserving.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKCrashObserving.h index 070416cabf..a210191a37 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashObserving.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKCrashObserving.h @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN @protocol FBSDKCrashObserving @property (nonatomic, copy) NSArray *prefixes; -@property (nonatomic, copy, nullable) NSArray *frameworks; +@property (nullable, nonatomic, copy) NSArray *frameworks; @optional diff --git a/Sources/FBSDKCoreKit_Basics/include/FBSDKJSONValue.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKJSONValue.h new file mode 100644 index 0000000000..5d953da45d --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKJSONValue.h @@ -0,0 +1,112 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN +/** + The purpose of this class is to serve as thin, type-safe wrapper + around FBSDKTypeUtility + */ +@interface FBSDKJSONField : NSObject + +/** + This can only be created by FBSDKJSONValue. + */ +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** +A safe method to unpack the values in the top-level JSON object. + https://developer.apple.com/documentation/foundation/nsjsonserialization +*/ +- (void)matchArray:(void (^_Nullable)(NSArray *_Nonnull))arrayMatcher + dictionary:(void (^_Nullable)(NSDictionary *_Nonnull))dictionaryMatcher + string:(void (^_Nullable)(NSString *_Nonnull))stringMatcher + number:(void (^_Nullable)(NSNumber *_Nonnull))numberMatcher + null:(void (^_Nullable)(void))nullMatcher; + +/** + The underlying JSON object. The only guarantee we provide with this + is that it passes [FBSDKTypeUtility isValidJSONObject:] + */ +@property (nonnull, nonatomic, readonly, strong) id rawObject; + +- (NSArray *_Nullable)arrayOrNil; +- (NSDictionary *_Nullable)dictionaryOrNil; +- (NSString *_Nullable)stringOrNil; +- (NSNumber *_Nullable)numberOrNil; +- (NSNull *_Nullable)nullOrNil; + +@end + +/** + Represents Top-level JSON objects. + */ +@interface FBSDKJSONValue : NSObject + +/** + If the object does not pass [FBSDKTypeUtility isValidJSONObject:] + this will return nil. + */ +- (_Nullable instancetype)initWithPotentialJSONObject:(id)obj; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + The underlying JSON object. The only guarantee we provide with this + is that it passes [FBSDKTypeUtility isValidJSONObject:] + */ +@property (nonatomic, readonly, strong) id rawObject; + +/** + A safe method to unpack the values in the top-level JSON object. + + The specs are per Apple's documentation: https://developer.apple.com/documentation/foundation/nsjsonserialization + */ +- (void)matchArray:(void (^_Nullable)(NSArray *))arrayMatcher + dictionary:(void (^_Nullable)(NSDictionary *))dictMatcher; + +/** + Returns the dictionary if that's truly what it is, otherwise, nil. + */ +- (NSDictionary *_Nullable)matchDictionaryOrNil; + +/** + The unsafe variant which drops all the type-safety for this class. + If this object is nonnull, you at least have guarantees from Apple that this is NSNull, NSString, NSNumber, NSArray, or NSDictionary. + */ +- (NSDictionary *_Nullable)unsafe_matchDictionaryOrNil; + +- (NSArray *_Nullable)matchArrayOrNil; +- (NSArray *_Nullable)unsafe_matchArrayOrNil; + +@end + +/** +FBSDKTypeUtility returns id, which is problematic in our codebase. + +You can wrap resulting objects in this to force users of your JSON to use +type-safe bindings. + +If this is not a valid JSON object...this will return nil. +*/ +FBSDKJSONValue *_Nullable FBSDKCreateJSONFromString(NSString *_Nullable string, NSError *__autoreleasing *errorRef); + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKLibAnalyzer.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKLibAnalyzer.h similarity index 95% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKLibAnalyzer.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKLibAnalyzer.h index e6873adef1..5303875be2 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKLibAnalyzer.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKLibAnalyzer.h @@ -23,9 +23,9 @@ NS_ASSUME_NONNULL_BEGIN @interface FBSDKLibAnalyzer : NSObject + (NSDictionary *)getMethodsTable:(NSArray *)prefixes - frameworks:(NSArray * _Nullable)frameworks; + frameworks:(NSArray *_Nullable)frameworks; + (nullable NSArray *)symbolicateCallstack:(NSArray *)callstack - methodMapping:(NSDictionary *)methodMapping; + methodMapping:(NSDictionary *)methodMapping; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKSafeCast.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKSafeCast.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKSafeCast.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKSafeCast.h diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKTypeUtility.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKTypeUtility.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKTypeUtility.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKTypeUtility.h diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSession.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKURLSession.h similarity index 89% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSession.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKURLSession.h index 34707dc4e1..e19287aadc 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSession.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKURLSession.h @@ -24,9 +24,9 @@ NS_ASSUME_NONNULL_BEGIN @interface FBSDKURLSession : NSObject -@property (atomic, strong, nullable) NSURLSession *session; -@property (nonatomic, weak, nullable) id delegate; -@property (nonatomic, retain, nullable) NSOperationQueue *delegateQueue; +@property (nullable, atomic, strong) NSURLSession *session; +@property (nullable, nonatomic, weak) id delegate; +@property (nullable, nonatomic, retain) NSOperationQueue *delegateQueue; - (instancetype)initWithDelegate:(id)delegate delegateQueue:(NSOperationQueue *)delegateQueue; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSessionTask.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKURLSessionTask.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/Basics/Internal/FBSDKURLSessionTask.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKURLSessionTask.h diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKUserDataStore.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h similarity index 61% rename from FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKUserDataStore.h rename to Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h index bbef7b3c34..f2e935128e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKUserDataStore.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h @@ -18,10 +18,42 @@ #import -#import "FBSDKAppEvents+Internal.h" - NS_ASSUME_NONNULL_BEGIN +/// typedef for FBSDKAppEventUserDataType +typedef NSString *const FBSDKAppEventUserDataType NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAME(AppEvents.UserDataType); + +/** Parameter key used to specify user's email. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventEmail; +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventEmail; + +/** Parameter key used to specify user's first name. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventFirstName; + +/** Parameter key used to specify user's last name. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventLastName; + +/** Parameter key used to specify user's phone. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventPhone; + +/** Parameter key used to specify user's date of birth. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventDateOfBirth; + +/** Parameter key used to specify user's gender. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventGender; + +/** Parameter key used to specify user's city. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventCity; + +/** Parameter key used to specify user's state. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventState; + +/** Parameter key used to specify user's zip. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventZip; + +/** Parameter key used to specify user's country. */ +FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventCountry; + NS_SWIFT_NAME(UserDataStore) @interface FBSDKUserDataStore : NSObject diff --git a/samples/Configurations/Project.xcconfig b/samples/Configurations/Project.xcconfig index 2174945e7e..aae9796b88 100644 --- a/samples/Configurations/Project.xcconfig +++ b/samples/Configurations/Project.xcconfig @@ -18,7 +18,7 @@ // Architectures ARCHS = i386 armv7 x86_64 arm64 -IPHONEOS_DEPLOYMENT_TARGET = 8.0 +IPHONEOS_DEPLOYMENT_TARGET = 9.0 SDKROOT = iphoneos // Build Options diff --git a/samples/FacebookLoginSample/FacebookLoginSample.xcodeproj/project.pbxproj b/samples/FacebookLoginSample/FacebookLoginSample.xcodeproj/project.pbxproj index 35134084b5..478506522f 100644 --- a/samples/FacebookLoginSample/FacebookLoginSample.xcodeproj/project.pbxproj +++ b/samples/FacebookLoginSample/FacebookLoginSample.xcodeproj/project.pbxproj @@ -13,7 +13,7 @@ F431CBE023DB5AA700A243D4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F431CBDE23DB5AA700A243D4 /* Main.storyboard */; }; F431CBE223DB5AAA00A243D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F431CBE123DB5AAA00A243D4 /* Assets.xcassets */; }; F431CBE523DB5AAA00A243D4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F431CBE323DB5AAA00A243D4 /* LaunchScreen.storyboard */; }; - F431CBFC23DB5CD200A243D4 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = F431CBFB23DB5CD200A243D4 /* FacebookLogin */; }; + F45CD1D524C7552D00C84BF7 /* FacebookLogin in Frameworks */ = {isa = PBXBuildFile; productRef = F45CD1D424C7552D00C84BF7 /* FacebookLogin */; }; F4D3AE8623DB60F7001BAF89 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4D3AE8523DB60F7001BAF89 /* LoginViewController.swift */; }; F4F742FD23DB7A3500A823A9 /* LoginManagerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4F742FC23DB7A3500A823A9 /* LoginManagerViewController.swift */; }; F4F742FF23DB832F00A823A9 /* LoginDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4F742FE23DB832F00A823A9 /* LoginDetailsViewController.swift */; }; @@ -28,6 +28,7 @@ F431CBE123DB5AAA00A243D4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; F431CBE423DB5AAA00A243D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; F431CBE623DB5AAA00A243D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F45CD1D224C7552300C84BF7 /* facebook-ios-sdk */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "facebook-ios-sdk"; path = ../..; sourceTree = ""; }; F4D3AE8523DB60F7001BAF89 /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = ""; }; F4F742FC23DB7A3500A823A9 /* LoginManagerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginManagerViewController.swift; sourceTree = ""; }; F4F742FE23DB832F00A823A9 /* LoginDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginDetailsViewController.swift; sourceTree = ""; }; @@ -38,7 +39,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F431CBFC23DB5CD200A243D4 /* FacebookLogin in Frameworks */, + F45CD1D524C7552D00C84BF7 /* FacebookLogin in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -48,8 +49,10 @@ F431CBCC23DB5AA700A243D4 = { isa = PBXGroup; children = ( + F45CD1D224C7552300C84BF7 /* facebook-ios-sdk */, F431CBD723DB5AA700A243D4 /* FacebookLoginSample */, F431CBD623DB5AA700A243D4 /* Products */, + F45CD1D324C7552D00C84BF7 /* Frameworks */, ); sourceTree = ""; }; @@ -78,6 +81,13 @@ path = FacebookLoginSample; sourceTree = ""; }; + F45CD1D324C7552D00C84BF7 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -95,7 +105,7 @@ ); name = FacebookLoginSample; packageProductDependencies = ( - F431CBFB23DB5CD200A243D4 /* FacebookLogin */, + F45CD1D424C7552D00C84BF7 /* FacebookLogin */, ); productName = FacebookLoginSample; productReference = F431CBD523DB5AA700A243D4 /* FacebookLoginSample.app */; @@ -126,7 +136,6 @@ ); mainGroup = F431CBCC23DB5AA700A243D4; packageReferences = ( - F431CBFA23DB5CD200A243D4 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */, ); productRefGroup = F431CBD623DB5AA700A243D4 /* Products */; projectDirPath = ""; @@ -357,21 +366,9 @@ }; /* End XCConfigurationList section */ -/* Begin XCRemoteSwiftPackageReference section */ - F431CBFA23DB5CD200A243D4 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/facebook/facebook-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 6.0.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - /* Begin XCSwiftPackageProductDependency section */ - F431CBFB23DB5CD200A243D4 /* FacebookLogin */ = { + F45CD1D424C7552D00C84BF7 /* FacebookLogin */ = { isa = XCSwiftPackageProductDependency; - package = F431CBFA23DB5CD200A243D4 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */; productName = FacebookLogin; }; /* End XCSwiftPackageProductDependency section */ diff --git a/samples/FacebookShareSample/FacebookShareSample.xcodeproj/project.pbxproj b/samples/FacebookShareSample/FacebookShareSample.xcodeproj/project.pbxproj index a7296d922c..a36f2e3971 100644 --- a/samples/FacebookShareSample/FacebookShareSample.xcodeproj/project.pbxproj +++ b/samples/FacebookShareSample/FacebookShareSample.xcodeproj/project.pbxproj @@ -7,13 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + F45CD1D124C754C100C84BF7 /* FacebookShare in Frameworks */ = {isa = PBXBuildFile; productRef = F45CD1D024C754C100C84BF7 /* FacebookShare */; }; F46A5FA523E1ED3200948850 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46A5FA423E1ED3200948850 /* AppDelegate.swift */; }; F46A5FA723E1ED3200948850 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46A5FA623E1ED3200948850 /* SceneDelegate.swift */; }; F46A5FA923E1ED3200948850 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46A5FA823E1ED3200948850 /* ShareViewController.swift */; }; F46A5FAC23E1ED3200948850 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F46A5FAA23E1ED3200948850 /* Main.storyboard */; }; F46A5FAE23E1ED3300948850 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F46A5FAD23E1ED3300948850 /* Assets.xcassets */; }; F46A5FB123E1ED3300948850 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F46A5FAF23E1ED3300948850 /* LaunchScreen.storyboard */; }; - F46A5FC823E1F3B800948850 /* FacebookShare in Frameworks */ = {isa = PBXBuildFile; productRef = F46A5FC723E1F3B800948850 /* FacebookShare */; }; F46A5FCA23E20C5300948850 /* ShareViewControllerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46A5FC923E20C5300948850 /* ShareViewControllerExtensions.swift */; }; /* End PBXBuildFile section */ @@ -28,6 +28,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + F45CD1CE24C754AB00C84BF7 /* facebook-ios-sdk */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "facebook-ios-sdk"; path = ../..; sourceTree = ""; }; F46A5FA123E1ED3200948850 /* FacebookShareSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FacebookShareSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; F46A5FA423E1ED3200948850 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; F46A5FA623E1ED3200948850 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -45,7 +46,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F46A5FC823E1F3B800948850 /* FacebookShare in Frameworks */, + F45CD1D124C754C100C84BF7 /* FacebookShare in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,11 +60,20 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + F45CD1CF24C754C100C84BF7 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; F46A5F9823E1ED3200948850 = { isa = PBXGroup; children = ( + F45CD1CE24C754AB00C84BF7 /* facebook-ios-sdk */, F46A5FA323E1ED3200948850 /* FacebookShareSample */, F46A5FA223E1ED3200948850 /* Products */, + F45CD1CF24C754C100C84BF7 /* Frameworks */, ); sourceTree = ""; }; @@ -108,7 +118,7 @@ ); name = FacebookShareSample; packageProductDependencies = ( - F46A5FC723E1F3B800948850 /* FacebookShare */, + F45CD1D024C754C100C84BF7 /* FacebookShare */, ); productName = FacebookShareSample; productReference = F46A5FA123E1ED3200948850 /* FacebookShareSample.app */; @@ -161,7 +171,6 @@ ); mainGroup = F46A5F9823E1ED3200948850; packageReferences = ( - F46A5FC623E1F3B800948850 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */, ); productRefGroup = F46A5FA223E1ED3200948850 /* Products */; projectDirPath = ""; @@ -466,21 +475,9 @@ }; /* End XCConfigurationList section */ -/* Begin XCRemoteSwiftPackageReference section */ - F46A5FC623E1F3B800948850 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/facebook/facebook-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 6.0.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - /* Begin XCSwiftPackageProductDependency section */ - F46A5FC723E1F3B800948850 /* FacebookShare */ = { + F45CD1D024C754C100C84BF7 /* FacebookShare */ = { isa = XCSwiftPackageProductDependency; - package = F46A5FC623E1F3B800948850 /* XCRemoteSwiftPackageReference "facebook-ios-sdk" */; productName = FacebookShare; }; /* End XCSwiftPackageProductDependency section */ diff --git a/samples/RPSSample/RPSSample/RPSAppDelegate.h b/samples/RPSSample/RPSSample/RPSAppDelegate.h index 9dd9c9a586..d2ed8cebf2 100644 --- a/samples/RPSSample/RPSSample/RPSAppDelegate.h +++ b/samples/RPSSample/RPSSample/RPSAppDelegate.h @@ -28,8 +28,8 @@ @interface RPSAppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; -//@property (strong, nonatomic) UITabBarController *tabBarController; -@property (strong, nonatomic) UINavigationController *navigationController; +@property (nonatomic, strong) UIWindow *window; +// @property (strong, nonatomic) UITabBarController *tabBarController; +@property (nonatomic, strong) UINavigationController *navigationController; @end diff --git a/samples/RPSSample/RPSSample/RPSAppDelegate.m b/samples/RPSSample/RPSSample/RPSAppDelegate.m index 88a193a93f..8499639168 100644 --- a/samples/RPSSample/RPSSample/RPSAppDelegate.m +++ b/samples/RPSSample/RPSSample/RPSAppDelegate.m @@ -32,41 +32,42 @@ @implementation RPSAppDelegate #pragma mark - Class methods -+ (RPSCall)callFromAppLinkURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { - FBSDKURL *appLinkURL = [FBSDKURL URLWithInboundURL:url sourceApplication:sourceApplication]; - NSURL *appLinkTargetURL = [appLinkURL targetURL]; - if (!appLinkTargetURL) { - return RPSCallNone; - } - NSString *queryString = [appLinkTargetURL query]; - for(NSString *component in [queryString componentsSeparatedByString:@"&"]) { - NSArray *pair = [component componentsSeparatedByString:@"="]; - NSString *param = pair[0]; - NSString *val = pair[1]; - if ([param isEqualToString:@"gesture"]) { - if ([val isEqualToString:@"rock"]) { - return RPSCallRock; - } else if ([val isEqualToString:@"paper"]) { - return RPSCallPaper; - } else if ([val isEqualToString:@"scissors"]) { - return RPSCallScissors; - } - } ++ (RPSCall)callFromAppLinkURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication +{ + FBSDKURL *appLinkURL = [FBSDKURL URLWithInboundURL:url sourceApplication:sourceApplication]; + NSURL *appLinkTargetURL = [appLinkURL targetURL]; + if (!appLinkTargetURL) { + return RPSCallNone; + } + NSString *queryString = [appLinkTargetURL query]; + for (NSString *component in [queryString componentsSeparatedByString:@"&"]) { + NSArray *pair = [component componentsSeparatedByString:@"="]; + NSString *param = pair[0]; + NSString *val = pair[1]; + if ([param isEqualToString:@"gesture"]) { + if ([val isEqualToString:@"rock"]) { + return RPSCallRock; + } else if ([val isEqualToString:@"paper"]) { + return RPSCallPaper; + } else if ([val isEqualToString:@"scissors"]) { + return RPSCallScissors; + } } + } - return RPSCallNone; + return RPSCallNone; } #pragma mark - UIApplicationDelegate - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url - options:(nonnull NSDictionary *)options + options:(nonnull NSDictionary *)options { - return [self application:application - openURL:url - sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] - annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; + return [self application:application + openURL:url + sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] + annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; } // Still need this for iOS8 @@ -75,40 +76,41 @@ - (BOOL)application:(UIApplication *)application sourceApplication:(nullable NSString *)sourceApplication annotation:(nonnull id)annotation { - FBSDKURL *appLink = [FBSDKURL URLWithInboundURL:url sourceApplication:sourceApplication]; - if (appLink.isAutoAppLink) { - [[[UIAlertView alloc] initWithTitle:@"Received Auto App Link:" - message:[NSString stringWithFormat:@"product id: %@", appLink.appLinkData[@"product_id"]] - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil] show]; - } - - BOOL result = [[FBSDKApplicationDelegate sharedInstance] application:application - openURL:url - sourceApplication:sourceApplication - annotation:annotation]; - return result; + FBSDKURL *appLink = [FBSDKURL URLWithInboundURL:url sourceApplication:sourceApplication]; + if (appLink.isAutoAppLink) { + [[[UIAlertView alloc] initWithTitle:@"Received Auto App Link:" + message:[NSString stringWithFormat:@"product id: %@", appLink.appLinkData[@"product_id"]] + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles:nil] show]; + } + + BOOL result = [[FBSDKApplicationDelegate sharedInstance] application:application + openURL:url + sourceApplication:sourceApplication + annotation:annotation]; + return result; } -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - // Override point for customization after application launch. +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + // Override point for customization after application launch. - RPSRootViewController *rootViewController = [[RPSRootViewController alloc] init]; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; + RPSRootViewController *rootViewController = [[RPSRootViewController alloc] init]; + self.window.rootViewController = rootViewController; + [self.window makeKeyAndVisible]; - [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *url, NSError *error) { - if (error) { - NSLog(@"Received error while fetching deferred app link %@", error); - } - if (url) { - [[UIApplication sharedApplication] openURL:url]; - } - }]; + [FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *url, NSError *error) { + if (error) { + NSLog(@"Received error while fetching deferred app link %@", error); + } + if (url) { + [[UIApplication sharedApplication] openURL:url]; + } + }]; - return YES; + return YES; } @end diff --git a/samples/RPSSample/RPSSample/RPSAppLinkedViewController.m b/samples/RPSSample/RPSSample/RPSAppLinkedViewController.m index 0afd2409b4..44060efafc 100644 --- a/samples/RPSSample/RPSSample/RPSAppLinkedViewController.m +++ b/samples/RPSSample/RPSSample/RPSAppLinkedViewController.m @@ -21,60 +21,63 @@ #import "RPSCommonObjects.h" @interface RPSAppLinkedViewController () -@property (nonatomic, assign) RPSCall call; +@property (nonatomic, assign) RPSCall call; @property (nonatomic, weak) IBOutlet UIImageView *callImageView; -@property (nonatomic, weak) IBOutlet UIButton *playButton; +@property (nonatomic, weak) IBOutlet UIButton *playButton; @end @implementation RPSAppLinkedViewController #pragma mark - Lifecycle -- (instancetype)initWithCall:(RPSCall)call { - NSParameterAssert(call != RPSCallNone); +- (instancetype)initWithCall:(RPSCall)call +{ + NSParameterAssert(call != RPSCallNone); - self = [super init]; + self = [super init]; - if (self) { - self.call = call; - self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - } + if (self) { + self.call = call; + self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + } - return self; + return self; } #pragma mark - Methods -- (IBAction)play:(id)sender { - [self dismissViewControllerAnimated:YES completion:nil]; +- (IBAction)play:(id)sender +{ + [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - UIViewController -- (void)viewDidLoad { - [super viewDidLoad]; - - self.playButton.layer.cornerRadius = 8.0; - self.playButton.layer.borderWidth = 4.0; - self.playButton.layer.borderColor = self.playButton.titleLabel.textColor.CGColor; - - UIImage *callImage = nil; - switch (self.call) { - case RPSCallPaper: - callImage = [UIImage imageNamed:@"right-paper-128.png"]; - break; - case RPSCallRock: - callImage = [UIImage imageNamed:@"right-rock-128.png"]; - break; - case RPSCallScissors: - callImage = [UIImage imageNamed:@"right-scissors-128.png"]; - break; - - default: - break; - } - - [self.callImageView setImage:callImage]; +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.playButton.layer.cornerRadius = 8.0; + self.playButton.layer.borderWidth = 4.0; + self.playButton.layer.borderColor = self.playButton.titleLabel.textColor.CGColor; + + UIImage *callImage = nil; + switch (self.call) { + case RPSCallPaper: + callImage = [UIImage imageNamed:@"right-paper-128.png"]; + break; + case RPSCallRock: + callImage = [UIImage imageNamed:@"right-rock-128.png"]; + break; + case RPSCallScissors: + callImage = [UIImage imageNamed:@"right-scissors-128.png"]; + break; + + default: + break; + } + + [self.callImageView setImage:callImage]; } @end diff --git a/samples/RPSSample/RPSSample/RPSAutoAppLinkBasicViewController.m b/samples/RPSSample/RPSSample/RPSAutoAppLinkBasicViewController.m index bc8f470454..eabc9e84c2 100644 --- a/samples/RPSSample/RPSSample/RPSAutoAppLinkBasicViewController.m +++ b/samples/RPSSample/RPSSample/RPSAutoAppLinkBasicViewController.m @@ -20,9 +20,9 @@ static const int paddingLen = 10; -@interface RPSAutoAppLinkBasicViewController() +@interface RPSAutoAppLinkBasicViewController () -@property (strong, nonatomic) Coffee* product; +@property (nonatomic, strong) Coffee *product; @property (nonatomic, copy) NSDictionary *data; @end @@ -31,49 +31,49 @@ @implementation RPSAutoAppLinkBasicViewController - (void)viewDidLoad { - [super viewDidLoad]; + [super viewDidLoad]; - self.view.backgroundColor = [UIColor whiteColor]; - UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; - int stdWidth = scrollView.frame.size.width - paddingLen*2; + self.view.backgroundColor = [UIColor whiteColor]; + UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; + int stdWidth = scrollView.frame.size.width - paddingLen * 2; - UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 50, stdWidth, 30)]; - nameLabel.font = [UIFont boldSystemFontOfSize:24]; - nameLabel.textColor = [UIColor grayColor]; + UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 50, stdWidth, 30)]; + nameLabel.font = [UIFont boldSystemFontOfSize:24]; + nameLabel.textColor = [UIColor grayColor]; - UILabel *descLabel = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 90, stdWidth, 20)]; - descLabel.font = [UIFont systemFontOfSize:14]; - descLabel.textColor = [UIColor lightGrayColor]; + UILabel *descLabel = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 90, stdWidth, 20)]; + descLabel.font = [UIFont systemFontOfSize:14]; + descLabel.textColor = [UIColor lightGrayColor]; - UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 130, stdWidth, 20)]; - priceLabel.font = [UIFont systemFontOfSize:20]; - priceLabel.textColor = [UIColor blackColor]; + UILabel *priceLabel = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 130, stdWidth, 20)]; + priceLabel.font = [UIFont systemFontOfSize:20]; + priceLabel.textColor = [UIColor blackColor]; - if (self.product == nil) { - self.product = [[Coffee alloc] initWithName:@"Coffee" desc:@"I am just a coffee" price:1]; - } - nameLabel.text = self.product.name; - descLabel.text = [@"Description: " stringByAppendingString:self.product.desc]; - priceLabel.text = [@"Price: $" stringByAppendingString:[@(self.product.price) stringValue]]; + if (self.product == nil) { + self.product = [[Coffee alloc] initWithName:@"Coffee" desc:@"I am just a coffee" price:1]; + } + nameLabel.text = self.product.name; + descLabel.text = [@"Description: " stringByAppendingString:self.product.desc]; + priceLabel.text = [@"Price: $" stringByAppendingString:[@(self.product.price) stringValue]]; - [scrollView addSubview: nameLabel]; - [scrollView addSubview: descLabel]; - [scrollView addSubview: priceLabel]; + [scrollView addSubview:nameLabel]; + [scrollView addSubview:descLabel]; + [scrollView addSubview:priceLabel]; - if (self.data != nil) { - UILabel *dataLabel = [[UILabel alloc] init]; - dataLabel.font = [UIFont systemFontOfSize:20]; - dataLabel.textColor = [UIColor blueColor]; - dataLabel.text = [NSString stringWithFormat:@"data is: %@", self.data]; - dataLabel.numberOfLines = 0; - CGSize size = [dataLabel.text boundingRectWithSize:CGSizeMake(stdWidth, 1000) - options:NSStringDrawingUsesLineFragmentOrigin - attributes:@{NSFontAttributeName:dataLabel.font} - context:nil].size; - dataLabel.frame = CGRectMake(paddingLen, 180, size.width, size.height); - [scrollView addSubview:dataLabel]; - } - [self.view addSubview: scrollView]; + if (self.data != nil) { + UILabel *dataLabel = [[UILabel alloc] init]; + dataLabel.font = [UIFont systemFontOfSize:20]; + dataLabel.textColor = [UIColor blueColor]; + dataLabel.text = [NSString stringWithFormat:@"data is: %@", self.data]; + dataLabel.numberOfLines = 0; + CGSize size = [dataLabel.text boundingRectWithSize:CGSizeMake(stdWidth, 1000) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{NSFontAttributeName : dataLabel.font} + context:nil].size; + dataLabel.frame = CGRectMake(paddingLen, 180, size.width, size.height); + [scrollView addSubview:dataLabel]; + } + [self.view addSubview:scrollView]; } @end diff --git a/samples/RPSSample/RPSSample/RPSAutoAppLinkDebugTool.m b/samples/RPSSample/RPSSample/RPSAutoAppLinkDebugTool.m index 8bc4aaf285..ae22911949 100644 --- a/samples/RPSSample/RPSSample/RPSAutoAppLinkDebugTool.m +++ b/samples/RPSSample/RPSSample/RPSAutoAppLinkDebugTool.m @@ -29,94 +29,90 @@ @implementation RPSAutoAppLinkDebugTool - (void)viewDidLoad { - [super viewDidLoad]; - - self.view.backgroundColor = [UIColor whiteColor]; - UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame]; - int frameWidth = scrollView.frame.size.width - paddingLen*2; - - UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 50, frameWidth, frameHeight)]; - labelName.font = [UIFont boldSystemFontOfSize:24]; - labelName.textColor = [UIColor grayColor]; - labelName.text = @"Auto Applink Debug Tool"; - - UILabel *labelDesc = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 100, frameWidth, frameHeight + 10)]; - labelDesc.font = [UIFont systemFontOfSize:14]; - labelDesc.textColor = [UIColor lightGrayColor]; - labelDesc.text = @"Enter your FB App ID and product ID to get your auto applink"; - labelDesc.numberOfLines = 0; - - self.appIDView = [self textFieldWithText: @"FB App ID (ex. 111222333)" keyBoardType:UIKeyboardTypeNumberPad]; - self.appIDView.frame = CGRectMake(paddingLen, 150, frameWidth, frameHeight); - - self.productIDView = [self textFieldWithText: @"Product ID (ex. 123)" keyBoardType:UIKeyboardTypeDefault]; - self.productIDView.frame = CGRectMake(paddingLen, 200, frameWidth, frameHeight); - - UIButton *sendButton = [[UIButton alloc] initWithFrame:CGRectMake(paddingLen, 250, frameWidth, frameHeight + 10)]; - [sendButton setBackgroundColor:[[UIColor blueColor] colorWithAlphaComponent:0.4]]; - [sendButton setTitle:@"Send" forState:UIControlStateNormal]; - [sendButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; - [sendButton addTarget:self action:@selector(sendAutoAppLink:) forControlEvents:UIControlEventTouchUpInside]; - - [scrollView addSubview:labelName]; - [scrollView addSubview:labelDesc]; - [scrollView addSubview:self.appIDView]; - [scrollView addSubview:self.productIDView]; - [scrollView addSubview:sendButton]; - [self.view addSubview:scrollView]; + [super viewDidLoad]; + + self.view.backgroundColor = [UIColor whiteColor]; + UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame]; + int frameWidth = scrollView.frame.size.width - paddingLen * 2; + + UILabel *labelName = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 50, frameWidth, frameHeight)]; + labelName.font = [UIFont boldSystemFontOfSize:24]; + labelName.textColor = [UIColor grayColor]; + labelName.text = @"Auto Applink Debug Tool"; + + UILabel *labelDesc = [[UILabel alloc] initWithFrame:CGRectMake(paddingLen, 100, frameWidth, frameHeight + 10)]; + labelDesc.font = [UIFont systemFontOfSize:14]; + labelDesc.textColor = [UIColor lightGrayColor]; + labelDesc.text = @"Enter your FB App ID and product ID to get your auto applink"; + labelDesc.numberOfLines = 0; + + self.appIDView = [self textFieldWithText:@"FB App ID (ex. 111222333)" keyBoardType:UIKeyboardTypeNumberPad]; + self.appIDView.frame = CGRectMake(paddingLen, 150, frameWidth, frameHeight); + + self.productIDView = [self textFieldWithText:@"Product ID (ex. 123)" keyBoardType:UIKeyboardTypeDefault]; + self.productIDView.frame = CGRectMake(paddingLen, 200, frameWidth, frameHeight); + + UIButton *sendButton = [[UIButton alloc] initWithFrame:CGRectMake(paddingLen, 250, frameWidth, frameHeight + 10)]; + [sendButton setBackgroundColor:[[UIColor blueColor] colorWithAlphaComponent:0.4]]; + [sendButton setTitle:@"Send" forState:UIControlStateNormal]; + [sendButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; + [sendButton addTarget:self action:@selector(sendAutoAppLink:) forControlEvents:UIControlEventTouchUpInside]; + + [scrollView addSubview:labelName]; + [scrollView addSubview:labelDesc]; + [scrollView addSubview:self.appIDView]; + [scrollView addSubview:self.productIDView]; + [scrollView addSubview:sendButton]; + [self.view addSubview:scrollView]; } - (UITextField *)textFieldWithText:(NSString *)text keyBoardType:(UIKeyboardType)type { - UITextField *textField; - textField = [[UITextField alloc] init]; - textField.layer.borderColor = [UIColor lightGrayColor].CGColor; - textField.layer.borderWidth = 1; - [textField setKeyboardType:type]; - textField.placeholder = text; - UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)]; - textField.leftView = paddingView; - textField.leftViewMode = UITextFieldViewModeAlways; - return textField; + UITextField *textField; + textField = [[UITextField alloc] init]; + textField.layer.borderColor = [UIColor lightGrayColor].CGColor; + textField.layer.borderWidth = 1; + [textField setKeyboardType:type]; + textField.placeholder = text; + UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)]; + textField.leftView = paddingView; + textField.leftViewMode = UITextFieldViewModeAlways; + return textField; } - (void)sendAutoAppLink:(UIButton *)button { - NSString *autoAppLink = [NSString stringWithFormat:@"fb%@://applinks?al_applink_data=", self.appIDView.text]; - NSDictionary *data = @{@"product_id" : self.productIDView.text, - @"is_auto_applink" : @"true" - }; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; - if (self.appIDView.text.length>0 && self.productIDView.text.length>0 && jsonData) { - NSString *encodeData = [FBSDKUtility URLEncode:[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; - NSString *encodeURL = [autoAppLink stringByAppendingString:encodeData]; - NSURL *url = [NSURL URLWithString:encodeURL]; - if (![[UIApplication sharedApplication] openURL:url]) { - [self showAlert: @"Cannot open the URL!"]; - } + NSString *autoAppLink = [NSString stringWithFormat:@"fb%@://applinks?al_applink_data=", self.appIDView.text]; + NSDictionary *data = @{@"product_id" : self.productIDView.text, + @"is_auto_applink" : @"true"}; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:nil]; + if (self.appIDView.text.length > 0 && self.productIDView.text.length > 0 && jsonData) { + NSString *encodeData = [FBSDKUtility URLEncode:[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]]; + NSString *encodeURL = [autoAppLink stringByAppendingString:encodeData]; + NSURL *url = [NSURL URLWithString:encodeURL]; + if (![[UIApplication sharedApplication] openURL:url]) { + [self showAlert:@"Cannot open the URL!"]; } - else { - if (self.appIDView.text.length == 0) { - [self showAlert: @"Invalid App ID!"]; - } - else if (self.productIDView.text.length == 0) { - [self showAlert: @"Invalid Product ID!"]; - } - else { - [self showAlert: @"Cannot generate url from input!"]; - } + } else { + if (self.appIDView.text.length == 0) { + [self showAlert:@"Invalid App ID!"]; + } else if (self.productIDView.text.length == 0) { + [self showAlert:@"Invalid Product ID!"]; + } else { + [self showAlert:@"Cannot generate url from input!"]; } + } } -- (void)showAlert:(NSString *) message +- (void)showAlert:(NSString *)message { - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" - message:message - delegate:self - cancelButtonTitle:@"Close" - otherButtonTitles:nil]; - [alertView show]; + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" + message:message + delegate:self + cancelButtonTitle:@"Close" + otherButtonTitles:nil]; + [alertView show]; } @end diff --git a/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.h b/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.h index e89e326d08..94aee14018 100644 --- a/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.h +++ b/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.h @@ -16,7 +16,6 @@ // 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 "RPSCoffee.h" diff --git a/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.m b/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.m index 564183aee6..81c791d74d 100644 --- a/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.m +++ b/samples/RPSSample/RPSSample/RPSAutoAppLinkStoryboardViewController.m @@ -18,15 +18,15 @@ #import "RPSAutoAppLinkStoryboardViewController.h" -@interface RPSAutoAppLinkStoryboardViewController() +@interface RPSAutoAppLinkStoryboardViewController () -@property (strong, nonatomic) Coffee* product; +@property (nonatomic, strong) Coffee *product; @property (nonatomic, copy) NSDictionary *data; -@property (weak, nonatomic) IBOutlet UILabel* nameLabel; -@property (weak, nonatomic) IBOutlet UILabel* descLabel; -@property (weak, nonatomic) IBOutlet UILabel* priceLabel; -@property (weak, nonatomic) IBOutlet UILabel* dataLabel; +@property (nonatomic, weak) IBOutlet UILabel *nameLabel; +@property (nonatomic, weak) IBOutlet UILabel *descLabel; +@property (nonatomic, weak) IBOutlet UILabel *priceLabel; +@property (nonatomic, weak) IBOutlet UILabel *dataLabel; @end @@ -34,19 +34,19 @@ @implementation RPSAutoAppLinkStoryboardViewController - (void)viewDidLoad { - [super viewDidLoad]; + [super viewDidLoad]; - if (self.product == nil) { - self.product = [[Coffee alloc] initWithName:@"Coffee" desc:@"I am just a STORYBOARD coffee" price:1]; - } + if (self.product == nil) { + self.product = [[Coffee alloc] initWithName:@"Coffee" desc:@"I am just a STORYBOARD coffee" price:1]; + } - self.nameLabel.text = self.product.name; - self.descLabel.text = [@"Description: " stringByAppendingString:self.product.desc]; - self.priceLabel.text = [@"Price: $" stringByAppendingString:[@(self.product.price) stringValue]]; + self.nameLabel.text = self.product.name; + self.descLabel.text = [@"Description: " stringByAppendingString:self.product.desc]; + self.priceLabel.text = [@"Price: $" stringByAppendingString:[@(self.product.price) stringValue]]; - if (self.data != nil) { - self.dataLabel.text = [NSString stringWithFormat:@"data is: %@", self.data]; - } + if (self.data != nil) { + self.dataLabel.text = [NSString stringWithFormat:@"data is: %@", self.data]; + } } @end diff --git a/samples/RPSSample/RPSSample/RPSCoffee.h b/samples/RPSSample/RPSSample/RPSCoffee.h index 9229854a8b..d368b80e33 100644 --- a/samples/RPSSample/RPSSample/RPSCoffee.h +++ b/samples/RPSSample/RPSSample/RPSCoffee.h @@ -24,6 +24,6 @@ @property (nonatomic, copy) NSString *desc; @property (nonatomic, assign) float price; -- (instancetype)initWithName:(NSString*)name desc:(NSString*)desc price:(float)price; +- (instancetype)initWithName:(NSString *)name desc:(NSString *)desc price:(float)price; @end diff --git a/samples/RPSSample/RPSSample/RPSCoffee.m b/samples/RPSSample/RPSSample/RPSCoffee.m index 88229f2421..faacf99a44 100644 --- a/samples/RPSSample/RPSSample/RPSCoffee.m +++ b/samples/RPSSample/RPSSample/RPSCoffee.m @@ -20,14 +20,14 @@ @implementation Coffee -- (instancetype)initWithName:(NSString*)name desc:(NSString*)desc price:(float)price +- (instancetype)initWithName:(NSString *)name desc:(NSString *)desc price:(float)price { - if ((self = [super init])) { - _name = [name copy]; - _desc = [desc copy]; - _price = price; - } - return self; + if ((self = [super init])) { + _name = [name copy]; + _desc = [desc copy]; + _price = price; + } + return self; } @end diff --git a/samples/RPSSample/RPSSample/RPSCommonObjects.h b/samples/RPSSample/RPSSample/RPSCommonObjects.h index afa6410d45..af8a911dfb 100644 --- a/samples/RPSSample/RPSSample/RPSCommonObjects.h +++ b/samples/RPSSample/RPSSample/RPSCommonObjects.h @@ -17,11 +17,16 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef enum { - RPSCallNone = -1, RPSCallRock = 0, RPSCallPaper = 1, RPSCallScissors = 2 // enum is also used to index arrays + RPSCallNone = -1, + RPSCallRock = 0, + RPSCallPaper = 1, + RPSCallScissors = 2, // enum is also used to index arrays } RPSCall; typedef enum { - RPSResultWin = 0, RPSResultLoss = 1, RPSResultTie = 2 + RPSResultWin = 0, + RPSResultLoss = 1, + RPSResultTie = 2, } RPSResult; extern NSString *builtInOpenGraphObjects[3]; diff --git a/samples/RPSSample/RPSSample/RPSCommonObjects.m b/samples/RPSSample/RPSSample/RPSCommonObjects.m index 509173fa86..b4bd530219 100644 --- a/samples/RPSSample/RPSSample/RPSCommonObjects.m +++ b/samples/RPSSample/RPSSample/RPSCommonObjects.m @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. NSString *builtInOpenGraphObjects[3] = { - @"672839339475385", // rock - @"296430467206197", // paper - @"524651207660361"}; // scissors + @"672839339475385", // rock + @"296430467206197", // paper + @"524651207660361" +}; // scissors diff --git a/samples/RPSSample/RPSSample/RPSFriendsViewController.h b/samples/RPSSample/RPSSample/RPSFriendsViewController.h index e325126e89..d192b4f330 100644 --- a/samples/RPSSample/RPSSample/RPSFriendsViewController.h +++ b/samples/RPSSample/RPSSample/RPSFriendsViewController.h @@ -20,11 +20,11 @@ @interface RPSFriendsViewController : UIViewController -@property (weak, nonatomic) IBOutlet UITextView *activityTextView; +@property (nonatomic, weak) IBOutlet UITextView *activityTextView; -@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property (nonatomic, weak) IBOutlet UITableView *tableView; -@property (weak, nonatomic) IBOutlet UIButton *challengeButton; +@property (nonatomic, weak) IBOutlet UIButton *challengeButton; - (IBAction)tapChallengeFriends:(id)sender; diff --git a/samples/RPSSample/RPSSample/RPSFriendsViewController.m b/samples/RPSSample/RPSSample/RPSFriendsViewController.m index e07a403b89..0672e4bf1f 100644 --- a/samples/RPSSample/RPSSample/RPSFriendsViewController.m +++ b/samples/RPSSample/RPSSample/RPSFriendsViewController.m @@ -21,277 +21,282 @@ #import #import - #import - #import @interface RPSFriendsViewController () @end - -@implementation RPSFriendsViewController { - NSMutableArray *_tableData; - BOOL _isPerformingLogin; +@implementation RPSFriendsViewController +{ + NSMutableArray *_tableData; + BOOL _isPerformingLogin; } -- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - _isPerformingLogin = NO; - self.title = NSLocalizedString(@"Rock w/Friends", @"Rock w/Friends"); - } +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + _isPerformingLogin = NO; + self.title = NSLocalizedString(@"Rock w/Friends", @"Rock w/Friends"); + } - return self; + return self; } #pragma mark - View lifecycle -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - if (!_isPerformingLogin) { - // Login with read permssions - FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken]; - if (![accessToken.permissions containsObject:@"user_friends"]) { - FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; - _isPerformingLogin = YES; - [loginManager logInWithPermissions:@[@"user_friends"] - fromViewController:self - handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { - _isPerformingLogin = NO; - if (error) { - NSLog(@"Failed to login:%@", error); - return; - } - - FBSDKAccessToken *newToken = [FBSDKAccessToken currentAccessToken]; - if (![newToken.permissions containsObject:@"user_friends"]) { - // Show alert - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Login Failed" - message:@"You must login and grant access to your friends list to use this feature" - delegate:self - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alertView show]; - [self.navigationController popToRootViewControllerAnimated:YES]; - return; - } - [self updateFriendsTable]; - }]; - } else { - [self updateFriendsTable]; - } +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + if (!_isPerformingLogin) { + // Login with read permssions + FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken]; + if (![accessToken.permissions containsObject:@"user_friends"]) { + FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; + _isPerformingLogin = YES; + [loginManager logInWithPermissions:@[@"user_friends"] + fromViewController:self + handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + _isPerformingLogin = NO; + if (error) { + NSLog(@"Failed to login:%@", error); + return; + } + + FBSDKAccessToken *newToken = [FBSDKAccessToken currentAccessToken]; + if (![newToken.permissions containsObject:@"user_friends"]) { + // Show alert + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Login Failed" + message:@"You must login and grant access to your friends list to use this feature" + delegate:self + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alertView show]; + [self.navigationController popToRootViewControllerAnimated:YES]; + return; + } + [self updateFriendsTable]; + }]; + } else { + [self updateFriendsTable]; } + } } #pragma makr - InvitFriends Button -- (IBAction)tapChallengeFriends:(id)sender { - FBSDKGameRequestDialog *gameRequestDialog = [[FBSDKGameRequestDialog alloc] init]; - FBSDKGameRequestContent *content = [[FBSDKGameRequestContent alloc] init]; - content.title = @"Challenge a Friend"; - content.message = @"Please come play RPS with me!"; - gameRequestDialog.content = content; - [gameRequestDialog show]; +- (IBAction)tapChallengeFriends:(id)sender +{ + FBSDKGameRequestDialog *gameRequestDialog = [[FBSDKGameRequestDialog alloc] init]; + FBSDKGameRequestContent *content = [[FBSDKGameRequestContent alloc] init]; + content.title = @"Challenge a Friend"; + content.message = @"Please come play RPS with me!"; + gameRequestDialog.content = content; + [gameRequestDialog show]; } #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [_tableData count]; + return [_tableData count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *const simpleTableIdentifier = @"SimpleTableItem"; + static NSString *const simpleTableIdentifier = @"SimpleTableItem"; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; - if (cell == nil) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]; - } + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]; + } - // Don't have the cell highlighted since we use the checkmark instead - cell.selectionStyle = UITableViewCellSelectionStyleNone; + // Don't have the cell highlighted since we use the checkmark instead + cell.selectionStyle = UITableViewCellSelectionStyleNone; - NSDictionary *data = [_tableData objectAtIndex:indexPath.row]; - cell.textLabel.text = data[@"name"]; - return cell; + NSDictionary *data = [_tableData objectAtIndex:indexPath.row]; + cell.textLabel.text = data[@"name"]; + return cell; } -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; - cell.accessoryType = UITableViewCellAccessoryCheckmark; +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + cell.accessoryType = UITableViewCellAccessoryCheckmark; - self.activityTextView.text = @"Loading..."; - NSDictionary *user = [_tableData objectAtIndex:[indexPath row]]; - [self updateActivityForID:user[@"id"]]; + self.activityTextView.text = @"Loading..."; + NSDictionary *user = [_tableData objectAtIndex:[indexPath row]]; + [self updateActivityForID:user[@"id"]]; } --(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath +- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; + [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; } #pragma mark - private methods -- (void)updateFriendsTable { - // We limit the friends list to only 50 results for this sample. In production you should - // use paging to dynamically grab more users. - NSDictionary *parameters = @{ - @"fields": @"name", - @"limit" : @"50" - }; - // This will only return the list of friends who have this app installed - FBSDKGraphRequest *friendsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/friends" - parameters:parameters]; - FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; - [connection addRequest:friendsRequest - completionHandler:^(FBSDKGraphRequestConnection *innerConnection, NSDictionary *result, NSError *error) { - if (error) { - NSLog(@"%@", error); - return; - } - - if (result) { - NSArray *data = result[@"data"]; - _tableData = [data copy]; - [_tableView reloadData]; - } - }]; - // start the actual request - [connection start]; +- (void)updateFriendsTable +{ + // We limit the friends list to only 50 results for this sample. In production you should + // use paging to dynamically grab more users. + NSDictionary *parameters = @{ + @"fields" : @"name", + @"limit" : @"50" + }; + // This will only return the list of friends who have this app installed + FBSDKGraphRequest *friendsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/friends" + parameters:parameters]; + FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; + [connection addRequest:friendsRequest + completionHandler:^(FBSDKGraphRequestConnection *innerConnection, NSDictionary *result, NSError *error) { + if (error) { + NSLog(@"%@", error); + return; + } + + if (result) { + NSArray *data = result[@"data"]; + _tableData = [data copy]; + [_tableView reloadData]; + } + }]; + // start the actual request + [connection start]; } // This is the workhorse method of this view. It updates the textView with the activity of a given user. It // accomplishes this by fetching the "throw" actions for the selected user. -- (void)getActivityForID:(NSString *)fbid callback:(void (^)(NSMutableArray *))callback{ - NSInteger __block pendingRequestCount = 0; - NSMutableArray *selectedUserActiviy = [NSMutableArray array]; - FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; - - // Get the results for plays posted to Facebook explicitly. - FBSDKGraphRequest *playActivityRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/fb_sample_rps:throw", fbid] - parameters:@{ - @"fields" : @"data,publish_time", - @"limit" : @"10", - @"date_format" : @"U" - }]; - ++pendingRequestCount; - [connection addRequest:playActivityRequest - completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id playActivity, NSError *error) { - if (error) { - NSLog(@"Failed get fb_sample_rps:throw activities for user '%@': %@",fbid, error); - } else if (playActivity) { - for (id entry in playActivity[@"data"]) { - NSString *gesture = entry[@"data"][@"gesture"][@"title"]; - NSString *opposing_gesture = entry[@"data"][@"opposing_gesture"][@"title"]; - [selectedUserActiviy addObject:@{ - @"publish_date" : [self getDateFromEpochTime:entry[@"publish_time"]], - @"player_gesture" : gesture, - @"opponent_gesture" : opposing_gesture - }]; - } - } - if (--pendingRequestCount == 0) { - callback(selectedUserActiviy); - } +- (void)getActivityForID:(NSString *)fbid callback:(void (^)(NSMutableArray *))callback +{ + NSInteger __block pendingRequestCount = 0; + NSMutableArray *selectedUserActiviy = [NSMutableArray array]; + FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; + + // Get the results for plays posted to Facebook explicitly. + FBSDKGraphRequest *playActivityRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/fb_sample_rps:throw", fbid] + parameters:@{ + @"fields" : @"data,publish_time", + @"limit" : @"10", + @"date_format" : @"U" + }]; + ++pendingRequestCount; + [connection addRequest:playActivityRequest + completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id playActivity, NSError *error) { + if (error) { + NSLog(@"Failed get fb_sample_rps:throw activities for user '%@': %@", fbid, error); + } else if (playActivity) { + for (id entry in playActivity[@"data"]) { + NSString *gesture = entry[@"data"][@"gesture"][@"title"]; + NSString *opposing_gesture = entry[@"data"][@"opposing_gesture"][@"title"]; + [selectedUserActiviy addObject:@{ + @"publish_date" : [self getDateFromEpochTime:entry[@"publish_time"]], + @"player_gesture" : gesture, + @"opponent_gesture" : opposing_gesture + }]; + } + } + if (--pendingRequestCount == 0) { + callback(selectedUserActiviy); + } + }]; + + FBSDKGraphRequest *gameActivityRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/fb_sample_rps:play", fbid] + parameters:@{ + @"fields" : @"data,publish_time", + @"limit" : @"10", + @"date_format" : @"U", + }]; + ++pendingRequestCount; + [connection addRequest:gameActivityRequest + batchEntryName:@"games-post" + completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { + if (error) { + NSLog(@"Failed to get game activity %@:", error); + } + if (--pendingRequestCount == 0) { + callback(selectedUserActiviy); + } + } + ]; + // A batch request that id dependent on the previous result + FBSDKGraphRequest *gameData = [[FBSDKGraphRequest alloc] initWithGraphPath:@"?ids={result=games-post:$.data.*.data.game.id}" + parameters:@{ + @"fields" : @"data,created_time", + @"date_format" : @"U", + }]; + ++pendingRequestCount; + [connection addRequest:gameData completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id games, NSError *innerError) { + if (innerError) { + // ignore code 2500 errors since that indicates the parent games-post error was empty. + if ([innerError.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] integerValue] != 2500) { + NSLog(@"Failed to get detailed game data for 'play' objects: %@", innerError); + } + } else if (games) { + for (id gameKey in games) { + NSDictionary *game = games[gameKey]; + NSString *player_gesture = game[@"data"][@"player_gesture"][@"title"]; + NSString *opponent_gesture = game[@"data"][@"opponent_gesture"][@"title"]; + [selectedUserActiviy addObject:@{ + @"publish_date" : [self getDateFromEpochTime:game[@"created_time"]], + @"player_gesture" : player_gesture, + @"opponent_gesture" : opponent_gesture }]; + } + } + if (--pendingRequestCount == 0) { + callback(selectedUserActiviy); + } + }]; - FBSDKGraphRequest *gameActivityRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/fb_sample_rps:play", fbid] - parameters:@{ - @"fields" : @"data,publish_time", - @"limit" : @"10", - @"date_format" : @"U", - }]; - ++pendingRequestCount; - [connection addRequest:gameActivityRequest - batchEntryName:@"games-post" - completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { - if (error) { - NSLog(@"Failed to get game activity %@:", error); - } - if (--pendingRequestCount == 0) { - callback(selectedUserActiviy); - } - } - ]; - // A batch request that id dependent on the previous result - FBSDKGraphRequest *gameData = [[FBSDKGraphRequest alloc] initWithGraphPath:@"?ids={result=games-post:$.data.*.data.game.id}" - parameters:@{ - @"fields" : @"data,created_time", - @"date_format" : @"U", - }]; - ++pendingRequestCount; - [connection addRequest:gameData completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id games, NSError *innerError) { - if (innerError) { - // ignore code 2500 errors since that indicates the parent games-post error was empty. - if ([innerError.userInfo[FBSDKGraphRequestErrorGraphErrorCodeKey] integerValue] != 2500) { - NSLog(@"Failed to get detailed game data for 'play' objects: %@", innerError); - } - } else if (games) { - for (id gameKey in games) { - NSDictionary *game = games[gameKey]; - NSString *player_gesture = game[@"data"][@"player_gesture"][@"title"]; - NSString *opponent_gesture = game[@"data"][@"opponent_gesture"][@"title"]; - [selectedUserActiviy addObject:@{ - @"publish_date" : [self getDateFromEpochTime:game[@"created_time"]], - @"player_gesture" : player_gesture, - @"opponent_gesture" : opponent_gesture - }]; - } - } - if (--pendingRequestCount == 0) { - callback(selectedUserActiviy); - } - }]; - - - [connection start]; + [connection start]; } -- (NSDate*)getDateFromEpochTime:(NSString *)time { - NSInteger publishTime = [time integerValue]; - return [NSDate dateWithTimeIntervalSince1970:publishTime]; +- (NSDate *)getDateFromEpochTime:(NSString *)time +{ + NSInteger publishTime = [time integerValue]; + return [NSDate dateWithTimeIntervalSince1970:publishTime]; } -- (void)updateActivityForID:(NSString *)fbid { - if (!fbid) { - self.activityTextView.text = @"No User Selected"; - return; +- (void)updateActivityForID:(NSString *)fbid +{ + if (!fbid) { + self.activityTextView.text = @"No User Selected"; + return; + } + + // keep track of the selction + [self getActivityForID:fbid callback:^(NSMutableArray *activity) { + // sort the array by date + [activity sortUsingComparator:^NSComparisonResult (id obj1, + id obj2) { + NSDate *obj1Date = obj1[@"publish_date"]; + NSDate *obj2Date = obj2[@"publish_date"]; + if (obj1Date && obj2Date) { + return [obj2Date compare:obj1Date]; + } + return NSOrderedSame; + }]; + + NSMutableString *output = [NSMutableString string]; + for (id entry in activity) { + NSDateComponents *c = [[NSCalendar currentCalendar] + components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear + fromDate:entry[@"publish_date"]]; + NSString *gesture = entry[@"player_gesture"]; + NSString *opposing_gesture = entry[@"opponent_gesture"]; + [output appendFormat:@"%02li/%02li/%02li - %@ %@ %@\n", + (long)c.month, + (long)c.day, + (long)c.year, + gesture, + @"vs", + opposing_gesture]; } - - // keep track of the selction - [self getActivityForID:fbid callback:^(NSMutableArray *activity) { - // sort the array by date - [activity sortUsingComparator:^NSComparisonResult(id obj1, - id obj2) { - NSDate *obj1Date = obj1[@"publish_date"]; - NSDate *obj2Date = obj2[@"publish_date"]; - if (obj1Date && obj2Date) { - return [obj2Date compare:obj1Date]; - } - return NSOrderedSame; - }]; - - NSMutableString *output = [NSMutableString string]; - for (id entry in activity) { - NSDateComponents *c = [[NSCalendar currentCalendar] - components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear - fromDate:entry[@"publish_date"]]; - NSString *gesture = entry[@"player_gesture"]; - NSString *opposing_gesture = entry[@"opponent_gesture"]; - [output appendFormat:@"%02li/%02li/%02li - %@ %@ %@\n", - (long)c.month, - (long)c.day, - (long)c.year, - gesture, - @"vs", - opposing_gesture]; - } - self.activityTextView.text = output; - }]; + self.activityTextView.text = output; + }]; } @end diff --git a/samples/RPSSample/RPSSample/RPSGameViewController.h b/samples/RPSSample/RPSSample/RPSGameViewController.h index 3ce533172f..23f03048d3 100644 --- a/samples/RPSSample/RPSSample/RPSGameViewController.h +++ b/samples/RPSSample/RPSSample/RPSGameViewController.h @@ -20,24 +20,24 @@ @interface RPSGameViewController : UIViewController -@property (unsafe_unretained, nonatomic) IBOutlet UILabel *rockLabel; -@property (unsafe_unretained, nonatomic) IBOutlet UILabel *paperLabel; -@property (unsafe_unretained, nonatomic) IBOutlet UILabel *scissorsLabel; +@property (nonatomic, unsafe_unretained) IBOutlet UILabel *rockLabel; +@property (nonatomic, unsafe_unretained) IBOutlet UILabel *paperLabel; +@property (nonatomic, unsafe_unretained) IBOutlet UILabel *scissorsLabel; -@property (unsafe_unretained, nonatomic) IBOutlet UILabel *shootLabel; +@property (nonatomic, unsafe_unretained) IBOutlet UILabel *shootLabel; -@property (unsafe_unretained, nonatomic) IBOutlet UIImageView *playerHand; -@property (unsafe_unretained, nonatomic) IBOutlet UIImageView *computerHand; +@property (nonatomic, unsafe_unretained) IBOutlet UIImageView *playerHand; +@property (nonatomic, unsafe_unretained) IBOutlet UIImageView *computerHand; -@property (unsafe_unretained, nonatomic) IBOutlet UIButton *rockButton; -@property (unsafe_unretained, nonatomic) IBOutlet UIButton *paperButton; -@property (unsafe_unretained, nonatomic) IBOutlet UIButton *scissorsButton; +@property (nonatomic, unsafe_unretained) IBOutlet UIButton *rockButton; +@property (nonatomic, unsafe_unretained) IBOutlet UIButton *paperButton; +@property (nonatomic, unsafe_unretained) IBOutlet UIButton *scissorsButton; -@property (unsafe_unretained, nonatomic) IBOutlet UIButton *againButton; -@property (unsafe_unretained, nonatomic) IBOutlet UIButton *facebookButton; +@property (nonatomic, unsafe_unretained) IBOutlet UIButton *againButton; +@property (nonatomic, unsafe_unretained) IBOutlet UIButton *facebookButton; -@property (unsafe_unretained, nonatomic) IBOutlet UILabel *resultLabel; -@property (unsafe_unretained, nonatomic) IBOutlet UILabel *scoreLabel; +@property (nonatomic, unsafe_unretained) IBOutlet UILabel *resultLabel; +@property (nonatomic, unsafe_unretained) IBOutlet UILabel *scoreLabel; - (IBAction)clickRPSButton:(id)sender; - (IBAction)clickAgainButton:(id)sender; diff --git a/samples/RPSSample/RPSSample/RPSGameViewController.m b/samples/RPSSample/RPSSample/RPSGameViewController.m index c25e736d9d..758bfeb631 100644 --- a/samples/RPSSample/RPSSample/RPSGameViewController.m +++ b/samples/RPSSample/RPSSample/RPSGameViewController.m @@ -22,9 +22,7 @@ #import #import - #import - #import #import "RPSAppDelegate.h" @@ -32,24 +30,24 @@ #import "RPSFriendsViewController.h" static NSString *callType[] = { - @"unknown", - @"rock", - @"paper", - @"scissors" + @"unknown", + @"rock", + @"paper", + @"scissors" }; // Some constants for creating Open Graph objects. static NSString *kResults[] = { - @"won", - @"lost", - @"tied" + @"won", + @"lost", + @"tied" }; // We upload photos for games, but we'd like to reuse the same objects during a session. static NSString *photoURLs[] = { - nil, - nil, - nil + nil, + nil, + nil }; typedef void (^RPSBlock)(void); @@ -57,82 +55,80 @@ @interface RPSGameViewController () @end -@implementation RPSGameViewController { - BOOL _needsInitialAnimation; - BOOL _interestedInImplicitShare; - RPSCall _lastPlayerCall, _lastComputerCall; - UIImage *_rightImages[3]; - UIImage *_leftImages[3]; - UIImage *_imagesToPublish[3]; - RPSBlock _alertOkHandler; - int _wins, _losses, _ties; - NSDate *_lastAnimationStartTime; - NSMutableSet *_activeConnections; +@implementation RPSGameViewController +{ + BOOL _needsInitialAnimation; + BOOL _interestedInImplicitShare; + RPSCall _lastPlayerCall, _lastComputerCall; + UIImage *_rightImages[3]; + UIImage *_leftImages[3]; + UIImage *_imagesToPublish[3]; + RPSBlock _alertOkHandler; + int _wins, _losses, _ties; + NSDate *_lastAnimationStartTime; + NSMutableSet *_activeConnections; } -- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - self.title = NSLocalizedString(@"You Rock!", @"You Rock!"); - self.tabBarItem.image = [UIImage imageNamed:@"first"]; +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + self.title = NSLocalizedString(@"You Rock!", @"You Rock!"); + self.tabBarItem.image = [UIImage imageNamed:@"first"]; + + BOOL ipad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad); - BOOL ipad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad); + NSString *rockRight = ipad ? @"right-rock-128.png" : @"right-rock-88.png"; + NSString *paperRight = ipad ? @"right-paper-128.png" : @"right-paper-88.png"; + NSString *scissorsRight = ipad ? @"right-scissors-128.png" : @"right-scissors-88.png"; - NSString *rockRight = ipad ? @"right-rock-128.png" : @"right-rock-88.png"; - NSString *paperRight = ipad ? @"right-paper-128.png" : @"right-paper-88.png"; - NSString *scissorsRight = ipad ? @"right-scissors-128.png" : @"right-scissors-88.png"; + NSString *rockLeft = ipad ? @"left-rock-128.png" : @"left-rock-88.png"; + NSString *paperLeft = ipad ? @"left-paper-128.png" : @"left-paper-88.png"; + NSString *scissorsLeft = ipad ? @"left-scissors-128.png" : @"left-scissors-88.png"; - NSString *rockLeft = ipad ? @"left-rock-128.png" : @"left-rock-88.png"; - NSString *paperLeft = ipad ? @"left-paper-128.png" : @"left-paper-88.png"; - NSString *scissorsLeft = ipad ? @"left-scissors-128.png" : @"left-scissors-88.png"; + _rightImages[RPSCallRock] = [UIImage imageNamed:rockRight]; + _rightImages[RPSCallPaper] = [UIImage imageNamed:paperRight]; + _rightImages[RPSCallScissors] = [UIImage imageNamed:scissorsRight]; - _rightImages[RPSCallRock] = [UIImage imageNamed:rockRight]; - _rightImages[RPSCallPaper] = [UIImage imageNamed:paperRight]; - _rightImages[RPSCallScissors] = [UIImage imageNamed:scissorsRight]; + _leftImages[RPSCallRock] = [UIImage imageNamed:rockLeft]; + _leftImages[RPSCallPaper] = [UIImage imageNamed:paperLeft]; + _leftImages[RPSCallScissors] = [UIImage imageNamed:scissorsLeft]; - _leftImages[RPSCallRock] = [UIImage imageNamed:rockLeft]; - _leftImages[RPSCallPaper] = [UIImage imageNamed:paperLeft]; - _leftImages[RPSCallScissors] = [UIImage imageNamed:scissorsLeft]; + _imagesToPublish[RPSCallRock] = [UIImage imageNamed:@"left-rock-128.png"]; + _imagesToPublish[RPSCallPaper] = [UIImage imageNamed:@"left-paper-128.png"]; + _imagesToPublish[RPSCallScissors] = [UIImage imageNamed:@"left-scissors-128.png"]; - _imagesToPublish[RPSCallRock] = [UIImage imageNamed:@"left-rock-128.png"]; - _imagesToPublish[RPSCallPaper] = [UIImage imageNamed:@"left-paper-128.png"]; - _imagesToPublish[RPSCallScissors] = [UIImage imageNamed:@"left-scissors-128.png"]; + _lastPlayerCall = _lastComputerCall = RPSCallNone; + _wins = _losses = _ties = 0; + _alertOkHandler = nil; + _needsInitialAnimation = YES; + _interestedInImplicitShare = YES; - _lastPlayerCall = _lastComputerCall = RPSCallNone; - _wins = _losses = _ties = 0; - _alertOkHandler = nil; - _needsInitialAnimation = YES; - _interestedInImplicitShare = YES; + _activeConnections = [[NSMutableSet alloc] init]; + } + return self; +} - _activeConnections = [[NSMutableSet alloc] init]; +- (void)viewDidLoad +{ + [super viewDidLoad]; - } - return self; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Check for a 15 digit FB App ID. If the FB App ID is less than 15 digits, display an alert. - - NSString *strFbAppId = [FBSDKSettings appID]; - NSString *strEmptyFBId = @"{your-facebook-app-id}"; - - if ([strFbAppId isEqualToString:strEmptyFBId]){ - - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Missing the Facebook App ID" message:@"The RPSSample-info.plist is missing the Facebook App ID in the FacebookAppID key.\r\n\nPlease close the app, add your Facebook App ID to FacebookAppID key in RPSSample-info.plist, and then restart the app.\r\n\nFor more information, see ReadMe.txt." preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Dismiss" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { - [alert dismissViewControllerAnimated:YES completion:nil]; - }]; - - [alert addAction:cancel]; - - [self presentViewController:alert animated:YES completion:nil]; - } - - else { - + // Check for a 15 digit FB App ID. If the FB App ID is less than 15 digits, display an alert. + + NSString *strFbAppId = [FBSDKSettings appID]; + NSString *strEmptyFBId = @"{your-facebook-app-id}"; + + if ([strFbAppId isEqualToString:strEmptyFBId]) { + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Missing the Facebook App ID" message:@"The RPSSample-info.plist is missing the Facebook App ID in the FacebookAppID key.\r\n\nPlease close the app, add your Facebook App ID to FacebookAppID key in RPSSample-info.plist, and then restart the app.\r\n\nFor more information, see ReadMe.txt." preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Dismiss" style:UIAlertActionStyleCancel handler:^(UIAlertAction *_Nonnull action) { + [alert dismissViewControllerAnimated:YES completion:nil]; + }]; + + [alert addAction:cancel]; + + [self presentViewController:alert animated:YES completion:nil]; + } else { UIColor *fontColor = self.rockLabel.textColor; [self.rockButton.layer setCornerRadius:8.0]; [self.rockButton.layer setBorderWidth:4.0]; @@ -177,494 +173,534 @@ - (void)viewDidLoad { [self updateScoreLabel]; [self resetField]; - } -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - self.navigationController.navigationBarHidden = YES; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - if (_needsInitialAnimation) { - // get things rolling - _needsInitialAnimation = NO; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [self animateField]; - }); - } -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - self.navigationController.navigationBarHidden = NO; -} - -- (void)viewDidUnload { - [self setRockLabel:nil]; - [self setPaperLabel:nil]; - [self setScissorsLabel:nil]; - [self setRockButton:nil]; - [self setRockButton:nil]; - [self setPaperButton:nil]; - [self setScissorsButton:nil]; - [self setShootLabel:nil]; - [self setComputerHand:nil]; - [self setAgainButton:nil]; - [self setPlayerHand:nil]; - [super viewDidUnload]; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - // Return YES for supported orientations - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); - } else { - return YES; - } -} - -- (void)resetField { - self.rockButton.hidden = - self.paperButton.hidden = - self.scissorsButton.hidden = - self.rockLabel.hidden = - self.paperLabel.hidden = - self.scissorsLabel.hidden = - self.shootLabel.hidden = - self.computerHand.hidden = - self.playerHand.hidden = - self.againButton.hidden = YES; - - self.rockButton.enabled = - self.paperButton.enabled = - self.scissorsButton.enabled = NO; - - self.resultLabel.text = @""; -} - -- (void)setFieldForPlayAgain { - self.shootLabel.hidden = - self.rockButton.hidden = - self.paperButton.hidden = - self.scissorsButton.hidden = YES; - - self.playerHand.hidden = - self.againButton.hidden = NO; -} - -- (void)animateField { - // rock - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - self.rockLabel.hidden = NO; - self.rockButton.hidden = NO; - - // paper - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - self.paperLabel.hidden = NO; - self.paperButton.hidden = NO; - - // scissors - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - self.scissorsLabel.hidden = NO; - self.scissorsButton.hidden = NO; - - // shoot! - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - self.shootLabel.hidden = - self.computerHand.hidden = NO; - self.rockButton.enabled = - self.paperButton.enabled = - self.scissorsButton.enabled = YES; - - self.computerHand.animationImages = @[ _rightImages[RPSCallRock], _rightImages[RPSCallPaper], _rightImages[RPSCallScissors]]; - self.computerHand.animationDuration = .4; - self.computerHand.animationRepeatCount = 0; - [self.computerHand startAnimating]; - _lastAnimationStartTime = [NSDate date]; + } +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + self.navigationController.navigationBarHidden = YES; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + if (_needsInitialAnimation) { + // get things rolling + _needsInitialAnimation = NO; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5 * NSEC_PER_SEC), + dispatch_get_main_queue(), ^{ + [self animateField]; + }); + } +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + self.navigationController.navigationBarHidden = NO; +} + +- (void)viewDidUnload +{ + [self setRockLabel:nil]; + [self setPaperLabel:nil]; + [self setScissorsLabel:nil]; + [self setRockButton:nil]; + [self setRockButton:nil]; + [self setPaperButton:nil]; + [self setScissorsButton:nil]; + [self setShootLabel:nil]; + [self setComputerHand:nil]; + [self setAgainButton:nil]; + [self setPlayerHand:nil]; + [super viewDidUnload]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + // Return YES for supported orientations + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); + } else { + return YES; + } +} + +- (void)resetField +{ + self.rockButton.hidden = + self.paperButton.hidden = + self.scissorsButton.hidden = + self.rockLabel.hidden = + self.paperLabel.hidden = + self.scissorsLabel.hidden = + self.shootLabel.hidden = + self.computerHand.hidden = + self.playerHand.hidden = + self.againButton.hidden = YES; + + self.rockButton.enabled = + self.paperButton.enabled = + self.scissorsButton.enabled = NO; + + self.resultLabel.text = @""; +} + +- (void)setFieldForPlayAgain +{ + self.shootLabel.hidden = + self.rockButton.hidden = + self.paperButton.hidden = + self.scissorsButton.hidden = YES; + + self.playerHand.hidden = + self.againButton.hidden = NO; +} + +- (void)animateField +{ + // rock + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .5 * NSEC_PER_SEC), + dispatch_get_main_queue(), ^{ + self.rockLabel.hidden = NO; + self.rockButton.hidden = NO; + + // paper + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), + dispatch_get_main_queue(), ^{ + self.paperLabel.hidden = NO; + self.paperButton.hidden = NO; + + // scissors + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), + dispatch_get_main_queue(), ^{ + self.scissorsLabel.hidden = NO; + self.scissorsButton.hidden = NO; + + // shoot! + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), + dispatch_get_main_queue(), ^{ + self.shootLabel.hidden = + self.computerHand.hidden = NO; + self.rockButton.enabled = + self.paperButton.enabled = + self.scissorsButton.enabled = YES; + + self.computerHand.animationImages = @[_rightImages[RPSCallRock], _rightImages[RPSCallPaper], _rightImages[RPSCallScissors]]; + self.computerHand.animationDuration = .4; + self.computerHand.animationRepeatCount = 0; + [self.computerHand startAnimating]; + _lastAnimationStartTime = [NSDate date]; }); }); }); }); } -- (RPSCall)callViaRandom { - return (RPSCall)(arc4random() % 3); +- (RPSCall)callViaRandom +{ + return (RPSCall)(arc4random() % 3); } - (RPSResult)resultForPlayerCall:(RPSCall)playerCall - computerCall:(RPSCall)computerCall { - static RPSResult results[3][3] = { - {RPSResultTie, RPSResultLoss, RPSResultWin}, - {RPSResultWin, RPSResultTie, RPSResultLoss}, - {RPSResultLoss, RPSResultWin, RPSResultTie} - }; - return results[playerCall][computerCall]; -} - -- (void)callGame:(RPSCall)playerCall { - NSTimeInterval timeTaken = fabs([_lastAnimationStartTime timeIntervalSinceNow]); - [self logTimeTaken:timeTaken]; - [self logCurrentPlayerCall:playerCall lastPlayerCall:_lastPlayerCall lastComputerCall:_lastComputerCall]; - - // stop animating and identify each opponent's call - [self.computerHand stopAnimating]; - _lastPlayerCall = playerCall; - _lastComputerCall = [self callViaRandom]; - self.computerHand.image = _rightImages[_lastComputerCall]; - - // update UI and counts based on result - RPSResult result = [self resultForPlayerCall:_lastPlayerCall - computerCall:_lastComputerCall]; - - switch (result) { - case RPSResultWin: - _wins++; - self.resultLabel.text = @"Win!"; - [self logPlayerCall:playerCall result:RPSResultWin timeTaken:timeTaken]; - break; - case RPSResultLoss: - _losses++; - self.resultLabel.text = @"Loss."; - [self logPlayerCall:playerCall result:RPSResultLoss timeTaken:timeTaken]; - break; - case RPSResultTie: - _ties++; - self.resultLabel.text = @"Tie..."; - [self logPlayerCall:playerCall result:RPSResultTie timeTaken:timeTaken]; - break; + computerCall:(RPSCall)computerCall +{ + static RPSResult results[3][3] = { + {RPSResultTie, RPSResultLoss, RPSResultWin}, + {RPSResultWin, RPSResultTie, RPSResultLoss}, + {RPSResultLoss, RPSResultWin, RPSResultTie} + }; + return results[playerCall][computerCall]; +} + +- (void)callGame:(RPSCall)playerCall +{ + NSTimeInterval timeTaken = fabs([_lastAnimationStartTime timeIntervalSinceNow]); + [self logTimeTaken:timeTaken]; + [self logCurrentPlayerCall:playerCall lastPlayerCall:_lastPlayerCall lastComputerCall:_lastComputerCall]; + + // stop animating and identify each opponent's call + [self.computerHand stopAnimating]; + _lastPlayerCall = playerCall; + _lastComputerCall = [self callViaRandom]; + self.computerHand.image = _rightImages[_lastComputerCall]; + + // update UI and counts based on result + RPSResult result = [self resultForPlayerCall:_lastPlayerCall + computerCall:_lastComputerCall]; + + switch (result) { + case RPSResultWin: + _wins++; + self.resultLabel.text = @"Win!"; + [self logPlayerCall:playerCall result:RPSResultWin timeTaken:timeTaken]; + break; + case RPSResultLoss: + _losses++; + self.resultLabel.text = @"Loss."; + [self logPlayerCall:playerCall result:RPSResultLoss timeTaken:timeTaken]; + break; + case RPSResultTie: + _ties++; + self.resultLabel.text = @"Tie..."; + [self logPlayerCall:playerCall result:RPSResultTie timeTaken:timeTaken]; + break; + } + [self updateScoreLabel]; + + if (_interestedInImplicitShare) { + [self publishResult]; + } +} + +- (void)updateScoreLabel +{ + self.scoreLabel.text = [NSString stringWithFormat:@"W = %d L = %d T = %d", _wins, _losses, _ties]; +} + +- (IBAction)clickRPSButton:(id)sender +{ + UIButton *button = sender; + RPSCall choice = (RPSCall)button.tag; + self.playerHand.image = _leftImages[choice]; + [self callGame:choice]; + [self setFieldForPlayAgain]; +} + +- (IBAction)clickAgainButton:(id)sender +{ + [self resetField]; + [self animateField]; +} + +- (IBAction)clickFacebookButton:(id)sender +{ + UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil + delegate:self + cancelButtonTitle:@"Cancel" + destructiveButtonTitle:nil + otherButtonTitles:@"Share on Facebook", + @"Share on Messenger", + @"Friends' Activity", + [FBSDKAccessToken currentAccessToken] ? @"Log out" : @"Log in", + nil]; + // Show the sheet + [sheet showInView:sender]; +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex +{ + if (buttonIndex != 0) { // ok + if (_alertOkHandler) { + _alertOkHandler(); + _alertOkHandler = nil; } - [self updateScoreLabel]; - - if (_interestedInImplicitShare) { - [self publishResult]; + } +} + +- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + switch (buttonIndex) { + case 0: { // Share on Facebook + FBSDKShareDialog *shareDialog = [[FBSDKShareDialog alloc] init]; + shareDialog.fromViewController = self; + if (![self shareWith:shareDialog content:[self getGameShareContent:NO]]) { + [self displayInstallAppWithAppName:@"Facebook"]; + } + break; } - -} - -- (void)updateScoreLabel { - self.scoreLabel.text = [NSString stringWithFormat:@"W = %d L = %d T = %d", _wins, _losses, _ties]; -} - -- (IBAction)clickRPSButton:(id)sender { - UIButton *button = sender; - RPSCall choice = (RPSCall)button.tag; - self.playerHand.image = _leftImages[choice]; - [self callGame:choice]; - [self setFieldForPlayAgain]; -} - -- (IBAction)clickAgainButton:(id)sender { - [self resetField]; - [self animateField]; -} - -- (IBAction)clickFacebookButton:(id)sender { - UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil - delegate:self - cancelButtonTitle:@"Cancel" - destructiveButtonTitle:nil - otherButtonTitles:@"Share on Facebook", - @"Share on Messenger", - @"Friends' Activity", - [FBSDKAccessToken currentAccessToken] ? @"Log out" : @"Log in", - nil]; - // Show the sheet - [sheet showInView:sender]; -} - -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { - if (buttonIndex != 0) { // ok - if (_alertOkHandler) { - _alertOkHandler(); - _alertOkHandler = nil; - } + case 1: { // Share on Messenger + if (![self shareWith:[[FBSDKMessageDialog alloc] init] content:[self getGameShareContent:YES]]) { + [self displayInstallAppWithAppName:@"Messenger"]; + } + break; } -} - -- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { - switch (buttonIndex) { - case 0: { // Share on Facebook - FBSDKShareDialog *shareDialog = [[FBSDKShareDialog alloc] init]; - shareDialog.fromViewController = self; - if (![self shareWith:shareDialog content:[self getGameShareContent:NO]]) { - [self displayInstallAppWithAppName:@"Facebook"]; - } - break; - } - case 1: { // Share on Messenger - if (![self shareWith:[[FBSDKMessageDialog alloc] init] content:[self getGameShareContent:YES]]) { - [self displayInstallAppWithAppName:@"Messenger"]; - } - break; - } - case 2: { // See Friends - UIViewController *friends; - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - friends = [[RPSFriendsViewController alloc] initWithNibName:@"RPSFriendsViewController_iPhone" bundle:nil]; - } else { - friends = [[RPSFriendsViewController alloc] initWithNibName:@"RPSFriendsViewController_iPad" bundle:nil]; - } - [self.navigationController pushViewController:friends - animated:YES]; - break; - } - case 3: { // Login and logout - if ([FBSDKAccessToken currentAccessToken]) { - FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; - [login logOut]; - } else { - // Try to login with permissions - [self loginAndRequestPermissionsWithSuccessHandler:nil - declinedOrCanceledHandler:^{ - // If the user declined permissions tell them why we need permissions - // and ask for permissions again if they want to grant permissions. - [self alertDeclinedPublishActionsWithCompletion:^{ - [self loginAndRequestPermissionsWithSuccessHandler:nil - declinedOrCanceledHandler:nil - errorHandler:^(NSError * error) { - NSLog(@"Error: %@", error.description); - }]; - }]; - } - errorHandler:^(NSError * error) { - NSLog(@"Error: %@", error.description); - }]; - } - } + case 2: { // See Friends + UIViewController *friends; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + friends = [[RPSFriendsViewController alloc] initWithNibName:@"RPSFriendsViewController_iPhone" bundle:nil]; + } else { + friends = [[RPSFriendsViewController alloc] initWithNibName:@"RPSFriendsViewController_iPad" bundle:nil]; + } + [self.navigationController pushViewController:friends + animated:YES]; + break; } -} - -- (BOOL)hasPlayedAtLeastOnce { - return _lastPlayerCall != RPSCallNone && _lastComputerCall != RPSCallNone; -} - -- (id) getGameShareContent:(BOOL)isShareForMessenger { - return (self.hasPlayedAtLeastOnce && !isShareForMessenger) ? [self getGameActivityShareContent] : [self getGameLinkShareContent]; -} - -- (FBSDKShareOpenGraphContent *) getGameActivityShareContent { - // set action's gesture property - FBSDKShareOpenGraphAction *action = [FBSDKShareOpenGraphAction actionWithType:@"fb_sample_rps:throw" - objectID:builtInOpenGraphObjects[_lastPlayerCall] - key:@"fb_sample_rps:gesture"]; - // set action's opposing_gesture property - [action setString:builtInOpenGraphObjects[_lastComputerCall] forKey:@"fb_sample_rps:opposing_gesture"]; - - FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init]; - content.action = action; - content.previewPropertyName = @"fb_sample_rps:gesture"; - return content; -} - -- (BOOL)shareWith:(id)dialog content:(id)content{ - dialog.shareContent = content; - dialog.delegate = self; - return [dialog show]; -} - -- (void) displayInstallAppWithAppName:(NSString *)appName { - NSString *message = [NSString stringWithFormat: - @"Install or upgrade the %@ application on your device and " - @"get cool new sharing features for this application. " - @"What do you want to do?" , appName]; - [self alertWithMessage:message - ok:@"Install or Upgrade Now" - cancel:@"Decide Later" - completion:^{ - [[UIApplication sharedApplication] - openURL:[NSURL URLWithString:[NSString stringWithFormat:@"itms-apps://itunes.com/apps/%@", appName]]]; - }]; -} - -- (FBSDKShareLinkContent *)getGameLinkShareContent { - FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init]; - content.contentURL = [NSURL URLWithString:@"https://developers.facebook.com/"]; - return content; -} - -- (FBSDKShareOpenGraphObject *)createGameObject { - RPSResult result = [self resultForPlayerCall:_lastPlayerCall - computerCall:_lastComputerCall]; - - NSString *resultName = kResults[result]; - - FBSDKShareOpenGraphObject *object = [[FBSDKShareOpenGraphObject alloc] init]; - [object setString:@"fb_sample_rps:game" forKey:@"og:type"]; - [object setString:@"an awesome game of Rock, Paper, Scissors" forKey:@"og:title"]; - [object setString:builtInOpenGraphObjects[_lastPlayerCall] forKey:@"fb_sample_rps:player_gesture"]; - [object setString:builtInOpenGraphObjects[_lastComputerCall] forKey:@"fb_sample_rps:opponent_gesture"]; - [object setString:resultName forKey:@"fb_sample_rps:result"]; - [object setString:photoURLs[_lastPlayerCall] forKey:@"og:image"]; - return object; -} - -- (FBSDKShareOpenGraphAction *)createPlayActionWithGame:(FBSDKShareOpenGraphObject *)game { - return [FBSDKShareOpenGraphAction actionWithType:@"fb_sample_rps:play" object:game key:@"fb_sample_rps:game"]; -} - -- (void)loginAndRequestPermissionsWithSuccessHandler:(RPSBlock) successHandler - declinedOrCanceledHandler:(RPSBlock) declinedOrCanceledHandler - errorHandler:(void (^)(NSError *)) errorHandler{ - FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; - [login logInWithPermissions:@[@"publish_actions"] - fromViewController:self - handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { - if (error) { - if (errorHandler) { - errorHandler(error); - } - return; - } + case 3: { // Login and logout + if ([FBSDKAccessToken currentAccessToken]) { + FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; + [login logOut]; + } else { + // Try to login with permissions + [self loginAndRequestPermissionsWithSuccessHandler:nil + declinedOrCanceledHandler:^{ + // If the user declined permissions tell them why we need permissions + // and ask for permissions again if they want to grant permissions. + [self alertDeclinedPublishActionsWithCompletion:^{ + [self loginAndRequestPermissionsWithSuccessHandler:nil + declinedOrCanceledHandler:nil + errorHandler:^(NSError *error) { + NSLog(@"Error: %@", error.description); + }]; + }]; + } + errorHandler:^(NSError *error) { + NSLog(@"Error: %@", error.description); + }]; + } + } + } +} + +- (BOOL)hasPlayedAtLeastOnce +{ + return _lastPlayerCall != RPSCallNone && _lastComputerCall != RPSCallNone; +} + +- (id)getGameShareContent:(BOOL)isShareForMessenger +{ + return (self.hasPlayedAtLeastOnce && !isShareForMessenger) ? [self getGameActivityShareContent] : [self getGameLinkShareContent]; +} + +- (FBSDKShareOpenGraphContent *)getGameActivityShareContent +{ + // set action's gesture property + FBSDKShareOpenGraphAction *action = [FBSDKShareOpenGraphAction actionWithType:@"fb_sample_rps:throw" + objectID:builtInOpenGraphObjects[_lastPlayerCall] + key:@"fb_sample_rps:gesture"]; + // set action's opposing_gesture property + [action setString:builtInOpenGraphObjects[_lastComputerCall] forKey:@"fb_sample_rps:opposing_gesture"]; + + FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init]; + content.action = action; + content.previewPropertyName = @"fb_sample_rps:gesture"; + return content; +} + +- (BOOL)shareWith:(id)dialog content:(id)content +{ + dialog.shareContent = content; + dialog.delegate = self; + return [dialog show]; +} + +- (void)displayInstallAppWithAppName:(NSString *)appName +{ + NSString *message = [NSString stringWithFormat: + @"Install or upgrade the %@ application on your device and " + @"get cool new sharing features for this application. " + @"What do you want to do?", appName]; + [self alertWithMessage:message + ok:@"Install or Upgrade Now" + cancel:@"Decide Later" + completion:^{ + [[UIApplication sharedApplication] + openURL:[NSURL URLWithString:[NSString stringWithFormat:@"itms-apps://itunes.com/apps/%@", appName]]]; + }]; +} + +- (FBSDKShareLinkContent *)getGameLinkShareContent +{ + FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init]; + content.contentURL = [NSURL URLWithString:@"https://developers.facebook.com/"]; + return content; +} + +- (FBSDKShareOpenGraphObject *)createGameObject +{ + RPSResult result = [self resultForPlayerCall:_lastPlayerCall + computerCall:_lastComputerCall]; + + NSString *resultName = kResults[result]; + + FBSDKShareOpenGraphObject *object = [[FBSDKShareOpenGraphObject alloc] init]; + [object setString:@"fb_sample_rps:game" forKey:@"og:type"]; + [object setString:@"an awesome game of Rock, Paper, Scissors" forKey:@"og:title"]; + [object setString:builtInOpenGraphObjects[_lastPlayerCall] forKey:@"fb_sample_rps:player_gesture"]; + [object setString:builtInOpenGraphObjects[_lastComputerCall] forKey:@"fb_sample_rps:opponent_gesture"]; + [object setString:resultName forKey:@"fb_sample_rps:result"]; + [object setString:photoURLs[_lastPlayerCall] forKey:@"og:image"]; + return object; +} + +- (FBSDKShareOpenGraphAction *)createPlayActionWithGame:(FBSDKShareOpenGraphObject *)game +{ + return [FBSDKShareOpenGraphAction actionWithType:@"fb_sample_rps:play" object:game key:@"fb_sample_rps:game"]; +} + +- (void)loginAndRequestPermissionsWithSuccessHandler:(RPSBlock)successHandler + declinedOrCanceledHandler:(RPSBlock)declinedOrCanceledHandler + errorHandler:(void (^)(NSError *))errorHandler +{ + FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; + [login logInWithPermissions:@[@"publish_actions"] + fromViewController:self + handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + if (error) { + if (errorHandler) { + errorHandler(error); + } + return; + } - if ([FBSDKAccessToken currentAccessToken] && - [[FBSDKAccessToken currentAccessToken].permissions containsObject:@"publish_actions"]) { - if (successHandler) { - successHandler(); - } - return; - } + if ([FBSDKAccessToken currentAccessToken] + && [[FBSDKAccessToken currentAccessToken].permissions containsObject:@"publish_actions"]) { + if (successHandler) { + successHandler(); + } + return; + } - if (declinedOrCanceledHandler) { - declinedOrCanceledHandler(); - } - }]; + if (declinedOrCanceledHandler) { + declinedOrCanceledHandler(); + } + }]; } -- (void)alertDeclinedPublishActionsWithCompletion:(RPSBlock)completion { - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Publish Permissions" - message:@"Publish permissions are needed to share game content automatically. Do you want to enable publish permissions?" - delegate:self - cancelButtonTitle:@"No" - otherButtonTitles:@"Ok", nil]; - _alertOkHandler = [completion copy]; - [alertView show]; +- (void)alertDeclinedPublishActionsWithCompletion:(RPSBlock)completion +{ + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Publish Permissions" + message:@"Publish permissions are needed to share game content automatically. Do you want to enable publish permissions?" + delegate:self + cancelButtonTitle:@"No" + otherButtonTitles:@"Ok", nil]; + _alertOkHandler = [completion copy]; + [alertView show]; } - (void)alertWithMessage:(NSString *)message ok:(NSString *)ok cancel:(NSString *)cancel - completion:(RPSBlock)completion { - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Share with Facebook" - message:message - delegate:self - cancelButtonTitle:cancel - otherButtonTitles:ok, nil]; - _alertOkHandler = [completion copy]; - [alertView show]; -} - -- (void)publishPhotoForGesture:(RPSCall)gesture { - FBSDKGraphRequestConnection *conn = [[FBSDKGraphRequestConnection alloc] init]; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/staging_resources" - parameters:@{@"file":_imagesToPublish[gesture]} - tokenString:[FBSDKAccessToken currentAccessToken].tokenString - version:nil - HTTPMethod:@"POST"]; - [conn addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - if (error) { - NSLog(@"%@", error); - } else { - photoURLs[gesture] = result[@"uri"]; - [self publishResult]; - } - }]; - [conn start]; -} - -- (void)publishResult { - // Check if we have publish permissions and ask for them if we don't - if (![FBSDKAccessToken currentAccessToken] || - ![[FBSDKAccessToken currentAccessToken].permissions containsObject:@"publish_actions"]) - { - NSLog(@"Re-requesting permissions"); - _interestedInImplicitShare = NO; - [self alertWithMessage:@"Share game activity with your friends?" - ok:@"Yes" - cancel:@"Maybe Later" - completion:^{ - _interestedInImplicitShare = YES; - [self loginAndRequestPermissionsWithSuccessHandler:^{ - [self publishResult]; - } - declinedOrCanceledHandler:nil - errorHandler:^(NSError * error) { - NSLog(@"Error: %@", error.description); - }]; - }]; - return; - } - - // We want to upload a photo representing the gesture the player threw, and use it as the - // image for our game OG object. But we optimize this and only upload one instance per session. - // So if we already have the image URL, we use it, otherwise we'll initiate an upload and - // publish the result once it finishes. - if (!photoURLs[_lastPlayerCall]) { - [self publishPhotoForGesture:_lastPlayerCall]; - return; + completion:(RPSBlock)completion +{ + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Share with Facebook" + message:message + delegate:self + cancelButtonTitle:cancel + otherButtonTitles:ok, nil]; + _alertOkHandler = [completion copy]; + [alertView show]; +} + +- (void)publishPhotoForGesture:(RPSCall)gesture +{ + FBSDKGraphRequestConnection *conn = [[FBSDKGraphRequestConnection alloc] init]; + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/staging_resources" + parameters:@{@"file" : _imagesToPublish[gesture]} + tokenString:[FBSDKAccessToken currentAccessToken].tokenString + version:nil + HTTPMethod:@"POST"]; + [conn addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + if (error) { + NSLog(@"%@", error); + } else { + photoURLs[gesture] = result[@"uri"]; + [self publishResult]; } - - FBSDKShareOpenGraphObject *game = [self createGameObject]; - FBSDKShareOpenGraphAction *action = [self createPlayActionWithGame:game]; - FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init]; - content.action = action; - content.previewPropertyName = @"fb_sample_rps:game"; - [FBSDKShareAPI shareWithContent:content delegate:self]; + }]; + [conn start]; +} + +- (void)publishResult +{ + // Check if we have publish permissions and ask for them if we don't + if (![FBSDKAccessToken currentAccessToken] + || ![[FBSDKAccessToken currentAccessToken].permissions containsObject:@"publish_actions"]) { + NSLog(@"Re-requesting permissions"); + _interestedInImplicitShare = NO; + [self alertWithMessage:@"Share game activity with your friends?" + ok:@"Yes" + cancel:@"Maybe Later" + completion:^{ + _interestedInImplicitShare = YES; + [self loginAndRequestPermissionsWithSuccessHandler:^{ + [self publishResult]; + } + declinedOrCanceledHandler:nil + errorHandler:^(NSError *error) { + NSLog(@"Error: %@", error.description); + }]; + }]; + return; + } + + // We want to upload a photo representing the gesture the player threw, and use it as the + // image for our game OG object. But we optimize this and only upload one instance per session. + // So if we already have the image URL, we use it, otherwise we'll initiate an upload and + // publish the result once it finishes. + if (!photoURLs[_lastPlayerCall]) { + [self publishPhotoForGesture:_lastPlayerCall]; + return; + } + + FBSDKShareOpenGraphObject *game = [self createGameObject]; + FBSDKShareOpenGraphAction *action = [self createPlayActionWithGame:game]; + FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init]; + content.action = action; + content.previewPropertyName = @"fb_sample_rps:game"; + [FBSDKShareAPI shareWithContent:content delegate:self]; } #pragma mark - FBSDKSharingDelegate -- (void)sharer:(id)sharer didCompleteWithResults:(NSDictionary *)results { - NSLog(@"Posted OG action with id: %@", results[@"postId"]); +- (void)sharer:(id)sharer didCompleteWithResults:(NSDictionary *)results +{ + NSLog(@"Posted OG action with id: %@", results[@"postId"]); } -- (void)sharer:(id)sharer didFailWithError:(NSError *)error { - NSLog(@"Error: %@", error.description); +- (void)sharer:(id)sharer didFailWithError:(NSError *)error +{ + NSLog(@"Error: %@", error.description); } -- (void)sharerDidCancel:(id)sharer { - NSLog(@"Canceled share"); +- (void)sharerDidCancel:(id)sharer +{ + NSLog(@"Canceled share"); } #pragma mark - Logging App Event - (void)logCurrentPlayerCall:(RPSCall)playerCall lastPlayerCall:(RPSCall)lastPlayerCall - lastComputerCall:(RPSCall)lastComputerCall { - // log the user's choice while comparing it against the result of their last throw - if (lastComputerCall != RPSCallNone && lastComputerCall != RPSCallNone) { - RPSResult lastResult = [self resultForPlayerCall:lastPlayerCall - computerCall:lastComputerCall]; - - NSString *transitionalWord = (lastResult == RPSResultWin? @"against" : - lastResult == RPSResultTie? @"with" : @"to"); - NSString *previousResult = [NSString stringWithFormat:@"%@ %@ %@", - kResults[lastResult], - transitionalWord, - callType[lastPlayerCall + 1]]; - [FBSDKAppEvents logEvent:@"Throw Based on Last Result" - parameters:@{callType[playerCall + 1] : previousResult}]; - } + lastComputerCall:(RPSCall)lastComputerCall +{ + // log the user's choice while comparing it against the result of their last throw + if (lastComputerCall != RPSCallNone && lastComputerCall != RPSCallNone) { + RPSResult lastResult = [self resultForPlayerCall:lastPlayerCall + computerCall:lastComputerCall]; + + NSString *transitionalWord = (lastResult == RPSResultWin ? @"against" + : lastResult == RPSResultTie ? @"with" : @"to"); + NSString *previousResult = [NSString stringWithFormat:@"%@ %@ %@", + kResults[lastResult], + transitionalWord, + callType[lastPlayerCall + 1]]; + [FBSDKAppEvents logEvent:@"Throw Based on Last Result" + parameters:@{callType[playerCall + 1] : previousResult}]; + } +} + +- (void)logPlayerCall:(RPSCall)playerCall result:(RPSResult)result timeTaken:(NSTimeInterval)timeTaken +{ + // log the user's choice and the respective result + NSString *playerChoice = callType[playerCall + 1]; + [FBSDKAppEvents logEvent:@"Round End" + valueToSum:timeTaken + parameters:@{@"roundResult" : kResults[result], @"playerChoice" : playerChoice}]; +} + +- (void)logTimeTaken:(NSTimeInterval)timeTaken +{ + // logs the time a user takes to make a choice in a round + NSString *timeTakenStr = (timeTaken < 0.5f ? @"< 0.5s" + : timeTaken < 1.0f ? @"0.5s <= t < 1.0s" + : timeTaken < 1.5f ? @"1.0s <= t < 1.5s" + : timeTaken < 2.0f ? @"1.5s <= t < 2.0s" + : timeTaken < 2.5f ? @"2.0s <= t < 2.5s" : @" >= 2.5s"); + [FBSDKAppEvents logEvent:@"Time Taken" + valueToSum:timeTaken + parameters:@{@"Time Taken" : timeTakenStr}]; } -- (void)logPlayerCall:(RPSCall)playerCall result:(RPSResult)result timeTaken:(NSTimeInterval)timeTaken { - // log the user's choice and the respective result - NSString *playerChoice = callType[playerCall + 1]; - [FBSDKAppEvents logEvent:@"Round End" - valueToSum:timeTaken - parameters:@{@"roundResult": kResults[result], @"playerChoice" : playerChoice}]; -} - -- (void)logTimeTaken:(NSTimeInterval)timeTaken { - // logs the time a user takes to make a choice in a round - NSString *timeTakenStr = (timeTaken < 0.5f? @"< 0.5s" : - timeTaken < 1.0f? @"0.5s <= t < 1.0s" : - timeTaken < 1.5f? @"1.0s <= t < 1.5s" : - timeTaken < 2.0f? @"1.5s <= t < 2.0s" : - timeTaken < 2.5f? @"2.0s <= t < 2.5s" : @" >= 2.5s"); - [FBSDKAppEvents logEvent:@"Time Taken" - valueToSum:timeTaken - parameters:@{@"Time Taken" : timeTakenStr}]; -} @end diff --git a/samples/RPSSample/RPSSample/RPSRootViewController.h b/samples/RPSSample/RPSSample/RPSRootViewController.h index c44eeca179..3fb5f3e341 100644 --- a/samples/RPSSample/RPSSample/RPSRootViewController.h +++ b/samples/RPSSample/RPSSample/RPSRootViewController.h @@ -20,6 +20,6 @@ @interface RPSRootViewController : UIViewController -@property (nonatomic, strong)UITabBarController *tabBarController; +@property (nonatomic, strong) UITabBarController *tabBarController; @end diff --git a/samples/RPSSample/RPSSample/RPSRootViewController.m b/samples/RPSSample/RPSSample/RPSRootViewController.m index bcb17c5dce..d0ddc42b95 100644 --- a/samples/RPSSample/RPSSample/RPSRootViewController.m +++ b/samples/RPSSample/RPSSample/RPSRootViewController.m @@ -25,26 +25,26 @@ @implementation RPSRootViewController - (void)viewDidLoad { - [super viewDidLoad]; - self.tabBarController = [[UITabBarController alloc] init]; - - UIViewController *gameViewController; - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { - gameViewController = [[RPSGameViewController alloc] initWithNibName:@"RPSGameViewController_iPhone" bundle:nil]; - } else { - gameViewController = [[RPSGameViewController alloc] initWithNibName:@"RPSGameViewController_iPad" bundle:nil]; - } - - UINavigationController *gameNavigationController = [[UINavigationController alloc] initWithRootViewController:gameViewController]; - gameViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Game" image:[UIImage imageNamed:@"game.png"] tag:0]; - - UIViewController *toolViewController = [[RPSAutoAppLinkDebugTool alloc] init]; - UINavigationController *toolNavigationController = [[UINavigationController alloc] initWithRootViewController:toolViewController]; - toolViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Auto Applink Debug Tool" image:[UIImage imageNamed:@"tool.png"] tag:1]; - toolNavigationController.navigationBar.topItem.title = @"Debug Tool"; - - self.tabBarController.viewControllers = @[gameNavigationController, toolNavigationController]; - [self.view addSubview:self.tabBarController.view]; + [super viewDidLoad]; + self.tabBarController = [[UITabBarController alloc] init]; + + UIViewController *gameViewController; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { + gameViewController = [[RPSGameViewController alloc] initWithNibName:@"RPSGameViewController_iPhone" bundle:nil]; + } else { + gameViewController = [[RPSGameViewController alloc] initWithNibName:@"RPSGameViewController_iPad" bundle:nil]; + } + + UINavigationController *gameNavigationController = [[UINavigationController alloc] initWithRootViewController:gameViewController]; + gameViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Game" image:[UIImage imageNamed:@"game.png"] tag:0]; + + UIViewController *toolViewController = [[RPSAutoAppLinkDebugTool alloc] init]; + UINavigationController *toolNavigationController = [[UINavigationController alloc] initWithRootViewController:toolViewController]; + toolViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Auto Applink Debug Tool" image:[UIImage imageNamed:@"tool.png"] tag:1]; + toolNavigationController.navigationBar.topItem.title = @"Debug Tool"; + + self.tabBarController.viewControllers = @[gameNavigationController, toolNavigationController]; + [self.view addSubview:self.tabBarController.view]; } @end diff --git a/samples/RPSSample/RPSSample/main.m b/samples/RPSSample/RPSSample/main.m index 0cbabe53ba..4c15bcbc14 100644 --- a/samples/RPSSample/RPSSample/main.m +++ b/samples/RPSSample/RPSSample/main.m @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([RPSAppDelegate class])); - } + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([RPSAppDelegate class])); + } } From 15cb7f558193378e2261a930df47f48c47ba4961 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 22 Sep 2020 16:50:25 -0700 Subject: [PATCH 002/227] Hardening Unit Tests Summary: More hardening around unit tests. It's really critical that we only mock from one place and clean up mocks after every test case. Reviewed By: KylinChang Differential Revision: D23797082 fbshipit-source-id: 61e4f4f36587f4d4d55b41fdb9faa0fe54ac05c4 --- .../FBSDKApplicationDelegateTests.m | 1 + .../Internal/AppEvents/FBSDKAppEventsTests.m | 166 ++++++++++++++---- .../AppEvents/FBSDKAppEventsUtilityTests.m | 5 +- .../Internal/Helpers/FBSDKTestCase.h | 18 +- .../Internal/Helpers/FBSDKTestCase.m | 38 +++- 5 files changed, 184 insertions(+), 44 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index c71ba75e0e..4744e1a16f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -293,6 +293,7 @@ - (void)testDidFinishLaunchingCalledFromAutoInit OCMStub([_partialDelegateMock applicationDidBecomeActive:UIApplication.sharedApplication]); [self stubCheckingFeatures]; [self stubDefaultMeasurementEventListenerWith:[FBSDKMeasurementEventListener new]]; + [self stubCachedProfileWith:nil]; OCMStub([self.timeSpentDataClassMock setSourceApplication:OCMArg.any openURL:OCMArg.any]); OCMStub([self.timeSpentDataClassMock registerAutoResetSourceApplication]); OCMStub([self.internalUtilityClassMock validateFacebookReservedURLSchemes]); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index cf0f609eee..76f11ba463 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -36,6 +36,7 @@ #import "FBSDKSettings.h" #import "FBSDKTestCase.h" #import "FBSDKUtility.h" +#import "SampleAccessToken.h" #import "UserDefaultsSpy.h" static NSString *const _mockAppID = @"mockAppID"; @@ -101,7 +102,6 @@ @interface FBSDKAppEventsTests : FBSDKTestCase NSDictionary *_mockPayload; double _mockPurchaseAmount; NSString *_mockCurrency; - id _mockAppEventsUtility; } @end @@ -121,15 +121,17 @@ - (void)setUp [FBSDKAppEvents setLoggingOverrideAppID:_mockAppID]; self.appEventsMock = OCMPartialMock([FBSDKAppEvents singleton]); - // Mock FBSDKAppEventsUtility - _mockAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); - OCMStub([_mockAppEventsUtility shouldDropAppEvent]).andReturn(NO); - OCMStub([_mockAppEventsUtility advertisingTrackingStatus]).andReturn(FBSDKAdvertisingTrackingAllowed); + + // Mock FBSDKAppEventsUtility methods + [self stubAppEventsUtilityShouldDropAppEventWith:NO]; } - (void)tearDown { + [super tearDown]; + [OHHTTPStubs removeAllStubs]; + [FBSDKAppEvents resetSingleton]; } - (void)testLogPurchaseFlush @@ -408,34 +410,121 @@ - (void)testCheckPersistedEventsCalledWhenLogEvent OCMVerifyAll(self.appEventsMock); } -- (void)testRequestForCustomAudienceThirdPartyIDWithAccessToken +- (void)testRequestForCustomAudienceThirdPartyIDWithTrackingDisallowed { - id mockAccessToken = [OCMockObject niceMockForClass:[FBSDKAccessToken class]]; - NSString *tokenString = [FBSDKAppEventsUtility tokenStringToUseFor:mockAccessToken]; - NSString *graphPath = [NSString stringWithFormat:@"%@/custom_audience_third_party_id", _mockAppID]; - FBSDKGraphRequest *expectedRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath - parameters:@{} - tokenString:tokenString - HTTPMethod:nil - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; + [self stubUserDefaultsWith:[UserDefaultsSpy new]]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingDisallowed]; + + XCTAssertNil( + [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:SampleAccessToken.validToken], + "Should not create a request for third party id if tracking is disallowed even if there is a current access token" + ); + XCTAssertNil( + [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:nil], + "Should not create a request for third party id if tracking is disallowed" + ); +} + +- (void)testRequestForCustomAudienceThirdPartyIDWithLimitedEventAndDataUsage +{ + [self stubSettingsShouldLimitEventAndDataUsageWith:YES]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; - // without access token - [[_mockAppEventsUtility expect] advertiserID]; + XCTAssertNil( + [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:SampleAccessToken.validToken], + "Should not create a request for third party id if event and data usage is limited even if there is a current access token" + ); + XCTAssertNil( + [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:nil], + "Should not create a request for third party id if event and data usage is limited" + ); +} + +- (void)testRequestForCustomAudienceThirdPartyIDWithoutAccessTokenWithoutAdvertiserID +{ + [self stubSettingsShouldLimitEventAndDataUsageWith:NO]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; + [self stubAppEventsUtilityAdvertiserIDWith:nil]; + + XCTAssertNil( + [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:nil], + "Should not create a request for third party id if there is no access token or advertiser id" + ); +} + +- (void)testRequestForCustomAudienceThirdPartyIDWithoutAccessTokenWithAdvertiserID +{ + NSString *advertiserID = @"abc123"; + [self stubSettingsShouldLimitEventAndDataUsageWith:NO]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; + [self stubAppEventsUtilityAdvertiserIDWith:advertiserID]; FBSDKGraphRequest *request = [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:nil]; + XCTAssertEqualObjects( + request.parameters, + @{ @"udid" : advertiserID }, + "Should include the udid in the request when there is no access token available" + ); +} + +- (void)testRequestForCustomAudienceThirdPartyIDWithAccessTokenWithoutAdvertiserID +{ + FBSDKAccessToken *token = SampleAccessToken.validToken; + [self stubSettingsShouldLimitEventAndDataUsageWith:NO]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; + [self stubAppEventsUtilityAdvertiserIDWith:nil]; + [self stubAppEventsUtilityTokenStringToUseForTokenWith:token.tokenString]; + + FBSDKGraphRequest *request = [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:token]; + XCTAssertEqualObjects( + request.tokenString, + token.tokenString, + "Should include the access token in the request when there is one available" + ); + XCTAssertNil( + request.parameters[@"udid"], + "Should not include the udid in the request when there is none available" + ); +} - [_mockAppEventsUtility verify]; +- (void)testRequestForCustomAudienceThirdPartyIDWithAccessTokenWithAdvertiserID +{ + NSString *expectedGraphPath = [NSString stringWithFormat:@"%@/custom_audience_third_party_id", _mockAppID]; - XCTAssertNil(request); + FBSDKAccessToken *token = SampleAccessToken.validToken; + NSString *advertiserID = @"abc123"; - // with access token - [[_mockAppEventsUtility reject] advertiserID]; + [self stubSettingsShouldLimitEventAndDataUsageWith:NO]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; + [self stubAppEventsUtilityTokenStringToUseForTokenWith:token.tokenString]; + [self stubAppEventsUtilityAdvertiserIDWith:advertiserID]; - request = [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:mockAccessToken]; + FBSDKGraphRequest *request = [FBSDKAppEvents requestForCustomAudienceThirdPartyIDWithAccessToken:token]; - XCTAssertEqualObjects(expectedRequest.graphPath, request.graphPath); - XCTAssertEqualObjects(expectedRequest.HTTPMethod, request.HTTPMethod); - XCTAssertEqualObjects(expectedRequest.parameters, expectedRequest.parameters); + XCTAssertEqualObjects( + request.tokenString, + token.tokenString, + "Should include the access token in the request when there is one available" + ); + XCTAssertNil( + request.parameters[@"udid"], + "Should not include the udid in the request when there is an access token available" + ); + XCTAssertEqualObjects( + request.graphPath, + expectedGraphPath, + "Should use the expected graph path for the request" + ); + XCTAssertEqual( + request.HTTPMethod, + FBSDKHTTPMethodGET, + "Should use the expected http method for the request" + ); + XCTAssertEqual( + request.flags, + FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery, + "Should use the expected flags for the request" + ); } - (void)testPublishInstall @@ -453,6 +542,7 @@ - (void)testPublishATEWithNoPing { [self stubAppID:@"mockAppID"]; [self stubUserDefaultsWith:[UserDefaultsSpy new]]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; id graphRequestMock = OCMClassMock([FBSDKGraphRequest class]); OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); @@ -467,6 +557,9 @@ - (void)testPublishATEWithNoPing [self.appEventsMock publishATE]; OCMVerify([graphRequestMock startWithCompletionHandler:[OCMArg any]]); + + [graphRequestMock stopMocking]; + graphRequestMock = nil; } - (void)testPublishATEWithPingLessThan24Hours @@ -475,6 +568,7 @@ - (void)testPublishATEWithPingLessThan24Hours UserDefaultsSpy *userDefault = [UserDefaultsSpy new]; [userDefault setObject:[NSDate dateWithTimeIntervalSinceNow:-12 * 60 * 60] forKey:[NSString stringWithFormat:@"com.facebook.sdk:lastATEPing%@", @"mockAppID"]]; [self stubUserDefaultsWith:userDefault]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; id graphRequestMock = OCMClassMock([FBSDKGraphRequest class]); OCMStub([graphRequestMock alloc]).andReturn(graphRequestMock); @@ -489,19 +583,22 @@ - (void)testPublishATEWithPingLessThan24Hours [self.appEventsMock publishATE]; OCMReject([graphRequestMock startWithCompletionHandler:[OCMArg any]]); + + [graphRequestMock stopMocking]; + graphRequestMock = nil; } - (void)testPublishATEWithVerifyingParams { [self stubAppID:@"mockAppID"]; [self stubUserDefaultsWith:[UserDefaultsSpy new]]; + [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; - id mockFBSDKAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); [self.appEventsMock publishATE]; OCMReject( - [mockFBSDKAppEventsUtility activityParametersDictionaryForEvent:[OCMArg any] - shouldAccessAdvertisingID:[OCMArg any]] + [self.appEventsUtilityClassMock activityParametersDictionaryForEvent:[OCMArg any] + shouldAccessAdvertisingID:[OCMArg any]] ); } @@ -524,6 +621,9 @@ - (void)testAppEventsKillSwitchDisabled accessToken:nil]; [self.appEventStatesMock verify]; + + [mockGateKeeperManager stopMocking]; + mockGateKeeperManager = nil; } - (void)testAppEventsKillSwitchEnabled @@ -541,6 +641,9 @@ - (void)testAppEventsKillSwitchEnabled parameters:nil isImplicitlyLogged:NO accessToken:nil]; + + [mockGateKeeperManager stopMocking]; + mockGateKeeperManager = nil; } - (void)testGraphRequestBannedWithAutoInitDisabled @@ -649,12 +752,14 @@ - (void)testLogInternalEventWithAccessToken ).andForwardToRealObject(); [FBSDKAppEvents logInternalEvent:_mockEventName parameters:@{} isImplicitlyLogged:NO accessToken:mockAccessToken]; OCMVerifyAll(self.appEventsMock); + + [mockAccessToken stopMocking]; + mockAccessToken = nil; } - (void)testInstanceLogEventWhenAutoLogAppEventsDisabled { - id mockSetting = OCMClassMock([FBSDKSettings class]); - OCMStub([mockSetting isAutoLogAppEventsEnabled]).andReturn(NO); + [self stubIsAutoLogAppEventsEnabled:NO]; OCMReject( [self.appEventsMock instanceLogEvent:_mockEventName valueToSum:@(_mockPurchaseAmount) @@ -668,8 +773,7 @@ - (void)testInstanceLogEventWhenAutoLogAppEventsDisabled - (void)testInstanceLogEventWhenAutoLogAppEventsEnabled { - id mockSetting = OCMClassMock([FBSDKSettings class]); - OCMStub([mockSetting isAutoLogAppEventsEnabled]).andReturn(YES); + [self stubIsAutoLogAppEventsEnabled:YES]; OCMExpect( [self.appEventsMock instanceLogEvent:_mockEventName valueToSum:@(_mockPurchaseAmount) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 3fe4c49d61..59c4d76dc5 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -198,7 +198,10 @@ - (void)testGetAdvertiserIDOniOS14WithCollectionEnabled OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); if (@available(iOS 14.0, *)) { - XCTAssertNotNil([FBSDKAppEventsUtility advertiserID]); + XCTAssertNotNil( + [FBSDKAppEventsUtility advertiserID], + "Advertiser id should not be nil when collection is enabled" + ); } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 723cf94b51..8398d1e3b4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -63,6 +63,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for mocking `FBSDKAppEventState` between tests @property (nullable, assign) id appEventStatesMock; +/// Used for sharing a `FBSDKAppEventsUtility` class mock between tests +@property (nullable, nonatomic, assign) id appEventsUtilityClassMock; + /// Used for sharing an `FBSDKApplicationDelegate` class mock between tests @property (nullable, assign) id fbApplicationDelegateClassMock; @@ -102,9 +105,6 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKInternalUtility` class mock between tests @property (nullable, nonatomic, assign) id internalUtilityClassMock; -/// Used for sharing a `FBSDKAppEventsUtility` class mock between tests -@property (nullable, nonatomic, assign) id appEventsUtilityClassMock; - /// Used for sharing a `FBSDKSKAdNetworkReporter` class mock between tests @property (nullable, nonatomic, assign) id adNetworkReporterClassMock; @@ -181,6 +181,18 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKSKAdNetworkReporter._loadConfigurationWithBlock` - (void)stubLoadingAdNetworkReporterConfiguration; +/// Stubs `FBSDKAppEventsUtility.shouldDropAppEvent` with the provided value +- (void)stubAppEventsUtilityShouldDropAppEventWith:(BOOL)shouldDropEvent; + +/// Stubs `FBSDKSettings.shouldLimitEventAndDataUsage` with the provided value +- (void)stubSettingsShouldLimitEventAndDataUsageWith:(BOOL)shouldLimit; + +/// Stubs `FBSDKAppEventsUtility.advertiserID` with the provided value +- (void)stubAppEventsUtilityAdvertiserIDWith:(nullable NSString *)identifier; + +/// Stubs `FBSDKAppEventsUtility.tokenStringToUseFor:` and returns the provided string +- (void)stubAppEventsUtilityTokenStringToUseForTokenWith:(NSString *)tokenString; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index c5ffaa831f..5067c480e2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -60,6 +60,7 @@ - (void)setUp [self setUpSettingsMock]; [self setUpServerConfigurationManagerMock]; [self setUpAppEventsMock]; + [self setUpAppEventsUtilityMock]; [self setUpFBApplicationDelegateMock]; [self setUpGateKeeperManagerMock]; [self setUpFeatureManagerMock]; @@ -71,7 +72,6 @@ - (void)setUp [self setUpMeasurementEventListenerMock]; [self setUpTimeSpendDataMock]; [self setUpInternalUtilityMock]; - [self setUpAppEventsUtilityMock]; [self setUpAdNetworkReporterMock]; } @@ -85,6 +85,9 @@ - (void)tearDown [_appEventStatesMock stopMocking]; _appEventStatesMock = nil; + [_appEventsUtilityClassMock stopMocking]; + _appEventsUtilityClassMock = nil; + [_fbApplicationDelegateClassMock stopMocking]; _fbApplicationDelegateClassMock = nil; @@ -127,9 +130,6 @@ - (void)tearDown [_internalUtilityClassMock stopMocking]; _internalUtilityClassMock = nil; - [_appEventsUtilityClassMock stopMocking]; - _appEventsUtilityClassMock = nil; - [_adNetworkReporterClassMock stopMocking]; _adNetworkReporterClassMock = nil; } @@ -168,6 +168,11 @@ - (void)setUpAppEventsMock OCMStub([_appEventStatesMock initWithToken:[OCMArg any] appID:[OCMArg any]]).andReturn(_appEventStatesMock); } +- (void)setUpAppEventsUtilityMock +{ + _appEventsUtilityClassMock = OCMStrictClassMock(FBSDKAppEventsUtility.class); +} + - (void)setUpNSBundleMock { self.nsBundleClassMock = OCMStrictClassMock(NSBundle.class); @@ -215,11 +220,6 @@ - (void)setUpInternalUtilityMock self.internalUtilityClassMock = OCMStrictClassMock(FBSDKInternalUtility.class); } -- (void)setUpAppEventsUtilityMock -{ - self.appEventsUtilityClassMock = OCMClassMock(FBSDKAppEventsUtility.class); -} - - (void)setUpAdNetworkReporterMock { self.adNetworkReporterClassMock = OCMClassMock(FBSDKSKAdNetworkReporter.class); @@ -343,6 +343,11 @@ - (void)stubClientTokenWith:(nullable NSString *)token OCMStub(ClassMethod([_settingsClassMock clientToken])).andReturn(token); } +- (void)stubAppEventsUtilityShouldDropAppEventWith:(BOOL)shouldDropEvent +{ + OCMStub(ClassMethod([_appEventsUtilityClassMock shouldDropAppEvent])).andReturn(shouldDropEvent); +} + - (void)stubAdvertisingTrackingStatusWith:(FBSDKAdvertisingTrackingStatus)trackingStatus { OCMStub(ClassMethod([_appEventsUtilityClassMock advertisingTrackingStatus])).andReturn(trackingStatus); @@ -353,4 +358,19 @@ - (void)stubLoadingAdNetworkReporterConfiguration OCMStub(ClassMethod([_adNetworkReporterClassMock _loadConfigurationWithBlock:OCMArg.any])); } +- (void)stubSettingsShouldLimitEventAndDataUsageWith:(BOOL)shouldLimit +{ + OCMStub(ClassMethod([_settingsClassMock shouldLimitEventAndDataUsage])).andReturn(shouldLimit); +} + +- (void)stubAppEventsUtilityAdvertiserIDWith:(nullable NSString *)identifier +{ + OCMStub(ClassMethod([_appEventsUtilityClassMock advertiserID])).andReturn(identifier); +} + +- (void)stubAppEventsUtilityTokenStringToUseForTokenWith:(NSString *)tokenString +{ + OCMStub(ClassMethod([_appEventsUtilityClassMock tokenStringToUseFor:OCMArg.any])).andReturn(tokenString); +} + @end From 692add42ea278a3db9b0a00e92f59ad40eb84c03 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 22 Sep 2020 16:50:25 -0700 Subject: [PATCH 003/227] Bump Graph API v8 Summary: Bumps default version of graph api to v8 Reviewed By: KylinChang Differential Revision: D23844972 fbshipit-source-id: b3ead3c0a878024e57a70108189744457a99f615 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 2 +- FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 594774e1fb..432fb54a27 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -99,4 +99,4 @@ #endif #define FBSDK_VERSION_STRING @"7.1.1" -#define FBSDK_TARGET_PLATFORM_VERSION @"v7.0" +#define FBSDK_TARGET_PLATFORM_VERSION @"v8.0" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m index cbd1988da1..bde573eba0 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m @@ -29,7 +29,7 @@ #import "FBSDKUtility.h" static NSString *const _mockGraphPath = @"me"; -static NSString *const _mockDefaultVersion = @"v7.0"; +static NSString *const _mockDefaultVersion = @"v8.0"; static NSString *const _mockPrefix = @"graph."; static NSDictionary *const _mockParameters(void) { @@ -147,12 +147,12 @@ - (void)testSerializeURL params:_mockParameters() httpMethod:FBSDKHTTPMethodPOST forBatch:YES]; - NSString *expectedURL = @"https://graph.facebook.com/v7.0/me?fields="; + NSString *expectedURL = @"https://graph.facebook.com/v8.0/me?fields="; XCTAssertEqualObjects(url, expectedURL); // Test URLEncode and URLDecode - NSString *expectedEncodedURL = @"https%3A%2F%2Fgraph.facebook.com%2Fv7.0%2Fme%3Ffields%3D"; + NSString *expectedEncodedURL = @"https%3A%2F%2Fgraph.facebook.com%2Fv8.0%2Fme%3Ffields%3D"; NSString *encodedSerializedURL = [FBSDKUtility URLEncode:expectedURL]; XCTAssertEqualObjects(encodedSerializedURL, expectedEncodedURL); From cc9f67162caeab94dec7c0d834bf1a8b015cc1d7 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 23 Sep 2020 15:39:18 -0700 Subject: [PATCH 004/227] Bump v8.0.0 (#1497) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1497 $title Reviewed By: robtimp Differential Revision: D23857192 fbshipit-source-id: b15055daee5a981abc88a55af7abf838f22fbe50 --- CHANGELOG.md | 29 ++++++++++++++++++- Configurations/Version.xcconfig | 2 +- FBSDKCoreKit.podspec | 2 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 2 +- FBSDKGamingServicesKit.podspec | 2 +- FBSDKLoginKit.podspec | 2 +- FBSDKShareKit.podspec | 2 +- FBSDKTVOSKit.podspec | 2 +- FacebookSDK.podspec | 2 +- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 2 +- scripts/run.sh | 2 +- 11 files changed, 38 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c465281d4..e459f40138 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Important -[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v7.1.1...HEAD) +[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.0.0...HEAD) + +## 8.0.0 + +## Added +- Added timestamp for install event in iOS 14 +- Added method `setAdvertiserTrackingEnabled` to overwrite the `advertiser_tracking_enabled` flag +- Added `SKAdNetwork` support for installs +- Added `SKAdNetwork` support for conversion value in iOS 14 +- Added `FBSDKReferralManager` for integrating with the web referral dialog +- Added method `loginWithURL` to `FBSDKLoginManager` for supporting deep link authentication +- Added E2E tests for all in-market versions of the SDK that run on server changes to avoid regressions + +## Changed +- Event handling in iOS 14: will drop events if `setAdvertiserTrackingEnabled` is called with `false` in iOS 14 +- `FBSDKProfile - imageURLForPictureMode:size:` - User profile images will only be available when an access or client token is available + +## Deprecated +- `FBSDKSettings - isAutoInitEnabled` - Auto-initialization flag. Will be removed in the next major release. Future versions of the SDK will not utilize the `+ load` method to automatically initialize the SDK. + +## Fixed / Patched +- #1444 - Update crash handling to use sigaction in signal handler and respect SIG_IGN +- #1447 - Login form automatically closing when SDK is not initialized on startup +- #1478 - Minimum iOS deployment target is now 9.0 +- #1485 - StoreKit is now added as a weak framework for CocoaPods + +[2020-09-22](https://github.com/facebook/facebook-ios-sdk/releases/tag/v8.0.0) | +[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v7.1.1...v8.0.0) ## 7.1.1 diff --git a/Configurations/Version.xcconfig b/Configurations/Version.xcconfig index a54d2076b2..e0cb407740 100644 --- a/Configurations/Version.xcconfig +++ b/Configurations/Version.xcconfig @@ -17,6 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // The versions for FBSDK and Messenger SDK. -FBSDK_PROJECT_VERSION=7.1.1 +FBSDK_PROJECT_VERSION=8.0.0 MNSDK_PROJECT_VERSION=TODO_SUPPORT_MNSDK diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index 8765ef6095..d48398c194 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKCoreKit' - s.version = '7.1.1' + s.version = '8.0.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform core features' s.description = <<-DESC diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 432fb54a27..701dea4780 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -98,5 +98,5 @@ #endif -#define FBSDK_VERSION_STRING @"7.1.1" +#define FBSDK_VERSION_STRING @"8.0.0" #define FBSDK_TARGET_PLATFORM_VERSION @"v8.0" diff --git a/FBSDKGamingServicesKit.podspec b/FBSDKGamingServicesKit.podspec index 72f708ee53..3ca6ce9bd7 100644 --- a/FBSDKGamingServicesKit.podspec +++ b/FBSDKGamingServicesKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKGamingServicesKit' - s.version = '7.1.1' + s.version = '8.0.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Gaming Services' s.description = <<-DESC diff --git a/FBSDKLoginKit.podspec b/FBSDKLoginKit.podspec index aba6c29b24..2e5e4c444d 100644 --- a/FBSDKLoginKit.podspec +++ b/FBSDKLoginKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKLoginKit' - s.version = '7.1.1' + s.version = '8.0.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 diff --git a/FBSDKShareKit.podspec b/FBSDKShareKit.podspec index 228fc04f92..d47eaec5a7 100644 --- a/FBSDKShareKit.podspec +++ b/FBSDKShareKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKShareKit' - s.version = '7.1.1' + s.version = '8.0.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform Sharing Features' s.description = <<-DESC diff --git a/FBSDKTVOSKit.podspec b/FBSDKTVOSKit.podspec index 25b5d521a4..7b062dee0b 100644 --- a/FBSDKTVOSKit.podspec +++ b/FBSDKTVOSKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKTVOSKit' - s.version = '7.1.1' + s.version = '8.0.0' s.summary = 'Official Facebook SDK for tvOS to access Facebook Platform with features like Login and Graph API.' s.description = <<-DESC diff --git a/FacebookSDK.podspec b/FacebookSDK.podspec index 72e36372b2..d6c2545c35 100644 --- a/FacebookSDK.podspec +++ b/FacebookSDK.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FacebookSDK' - s.version = '7.1.1' + s.version = '8.0.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform' s.description = <<-DESC diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index 30fca2d7fd..154316e1a2 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -29,7 +29,7 @@ #define FBSDK_MAX_CRASH_LOGS 5 #define FBSDK_CRASH_PATH_NAME @"instrument" #ifndef FBSDK_VERSION_STRING - #define FBSDK_VERSION_STRING @"7.1.1" + #define FBSDK_VERSION_STRING @"8.0.0" #endif static const int fatalSignals[] = diff --git a/scripts/run.sh b/scripts/run.sh index 21ea3cebda..3f62611c03 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -74,7 +74,7 @@ main() { SDK_VERSION_FILES=( "Configurations/Version.xcconfig" "FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h" - "FBSDKCoreKit/FBSDKCoreKit/Basics/Instrument/FBSDKCrashHandler.m" + "Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m" ) SDK_GRAPH_API_VERSION_FILES=( From 0cd91819be1a2c93aa04dc569a5623caf4636975 Mon Sep 17 00:00:00 2001 From: Daniel Loomb Date: Wed, 23 Sep 2020 18:38:48 -0700 Subject: [PATCH 005/227] Moving video uploader into GamingServicesKit (#1494) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1494 Colocate FBSDKVideoUploader with classes that use it. Reviewed By: joesus Differential Revision: D23715063 fbshipit-source-id: 8231459755f104306adf1cfd779596f697ab6ae3 --- FBSDKGamingServicesKit.podspec | 2 +- .../project.pbxproj | 4 +- .../FBSDKGamingVideoUploader.m | 8 +- .../Internal/FBSDKVideoUploader.h | 0 .../Internal/FBSDKVideoUploader.m | 100 ++++++++++-------- .../FBSDKShareKit.xcodeproj/project.pbxproj | 20 ---- .../Internal/FBSDKShareDefines.h | 11 -- .../Internal/FBSDKShareKit+Internal.h | 1 - 8 files changed, 62 insertions(+), 84 deletions(-) rename {FBSDKShareKit/FBSDKShareKit => FBSDKGamingServicesKit/FBSDKGamingServicesKit}/Internal/FBSDKVideoUploader.h (100%) rename {FBSDKShareKit/FBSDKShareKit => FBSDKGamingServicesKit/FBSDKGamingServicesKit}/Internal/FBSDKVideoUploader.m (72%) diff --git a/FBSDKGamingServicesKit.podspec b/FBSDKGamingServicesKit.podspec index 3ca6ce9bd7..90aeb0849f 100644 --- a/FBSDKGamingServicesKit.podspec +++ b/FBSDKGamingServicesKit.podspec @@ -33,6 +33,6 @@ Pod::Spec.new do |s| s.source_files = 'FBSDKGamingServicesKit/FBSDKGamingServicesKit/**/*.{h,m}' s.public_header_files = 'FBSDKGamingServicesKit/FBSDKGamingServicesKit/*.{h}' - s.dependency 'FBSDKShareKit', "~> #{s.version}" + s.dependency 'FBSDKCoreKit', "~> #{s.version}" end diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj index 51a0ff96c7..684acac692 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj @@ -255,7 +255,7 @@ 9FC2000C247D82A00016A053 /* FBSDKGamingVideoUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKGamingVideoUploader.h; sourceTree = ""; }; 9FC2000D247D82A00016A053 /* FBSDKGamingVideoUploaderConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKGamingVideoUploaderConfiguration.h; sourceTree = ""; }; 9FC20012247D83400016A053 /* FBSDKShareKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FBSDKShareKit.xcodeproj; path = ../FBSDKShareKit/FBSDKShareKit.xcodeproj; sourceTree = ""; }; - 9FC2002C247D8ACF0016A053 /* FBSDKVideoUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKVideoUploader.h; path = ../../../FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h; sourceTree = ""; }; + 9FC2002C247D8ACF0016A053 /* FBSDKVideoUploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKVideoUploader.h; sourceTree = ""; }; F46A224024D9F14D005878A8 /* FBSDKGamingServicesKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FBSDKGamingServicesKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F46A224424D9F14D005878A8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F46A224B24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGamingServicesKitTestUtility.m; sourceTree = ""; }; @@ -266,7 +266,7 @@ F4A54C8A244619630063015F /* FBSDKGamingServicesKit-Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKGamingServicesKit-Common.xcconfig"; sourceTree = ""; }; F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitInternalImport.h; sourceTree = ""; }; F4DE318024D9F4A700297C18 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - F4DE31AC24D9FD6000297C18 /* FBSDKVideoUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKVideoUploader.m; path = ../../../FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m; sourceTree = ""; }; + F4DE31AC24D9FD6000297C18 /* FBSDKVideoUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKVideoUploader.m; sourceTree = ""; }; F4DE31CF24DA0DD400297C18 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = ../Carthage/Build/iOS/OCMock.framework; sourceTree = ""; }; F4F7C9B623F48F2C0030A346 /* FBSDKGamingImageUploaderConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGamingImageUploaderConfiguration.m; sourceTree = ""; }; F4F7C9B723F48F2C0030A346 /* FBSDKGamingServiceCompletionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKGamingServiceCompletionHandler.h; sourceTree = ""; }; diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m index aec7ec6f54..8d6a1e6b48 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/FBSDKGamingVideoUploader.m @@ -19,14 +19,8 @@ #import "FBSDKGamingVideoUploader.h" #import "FBSDKCoreKitInternalImport.h" - -#if defined FBSDKCOCOAPODS - #import -#else - #import "FBSDKVideoUploader.h" -#endif - #import "FBSDKGamingVideoUploaderConfiguration.h" +#import "FBSDKVideoUploader.h" @interface FBSDKGamingVideoUploader () { diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.h similarity index 100% rename from FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h rename to FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.h diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m similarity index 72% rename from FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m rename to FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m index 99564ff9b5..7b46797c02 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m @@ -22,13 +22,29 @@ #import "FBSDKCoreKitInternalImport.h" -#if defined FBSDK_SWIFT_PACKAGE - #import +#define FBSDK_GAMING_RESULT_COMPLETION_GESTURE_KEY @"completionGesture" +#define FBSDK_GAMING_RESULT_COMPLETION_GESTURE_VALUE_POST @"post" +#define FBSDK_GAMING_VIDEO_END_OFFSET @"end_offset" +#define FBSDK_GAMING_VIDEO_FILE_CHUNK @"video_file_chunk" +#define FBSDK_GAMING_VIDEO_ID @"video_id" +#define FBSDK_GAMING_VIDEO_SIZE @"file_size" +#define FBSDK_GAMING_VIDEO_START_OFFSET @"start_offset" +#define FBSDK_GAMING_VIDEO_UPLOAD_PHASE @"upload_phase" +#define FBSDK_GAMING_VIDEO_UPLOAD_PHASE_FINISH @"finish" +#define FBSDK_GAMING_VIDEO_UPLOAD_PHASE_START @"start" +#define FBSDK_GAMING_VIDEO_UPLOAD_PHASE_TRANSFER @"transfer" +#define FBSDK_GAMING_VIDEO_UPLOAD_SESSION_ID @"upload_session_id" +#define FBSDK_GAMING_VIDEO_UPLOAD_SUCCESS @"success" + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +static NSErrorDomain const FBSDKGamingVideoUploadErrorDomain = @"com.facebook.sdk.gaming.videoupload"; + #else - #import -#endif -#import "FBSDKShareDefines.h" +static NSString *const FBSDKGamingVideoUploadErrorDomain = @"com.facebook.sdk.gaming.videoupload"; + +#endif static NSString *const FBSDKVideoUploaderDefaultGraphNode = @"me"; static NSString *const FBSDKVideoUploaderEdge = @"videos"; @@ -73,13 +89,13 @@ - (void)_postStartRequest 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]]; + NSNumber *uploadSessionID = [self.numberFormatter numberFromString:result[FBSDK_GAMING_VIDEO_UPLOAD_SESSION_ID]]; + NSNumber *videoID = [self.numberFormatter numberFromString:result[FBSDK_GAMING_VIDEO_ID]]; NSDictionary *offsetDictionary = [self _extractOffsetsFromResultDictionary:result]; if (uploadSessionID == nil || videoID == nil) { [self.delegate videoUploader:self didFailWithError: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown + [FBSDKError errorWithDomain:FBSDKGamingVideoUploadErrorDomain + code:0 message:@"Failed to get valid upload_session_id or video_id."]]; return; } else if (offsetDictionary == nil) { @@ -92,15 +108,15 @@ - (void)_postStartRequest }; if (_videoSize == 0) { [self.delegate videoUploader:self didFailWithError: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown + [FBSDKError errorWithDomain:FBSDKGamingVideoUploadErrorDomain + code:0 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], + FBSDK_GAMING_VIDEO_UPLOAD_PHASE : FBSDK_GAMING_VIDEO_UPLOAD_PHASE_START, + FBSDK_GAMING_VIDEO_SIZE : [NSString stringWithFormat:@"%tu", _videoSize], } HTTPMethod:@"POST"] startWithCompletionHandler:startRequestCompletionHandler]; } @@ -114,8 +130,8 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona } 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]; + NSUInteger startOffset = [offsetDictionary[FBSDK_GAMING_VIDEO_START_OFFSET] unsignedIntegerValue]; + NSUInteger endOffset = [offsetDictionary[FBSDK_GAMING_VIDEO_END_OFFSET] unsignedIntegerValue]; if (startOffset == endOffset) { [self _postFinishRequest]; return; @@ -125,8 +141,8 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona NSData *data = [self.delegate videoChunkDataForVideoUploader:self startOffset:startOffset endOffset:endOffset]; if (data == nil || data.length != chunkSize) { [self.delegate videoUploader:self didFailWithError: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown + [FBSDKError errorWithDomain:FBSDKGamingVideoUploadErrorDomain + code:0 message:[NSString stringWithFormat:@"Fail to get video chunk with start offset: %lu, end offset : %lu.", (unsigned long)startOffset, @@ -139,10 +155,10 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona contentType:@""]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:self->_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 : self->_uploadSessionID, - FBSDK_SHARE_VIDEO_FILE_CHUNK : dataAttachment, + FBSDK_GAMING_VIDEO_UPLOAD_PHASE : FBSDK_GAMING_VIDEO_UPLOAD_PHASE_TRANSFER, + FBSDK_GAMING_VIDEO_START_OFFSET : offsetDictionary[FBSDK_GAMING_VIDEO_START_OFFSET], + FBSDK_GAMING_VIDEO_UPLOAD_SESSION_ID : self->_uploadSessionID, + FBSDK_GAMING_VIDEO_FILE_CHUNK : dataAttachment, } HTTPMethod:@"POST"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *innerError) { @@ -163,13 +179,13 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona - (void)_postFinishRequest { - NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; + NSMutableDictionary *parameters = [NSMutableDictionary new]; [FBSDKTypeUtility dictionary:parameters - setObject:FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH - forKey:FBSDK_SHARE_VIDEO_UPLOAD_PHASE]; + setObject:FBSDK_GAMING_VIDEO_UPLOAD_PHASE_FINISH + forKey:FBSDK_GAMING_VIDEO_UPLOAD_PHASE]; [FBSDKTypeUtility dictionary:parameters setObject:_uploadSessionID - forKey:FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID]; + forKey:FBSDK_GAMING_VIDEO_UPLOAD_SESSION_ID]; [parameters addEntriesFromDictionary:self.parameters]; [[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath parameters:parameters @@ -178,17 +194,17 @@ - (void)_postFinishRequest [self.delegate videoUploader:self didFailWithError:error]; } else { result = [FBSDKTypeUtility dictionaryValue:result]; - if (result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] == nil) { + if (result[FBSDK_GAMING_VIDEO_UPLOAD_SUCCESS] == nil) { [self.delegate videoUploader:self didFailWithError: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown + [FBSDKError errorWithDomain:FBSDKGamingVideoUploadErrorDomain + code:0 message:@"Failed to finish uploading."]]; return; } - NSMutableDictionary *shareResult = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:shareResult setObject:result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] forKey:FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS]; - [FBSDKTypeUtility dictionary:shareResult setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; - [FBSDKTypeUtility dictionary:shareResult setObject:self->_videoID forKey:FBSDK_SHARE_VIDEO_ID]; + NSMutableDictionary *shareResult = [NSMutableDictionary new]; + [FBSDKTypeUtility dictionary:shareResult setObject:result[FBSDK_GAMING_VIDEO_UPLOAD_SUCCESS] forKey:FBSDK_GAMING_VIDEO_UPLOAD_SUCCESS]; + [FBSDKTypeUtility dictionary:shareResult setObject:FBSDK_GAMING_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_GAMING_RESULT_COMPLETION_GESTURE_KEY]; + [FBSDKTypeUtility dictionary:shareResult setObject:self->_videoID forKey:FBSDK_GAMING_VIDEO_ID]; [self.delegate videoUploader:self didCompleteWithResults:shareResult]; } }]; @@ -197,33 +213,33 @@ - (void)_postFinishRequest - (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]]; + NSNumber *startNum = [self.numberFormatter numberFromString:result[FBSDK_GAMING_VIDEO_START_OFFSET]]; + NSNumber *endNum = [self.numberFormatter numberFromString:result[FBSDK_GAMING_VIDEO_END_OFFSET]]; if (startNum == nil || endNum == nil) { [self.delegate videoUploader:self didFailWithError: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown + [FBSDKError errorWithDomain:FBSDKGamingVideoUploadErrorDomain + code:0 message:@"Fail to get valid start_offset or end_offset."]]; return nil; } if ([startNum compare:endNum] == NSOrderedDescending) { [self.delegate videoUploader:self didFailWithError: - [FBSDKError errorWithDomain:FBSDKShareErrorDomain - code:FBSDKShareErrorUnknown + [FBSDKError errorWithDomain:FBSDKGamingVideoUploadErrorDomain + code:0 message:@"Invalid offset: start_offset is greater than end_offset."]]; return nil; } - NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:shareResults setObject:startNum forKey:FBSDK_SHARE_VIDEO_START_OFFSET]; - [FBSDKTypeUtility dictionary:shareResults setObject:endNum forKey:FBSDK_SHARE_VIDEO_END_OFFSET]; + NSMutableDictionary *shareResults = [NSMutableDictionary new]; + [FBSDKTypeUtility dictionary:shareResults setObject:startNum forKey:FBSDK_GAMING_VIDEO_START_OFFSET]; + [FBSDKTypeUtility dictionary:shareResults setObject:endNum forKey:FBSDK_GAMING_VIDEO_END_OFFSET]; return shareResults; } - (NSNumberFormatter *)numberFormatter { if (!_numberFormatter) { - _numberFormatter = [[NSNumberFormatter alloc] init]; + _numberFormatter = [NSNumberFormatter new]; _numberFormatter.numberStyle = NSNumberFormatterDecimalStyle; } return _numberFormatter; diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index 0c068b6485..657b74ba25 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -46,7 +46,6 @@ 8144D8EE1D261D2900C8E4AC /* FBSDKDeviceShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D10A64A1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m */; }; 8144D8EF1D261D2900C8E4AC /* FBSDKShareConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 893774881A3B5B9A00BE2807 /* FBSDKShareConstants.m */; }; 8144D8F11D261D2900C8E4AC /* FBSDKSharePhotoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FC9C6E1A3FA1E00001910E /* FBSDKSharePhotoContent.m */; }; - 8144D8F21D261D2900C8E4AC /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */; }; 8144D8F31D261D2900C8E4AC /* FBSDKShareVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 896DE2111A9E280900195731 /* FBSDKShareVideo.m */; }; 8144D8F41D261D2900C8E4AC /* FBSDKDeviceShareButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D9E16B31CB46E8F00C8B68F /* FBSDKDeviceShareButton.m */; }; 8144D8F61D261D2900C8E4AC /* FBSDKShareVideoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 896DE2191A9E282800195731 /* FBSDKShareVideoContent.m */; }; @@ -66,7 +65,6 @@ 8144D9111D261D2900C8E4AC /* FBSDKDeviceShareViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D10A6491CB3806700F42AC1 /* FBSDKDeviceShareViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9131D261D2900C8E4AC /* FBSDKShareVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = 896DE2101A9E280900195731 /* FBSDKShareVideo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9141D261D2900C8E4AC /* FBSDKShareLinkContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 89CE02E31A3F56470033C9CA /* FBSDKShareLinkContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8144D9151D261D2900C8E4AC /* FBSDKVideoUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */; }; 8144D9161D261D2900C8E4AC /* FBSDKHashtag.h in Headers */ = {isa = PBXBuildFile; fileRef = D5158B5A1C5FD492003E32EE /* FBSDKHashtag.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8174916D1D1C6D79006E09DF /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B63D1D0A49B500962084 /* FBSDKCoreKit.framework */; }; 817491741D1C6D84006E09DF /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B63D1D0A49B500962084 /* FBSDKCoreKit.framework */; }; @@ -85,7 +83,6 @@ 81A07EF31D1A2E6A0041A29C /* FBSDKShareConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 893774881A3B5B9A00BE2807 /* FBSDKShareConstants.m */; }; 81A07EF61D1A2E6A0041A29C /* FBSDKShareUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 891C54571A3BB23F00DF05AF /* FBSDKShareUtility.m */; }; 81A07EF91D1A2E6A0041A29C /* FBSDKShareVideoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 896DE2191A9E282800195731 /* FBSDKShareVideoContent.m */; }; - 81A07EFB1D1A2E6A0041A29C /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */; }; 81A07EFC1D1A2E6A0041A29C /* FBSDKShareDialogMode.m in Sources */ = {isa = PBXBuildFile; fileRef = DB38B6821AAF668100099656 /* FBSDKShareDialogMode.m */; }; 81A07EFD1D1A2E6A0041A29C /* FBSDKLikeActionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D05A7E1AA0E0D300609300 /* FBSDKLikeActionController.m */; }; 81A07EFE1D1A2E6A0041A29C /* FBSDKShareMediaContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A419D91C922A2A006E7767 /* FBSDKShareMediaContent.m */; }; @@ -110,7 +107,6 @@ 81A07F1E1D1A2E6A0041A29C /* FBSDKAppGroupContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 89F203AD1AAA45BA0053499E /* FBSDKAppGroupContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81A07F1F1D1A2E6A0041A29C /* FBSDKLikeBoxView.h in Headers */ = {isa = PBXBuildFile; fileRef = 89688B391AA62BD800A98519 /* FBSDKLikeBoxView.h */; }; 81A07F201D1A2E6A0041A29C /* FBSDKShareUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 891C54561A3BB23F00DF05AF /* FBSDKShareUtility.h */; }; - 81A07F221D1A2E6A0041A29C /* FBSDKVideoUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */; }; 81A07F231D1A2E6A0041A29C /* FBSDKShareLinkContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 89CE02E31A3F56470033C9CA /* FBSDKShareLinkContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81A07F251D1A2E6A0041A29C /* FBSDKLikeBoxBorderView.h in Headers */ = {isa = PBXBuildFile; fileRef = 89688B401AA62C4100A98519 /* FBSDKLikeBoxBorderView.h */; }; 81A07F271D1A2E6A0041A29C /* FBSDKLikeActionControllerCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 89CE85E31AA4D1940030C6FA /* FBSDKLikeActionControllerCache.h */; }; @@ -190,9 +186,7 @@ 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 */; }; 939000641EB80C1A00250D4C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 939000631EB80C1A00250D4C /* CoreGraphics.framework */; }; - 93AECB911BB4B93D001AC1C4 /* FBSDKVideoUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */; }; 9D10A64B1CB3806700F42AC1 /* FBSDKDeviceShareViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D10A6491CB3806700F42AC1 /* FBSDKDeviceShareViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D10A64C1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D10A64A1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m */; }; 9D2D999F1BC4538300929E76 /* FBSDKShareKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D46C5F51A11E5D800A0DDB6 /* FBSDKShareKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -217,8 +211,6 @@ 9D2DE4271CA34ADC0072CF7E /* FBSDKHashtag.h in Headers */ = {isa = PBXBuildFile; fileRef = D5158B5A1C5FD492003E32EE /* FBSDKHashtag.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; - 9D9B1EB61BF1AF0000FD3175 /* FBSDKVideoUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */; }; - 9D9B1EB71BF1AF0300FD3175 /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */; }; 9D9E16B41CB46E8F00C8B68F /* FBSDKDeviceShareButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9E16B21CB46E8F00C8B68F /* FBSDKDeviceShareButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D9E16B51CB46E8F00C8B68F /* FBSDKDeviceShareButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D9E16B31CB46E8F00C8B68F /* FBSDKDeviceShareButton.m */; }; 9DE155621C161B5F005FCF5C /* FBSDKShareDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 8904148A1A648DAC00617215 /* FBSDKShareDefines.h */; }; @@ -506,8 +498,6 @@ 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; }; 939000631EB80C1A00250D4C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.2.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; 9D10A6491CB3806700F42AC1 /* FBSDKDeviceShareViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKDeviceShareViewController.h; sourceTree = ""; }; @@ -780,8 +770,6 @@ 890414791A6481AB00617215 /* FBSDKShareKit+Internal.h */, 891C54561A3BB23F00DF05AF /* FBSDKShareUtility.h */, 891C54571A3BB23F00DF05AF /* FBSDKShareUtility.m */, - 9382B78D1BB3A54000E4B24F /* FBSDKVideoUploader.h */, - 9382B78F1BB3A5AD00E4B24F /* FBSDKVideoUploader.m */, ); path = Internal; sourceTree = ""; @@ -947,7 +935,6 @@ 8144D9111D261D2900C8E4AC /* FBSDKDeviceShareViewController.h in Headers */, 8144D9131D261D2900C8E4AC /* FBSDKShareVideo.h in Headers */, 8144D9141D261D2900C8E4AC /* FBSDKShareLinkContent.h in Headers */, - 8144D9151D261D2900C8E4AC /* FBSDKVideoUploader.h in Headers */, 8144D9161D261D2900C8E4AC /* FBSDKHashtag.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -973,7 +960,6 @@ 81A07F1E1D1A2E6A0041A29C /* FBSDKAppGroupContent.h in Headers */, 81A07F1F1D1A2E6A0041A29C /* FBSDKLikeBoxView.h in Headers */, 81A07F201D1A2E6A0041A29C /* FBSDKShareUtility.h in Headers */, - 81A07F221D1A2E6A0041A29C /* FBSDKVideoUploader.h in Headers */, 81A07F231D1A2E6A0041A29C /* FBSDKShareLinkContent.h in Headers */, A49C0F001E54E6E400157726 /* FBSDKShareCameraEffectContent.h in Headers */, 81A07F251D1A2E6A0041A29C /* FBSDKLikeBoxBorderView.h in Headers */, @@ -1026,7 +1012,6 @@ 9D10A64B1CB3806700F42AC1 /* FBSDKDeviceShareViewController.h in Headers */, 9D2D99B71BC4545200929E76 /* FBSDKShareVideo.h in Headers */, 9D2D99B01BC4541200929E76 /* FBSDKShareLinkContent.h in Headers */, - 9D9B1EB61BF1AF0000FD3175 /* FBSDKVideoUploader.h in Headers */, 9D2DE4271CA34ADC0072CF7E /* FBSDKHashtag.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1053,7 +1038,6 @@ 89F203AF1AAA45BA0053499E /* FBSDKAppGroupContent.h in Headers */, 89688B3B1AA62BD800A98519 /* FBSDKLikeBoxView.h in Headers */, 891C54581A3BB23F00DF05AF /* FBSDKShareUtility.h in Headers */, - 93AECB911BB4B93D001AC1C4 /* FBSDKVideoUploader.h in Headers */, 89CE02E51A3F56470033C9CA /* FBSDKShareLinkContent.h in Headers */, B38A44BA20BC71E800DDE80D /* FBSDKSharingScheme.h in Headers */, A49C0EFF1E54E6E400157726 /* FBSDKShareCameraEffectContent.h in Headers */, @@ -1406,7 +1390,6 @@ 8144D8EE1D261D2900C8E4AC /* FBSDKDeviceShareViewController.m in Sources */, 8144D8EF1D261D2900C8E4AC /* FBSDKShareConstants.m in Sources */, 8144D8F11D261D2900C8E4AC /* FBSDKSharePhotoContent.m in Sources */, - 8144D8F21D261D2900C8E4AC /* FBSDKVideoUploader.m in Sources */, 8144D8F31D261D2900C8E4AC /* FBSDKShareVideo.m in Sources */, 8144D8F41D261D2900C8E4AC /* FBSDKDeviceShareButton.m in Sources */, 8144D8F61D261D2900C8E4AC /* FBSDKShareVideoContent.m in Sources */, @@ -1443,7 +1426,6 @@ 81A07EF61D1A2E6A0041A29C /* FBSDKShareUtility.m in Sources */, A49C0F121E55098400157726 /* FBSDKCameraEffectArguments.m in Sources */, 81A07EF91D1A2E6A0041A29C /* FBSDKShareVideoContent.m in Sources */, - 81A07EFB1D1A2E6A0041A29C /* FBSDKVideoUploader.m in Sources */, 81A07EFC1D1A2E6A0041A29C /* FBSDKShareDialogMode.m in Sources */, 81A07EFD1D1A2E6A0041A29C /* FBSDKLikeActionController.m in Sources */, 81A07EFE1D1A2E6A0041A29C /* FBSDKShareMediaContent.m in Sources */, @@ -1465,7 +1447,6 @@ 9D10A64C1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m in Sources */, 9D2D99AC1BC453FC00929E76 /* FBSDKShareConstants.m in Sources */, 9D2D99B61BC4544C00929E76 /* FBSDKSharePhotoContent.m in Sources */, - 9D9B1EB71BF1AF0300FD3175 /* FBSDKVideoUploader.m in Sources */, 9D2D99B81BC4545600929E76 /* FBSDKShareVideo.m in Sources */, 9D9E16B51CB46E8F00C8B68F /* FBSDKDeviceShareButton.m in Sources */, 9D2D99BA1BC4546100929E76 /* FBSDKShareVideoContent.m in Sources */, @@ -1502,7 +1483,6 @@ 891C54591A3BB23F00DF05AF /* FBSDKShareUtility.m in Sources */, A49C0F111E55098400157726 /* FBSDKCameraEffectArguments.m in Sources */, 896DE21B1A9E282800195731 /* FBSDKShareVideoContent.m in Sources */, - 9382B7901BB3A5AD00E4B24F /* FBSDKVideoUploader.m in Sources */, DB38B6831AAF668100099656 /* FBSDKShareDialogMode.m in Sources */, 89D05A801AA0E0D300609300 /* FBSDKLikeActionController.m in Sources */, 03A419DB1C922A2A006E7767 /* FBSDKShareMediaContent.m in Sources */, diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h index d3d8565e4a..3c4eda4d0b 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h @@ -28,16 +28,5 @@ #define FBSDK_SHARE_RESULT_DID_COMPLETE_KEY @"didComplete" #define FBSDK_SHARE_RESULT_PHOTO_IDS_KEY @"photo_ids" #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 54ba0a46fc..76eba84815 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h @@ -21,4 +21,3 @@ #import "FBSDKShareDefines.h" #import "FBSDKShareKit.h" #import "FBSDKShareUtility.h" -#import "FBSDKVideoUploader.h" From c28a7decfa77fe5d607fade6870cbbe877ca6447 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Thu, 24 Sep 2020 16:14:43 -0700 Subject: [PATCH 006/227] Consolidate [FBSDKSettings getAdvertisingTrackingStatus] and [FBSDKAppEventsUtility advertisingTrackingStatus] Summary: Since LAT is always on iOS 14, [FBSDKAppEventsUtility advertisingTrackingStatus] will always return FBSDKAdvertisingTrackingDisallowed ``` + (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus { static dispatch_once_t fetchAdvertisingTrackingStatusOnce; static FBSDKAdvertisingTrackingStatus status; dispatch_once(&fetchAdvertisingTrackingStatusOnce, ^{ status = FBSDKAdvertisingTrackingUnspecified; Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); if ([ASIdentifierManagerClass class]) { ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager]; if (manager) { status = manager.advertisingTrackingEnabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed; } } }); return status; } ``` We should use [FBSDKSettings getAdvertisingTrackingStatus] instead: ``` + (FBSDKAdvertisingTrackingStatus)getAdvertisingTrackingStatus { if (available(iOS 14.0, *)) { if (g_advertiserTrackingStatus == nil) { g_advertiserTrackingStatus = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsAdvertisingTrackingStatus] ?: @([FBSDKAppEventsConfigurationManager cachedAppEventsConfiguration].defaultATEStatus); } return g_advertiserTrackingStatus.unsignedIntegerValue; } else { return [FBSDKAppEventsUtility advertisingTrackingStatus]; } } ``` Reviewed By: dreamolight Differential Revision: D23915342 fbshipit-source-id: b32bedcdb36c20740dd0375928aeb7c77de42f6d --- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 2 +- .../Internal/AAM/FBSDKMetadataIndexer.m | 2 +- .../Internal/FBSDKAppEventsUtility.h | 1 - .../Internal/FBSDKAppEventsUtility.m | 19 ------------------- FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m | 18 +++++++++++++++++- .../Internal/FBSDKSettingsTests.m | 1 - .../Internal/Helpers/FBSDKTestCase.h | 2 +- .../Internal/Helpers/FBSDKTestCase.m | 2 +- 8 files changed, 21 insertions(+), 26 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index 8616cce40f..ca27e40c2c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -1510,7 +1510,7 @@ + (FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(FBSD // 3) if we have a user session token, then no need to send attribution ID / advertiser ID back as the udid parameter // 4) otherwise, send back the udid parameter. - if ([FBSDKAppEventsUtility advertisingTrackingStatus] == FBSDKAdvertisingTrackingDisallowed || FBSDKSettings.shouldLimitEventAndDataUsage) { + if ([FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingDisallowed || FBSDKSettings.shouldLimitEventAndDataUsage) { return nil; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m index d4298aa7ed..529c1d897e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m @@ -53,7 +53,7 @@ + (void)initialize + (void)enable { @try { - if (FBSDKAdvertisingTrackingAllowed != [FBSDKAppEventsUtility advertisingTrackingStatus]) { + if (FBSDKAdvertisingTrackingAllowed != [FBSDKSettings getAdvertisingTrackingStatus]) { return; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h index e257216113..a52202ed13 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h @@ -44,7 +44,6 @@ NS_SWIFT_NAME(AppEventsUtility) + (instancetype)new NS_UNAVAILABLE; @property (class, nonatomic, copy, readonly) NSString *advertiserID; -@property (class, nonatomic, assign, readonly) FBSDKAdvertisingTrackingStatus advertisingTrackingStatus; @property (class, nonatomic, assign, readonly) long unixTimeNow; @property (class, nonatomic, assign, readonly) BOOL isDebugBuild; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index a4c01edeb5..eb5f175c25 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -166,25 +166,6 @@ + (NSString *)advertiserID return result; } -+ (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus -{ - static dispatch_once_t fetchAdvertisingTrackingStatusOnce; - static FBSDKAdvertisingTrackingStatus status; - - dispatch_once(&fetchAdvertisingTrackingStatusOnce, ^{ - status = FBSDKAdvertisingTrackingUnspecified; - Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); - if ([ASIdentifierManagerClass class]) { - ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager]; - if (manager) { - status = manager.advertisingTrackingEnabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed; - } - } - }); - - return status; -} - + (BOOL)isStandardEvent:(nullable NSString *)event { if (!event) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m index 7f0ac6dfb6..cc264139e8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m @@ -18,6 +18,8 @@ #import "FBSDKSettings+Internal.h" +#import + #import "FBSDKAccessTokenCache.h" #import "FBSDKAccessTokenExpirer.h" #import "FBSDKAppEvents+Internal.h" @@ -223,7 +225,21 @@ + (FBSDKAdvertisingTrackingStatus)getAdvertisingTrackingStatus } return g_advertiserTrackingStatus.unsignedIntegerValue; } else { - return [FBSDKAppEventsUtility advertisingTrackingStatus]; + static dispatch_once_t fetchAdvertisingTrackingStatusOnce; + static FBSDKAdvertisingTrackingStatus status; + + dispatch_once(&fetchAdvertisingTrackingStatusOnce, ^{ + status = FBSDKAdvertisingTrackingUnspecified; + Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); + if ([ASIdentifierManagerClass class]) { + ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager]; + if (manager) { + status = manager.advertisingTrackingEnabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed; + } + } + }); + + return status; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m index 65df3e37be..79fc12770e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m @@ -74,7 +74,6 @@ - (void)setUp userDefaultsSpy = [UserDefaultsSpy new]; [self stubUserDefaultsWith:userDefaultsSpy]; [self stubLoggingIfUserSettingsChanged]; - [self stubAdvertisingTrackingStatusWith:FBSDKAdvertisingTrackingAllowed]; } - (void)tearDown diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 8398d1e3b4..40f9360fab 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -175,7 +175,7 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKSettings.clientToken` with the provided token string - (void)stubClientTokenWith:(nullable NSString *)token; -/// Stubs `FBSDKAppEventsUtility.advertisingTrackingStatus` with the provided value +/// Stubs `FBSDKSettings.getAdvertisingTrackingStatus` with the provided value - (void)stubAdvertisingTrackingStatusWith:(FBSDKAdvertisingTrackingStatus)trackingStatus; /// Stubs `FBSDKSKAdNetworkReporter._loadConfigurationWithBlock` diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 5067c480e2..4af9f70820 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -350,7 +350,7 @@ - (void)stubAppEventsUtilityShouldDropAppEventWith:(BOOL)shouldDropEvent - (void)stubAdvertisingTrackingStatusWith:(FBSDKAdvertisingTrackingStatus)trackingStatus { - OCMStub(ClassMethod([_appEventsUtilityClassMock advertisingTrackingStatus])).andReturn(trackingStatus); + OCMStub(ClassMethod([_settingsClassMock getAdvertisingTrackingStatus])).andReturn(trackingStatus); } - (void)stubLoadingAdNetworkReporterConfiguration From 86c35cf91341e6da97ed7b3820981ecd9b337977 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Thu, 24 Sep 2020 18:04:55 -0700 Subject: [PATCH 007/227] Respect shouldDropAppEvent() when initializing Summary: We should only disable AAM when we could not collect app events. Reviewed By: KylinChang Differential Revision: D23917647 fbshipit-source-id: 8f550f9ca61ac40fdbc1d002d5002d03d625ec53 --- .../AppEvents/Internal/AAM/FBSDKMetadataIndexer.m | 2 +- .../AppEvents/Internal/FBSDKAppEventsUtility.m | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m index 529c1d897e..db11c899d8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m @@ -53,7 +53,7 @@ + (void)initialize + (void)enable { @try { - if (FBSDKAdvertisingTrackingAllowed != [FBSDKSettings getAdvertisingTrackingStatus]) { + if ([FBSDKAppEventsUtility shouldDropAppEvent]) { return; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index eb5f175c25..0b84dccb51 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -88,11 +88,10 @@ + (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventC BOOL advertiserTrackingEnabled = [FBSDKSettings isAdvertiserTrackingEnabled]; [FBSDKTypeUtility dictionary:parameters setObject:@(advertiserTrackingEnabled).stringValue forKey:@"advertiser_tracking_enabled"]; - if (advertiserTrackingEnabled) { - NSString *userData = [FBSDKAppEvents getUserData]; - if (userData) { - [FBSDKTypeUtility dictionary:parameters setObject:userData forKey:@"ud"]; - } + + NSString *userData = [FBSDKAppEvents getUserData]; + if (userData) { + [FBSDKTypeUtility dictionary:parameters setObject:userData forKey:@"ud"]; } [FBSDKTypeUtility dictionary:parameters setObject:@(!FBSDKSettings.limitEventAndDataUsage).stringValue forKey:@"application_tracking_enabled"]; From 0dd6f3fdfab158ab328eba5ad00a600fa953e15b Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Thu, 24 Sep 2020 18:22:30 -0700 Subject: [PATCH 008/227] Update Changelog for fixing AAM / MAM Summary: Same as the title Reviewed By: YOUDAN Differential Revision: D23922764 fbshipit-source-id: 24f532b74746a4a85ddfe048db8519db2726e6b6 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e459f40138..7dfc5d55cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - #1447 - Login form automatically closing when SDK is not initialized on startup - #1478 - Minimum iOS deployment target is now 9.0 - #1485 - StoreKit is now added as a weak framework for CocoaPods +- Bug fix for Advanced Matching, which was not working on iOS 14 [2020-09-22](https://github.com/facebook/facebook-ios-sdk/releases/tag/v8.0.0) | [Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v7.1.1...v8.0.0) From 36bc1845cb7c1a829ed218d0fe2db8e38bb9734e Mon Sep 17 00:00:00 2001 From: Zilin Zhang Date: Fri, 25 Sep 2020 13:02:37 -0700 Subject: [PATCH 009/227] Fix the issue of ATE status Summary: as title Reviewed By: dreamolight Differential Revision: D23937943 fbshipit-source-id: be7f61395d7a594cf2d04264493ce90b8ab23cfd --- .../FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index 0b84dccb51..b0393d8b30 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -86,8 +86,10 @@ + (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventC [FBSDKTypeUtility dictionary:parameters setObject:[FBSDKBasicUtility anonymousID] forKey:FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY]; - BOOL advertiserTrackingEnabled = [FBSDKSettings isAdvertiserTrackingEnabled]; - [FBSDKTypeUtility dictionary:parameters setObject:@(advertiserTrackingEnabled).stringValue forKey:@"advertiser_tracking_enabled"]; + FBSDKAdvertisingTrackingStatus advertisingTrackingStatus = [FBSDKSettings getAdvertisingTrackingStatus]; + if (advertisingTrackingStatus != FBSDKAdvertisingTrackingUnspecified) { + [FBSDKTypeUtility dictionary:parameters setObject:@([FBSDKSettings isAdvertiserTrackingEnabled]).stringValue forKey:@"advertiser_tracking_enabled"]; + } NSString *userData = [FBSDKAppEvents getUserData]; if (userData) { From 1bb5d46e77a31cd84cc5421067c386ae7411aae6 Mon Sep 17 00:00:00 2001 From: Zilin Zhang Date: Sun, 27 Sep 2020 12:33:45 -0700 Subject: [PATCH 010/227] Remove dynamic linking of ASIdentifierManager Summary: As title Reviewed By: Oliverccccct, dreamolight Differential Revision: D23947476 fbshipit-source-id: 383c574b2966e0870bb1aba2a7b52d12cf9ad50b --- FBSDKCoreKit.podspec | 2 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m | 17 ++--------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index d48398c194..400c6b0b23 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -26,7 +26,7 @@ Pod::Spec.new do |s| tag: "v#{s.version}" } - s.ios.weak_frameworks = 'Accelerate', 'Accounts', 'Social', 'Security', 'StoreKit', 'QuartzCore', 'CoreGraphics', 'UIKit', 'Foundation', 'AudioToolbox' + s.ios.weak_frameworks = 'Accelerate', 'Accounts', 'AdSupport', 'Social', 'Security', 'StoreKit', 'QuartzCore', 'CoreGraphics', 'UIKit', 'Foundation', 'AudioToolbox' s.tvos.weak_frameworks = 'CoreLocation', 'Security', 'QuartzCore', 'CoreGraphics', 'UIKit', 'Foundation', 'AudioToolbox' # This excludes `FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/` folder, as that folder includes only `no-arc` files. diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m index cc264139e8..7b26d7d386 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m @@ -225,21 +225,8 @@ + (FBSDKAdvertisingTrackingStatus)getAdvertisingTrackingStatus } return g_advertiserTrackingStatus.unsignedIntegerValue; } else { - static dispatch_once_t fetchAdvertisingTrackingStatusOnce; - static FBSDKAdvertisingTrackingStatus status; - - dispatch_once(&fetchAdvertisingTrackingStatusOnce, ^{ - status = FBSDKAdvertisingTrackingUnspecified; - Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); - if ([ASIdentifierManagerClass class]) { - ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager]; - if (manager) { - status = manager.advertisingTrackingEnabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed; - } - } - }); - - return status; + // @lint-ignore CLANGTIDY + return ASIdentifierManager.sharedManager.advertisingTrackingEnabled ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed; } } From 0c788fa3fe006d16d4a2b0891e1a58ad5159eafd Mon Sep 17 00:00:00 2001 From: Zilin Zhang Date: Sun, 27 Sep 2020 18:28:25 -0700 Subject: [PATCH 011/227] Fix build issue for AdSupport (#1500) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1500 As title Reviewed By: dreamolight Differential Revision: D23955816 fbshipit-source-id: ff00a38c026cd1073a54859fad0dd260bcc2e502 --- FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 4226b310a3..56be80ee27 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -1018,6 +1018,8 @@ F9A06DD42510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; F9A06DD52510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; F9A06DD62510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */; }; + F9A18071252150610062E634 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9A18062252150610062E634 /* AdSupport.framework */; }; + F9A180732521506C0062E634 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9A180722521506C0062E634 /* AdSupport.framework */; }; F9A80C9E237D02860019D7E0 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9A80C9D237D02860019D7E0 /* Accelerate.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; F9CBE51124E085CD0097B442 /* FBSDKSKAdNetworkReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = F9CBE50F24E085CD0097B442 /* FBSDKSKAdNetworkReporter.h */; }; F9CBE51224E085CD0097B442 /* FBSDKSKAdNetworkReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = F9CBE51024E085CD0097B442 /* FBSDKSKAdNetworkReporter.m */; }; @@ -1638,6 +1640,8 @@ F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfiguration.m; sourceTree = ""; }; F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfigurationManager.h; sourceTree = ""; }; F9A06DCE2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationManager.m; sourceTree = ""; }; + F9A18062252150610062E634 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/AdSupport.framework; sourceTree = DEVELOPER_DIR; }; + F9A180722521506C0062E634 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; F9A80C9D237D02860019D7E0 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; F9CBE50F24E085CD0097B442 /* FBSDKSKAdNetworkReporter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkReporter.h; sourceTree = ""; }; F9CBE51024E085CD0097B442 /* FBSDKSKAdNetworkReporter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkReporter.m; sourceTree = ""; }; @@ -1662,6 +1666,7 @@ buildActionMask = 2147483647; files = ( F9FFE01F2252D66E007B2346 /* libz.tbd in Frameworks */, + F9A18071252150610062E634 /* AdSupport.framework in Frameworks */, 4AF47D131F424A8700A57A67 /* CoreImage.framework in Frameworks */, 8131FB461D261DED000350FF /* CoreGraphics.framework in Frameworks */, 8131FB4A1D261E06000350FF /* UIKit.framework in Frameworks */, @@ -1673,6 +1678,7 @@ buildActionMask = 2147483647; files = ( F9A80C9E237D02860019D7E0 /* Accelerate.framework in Frameworks */, + F9A180732521506C0062E634 /* AdSupport.framework in Frameworks */, C52C02ED2315039400F30E2A /* WebKit.framework in Frameworks */, F9FFE01D2252D666007B2346 /* libz.tbd in Frameworks */, F96ADE7A21E6ABB400F6043F /* StoreKit.framework in Frameworks */, @@ -1997,6 +2003,8 @@ 893F44A31A644536001DB0B6 /* Frameworks */ = { isa = PBXGroup; children = ( + F9A18062252150610062E634 /* AdSupport.framework */, + F9A180722521506C0062E634 /* AdSupport.framework */, F9A80C9D237D02860019D7E0 /* Accelerate.framework */, C52C02DF2315039400F30E2A /* WebKit.framework */, F9FFE01C2252D665007B2346 /* libz.tbd */, From 7622c7ba1cace656532ff1fb1c0c1ca3e577360f Mon Sep 17 00:00:00 2001 From: Zilin Zhang Date: Sun, 27 Sep 2020 18:53:00 -0700 Subject: [PATCH 012/227] Unit Test for ATE in event payload Summary: as title Reviewed By: dreamolight Differential Revision: D23955758 fbshipit-source-id: acadb629097c731b4dacb8c4f1df755697414fd2 --- .../Internal/FBSDKAppEventsConfiguration.m | 11 ++++ .../AppEvents/FBSDKAppEventsUtilityTests.m | 54 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m index 383ce13123..9a58434a62 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsConfiguration.m @@ -102,4 +102,15 @@ - (instancetype)copyWithZone:(NSZone *)zone return self; } +#pragma mark - Testability + +#if DEBUG + +- (void)setDefaultATEStatus:(FBSDKAdvertisingTrackingStatus)status +{ + _defaultATEStatus = status; +} + +#endif + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 59c4d76dc5..3f3a2af5ca 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -16,6 +16,8 @@ // 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. +// @lint-ignore-every CLANGTIDY +#import #import #import #import @@ -23,6 +25,15 @@ #import "FBSDKCoreKit+Internal.h" static NSString *const FBSDKSettingsInstallTimestamp = @"com.facebook.sdk:FBSDKSettingsInstallTimestamp"; +static NSString *const FBSDKSettingsAdvertisingTrackingStatus = @"com.facebook.sdk:FBSDKSettingsAdvertisingTrackingStatus"; + +@interface FBSDKSettings () ++ (void)resetAdvertiserTrackingStatusCache; +@end + +@interface FBSDKAppEventsConfiguration () +- (void)setDefaultATEStatus:(FBSDKAdvertisingTrackingStatus)status; +@end @interface FBSDKAppEventsUtilityTests : XCTestCase @@ -196,6 +207,9 @@ - (void)testGetAdvertiserIDOniOS14WithCollectionEnabled OCMStub([mockAppEventsConfiguration advertiserIDCollectionEnabled]).andReturn(YES); id mockAppEventsConfigurationManager = OCMClassMock([FBSDKAppEventsConfigurationManager class]); OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); + id mockASIdentifierManager = OCMClassMock([ASIdentifierManager class]); + OCMStub([mockASIdentifierManager advertisingIdentifier]).andReturn([NSUUID UUID]); + OCMStub([mockASIdentifierManager sharedManager]).andReturn(mockASIdentifierManager); if (@available(iOS 14.0, *)) { XCTAssertNotNil( @@ -214,6 +228,10 @@ - (void)testGetAdvertiserIDOniOS14WithCollectionDisabled OCMStub([mockAppEventsConfiguration advertiserIDCollectionEnabled]).andReturn(NO); id mockAppEventsConfigurationManager = OCMClassMock([FBSDKAppEventsConfigurationManager class]); OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); + OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(mockAppEventsConfiguration); + id mockASIdentifierManager = OCMClassMock([ASIdentifierManager class]); + OCMStub([mockASIdentifierManager advertisingIdentifier]).andReturn([NSUUID UUID]); + OCMStub([mockASIdentifierManager sharedManager]).andReturn(mockASIdentifierManager); if (@available(iOS 14.0, *)) { XCTAssertNil([FBSDKAppEventsUtility advertiserID]); @@ -237,6 +255,42 @@ - (void)testShouldDropAppEvent } } +- (void)testAdvertiserTrackingEnabledInAppEventPayload +{ + FBSDKAppEventsConfiguration *configuration = [[FBSDKAppEventsConfiguration alloc] initWithJSON:@{}]; + id mockAppEventsConfigurationManager = OCMClassMock([FBSDKAppEventsConfigurationManager class]); + OCMStub([mockAppEventsConfigurationManager cachedAppEventsConfiguration]).andReturn(configuration); + NSArray *statusList = @[@(FBSDKAdvertisingTrackingAllowed), @(FBSDKAdvertisingTrackingDisallowed), @(FBSDKAdvertisingTrackingUnspecified)]; + for (NSNumber *defaultATEStatus in statusList) { + [configuration setDefaultATEStatus:defaultATEStatus.unsignedIntegerValue]; + for (NSNumber *status in statusList) { + [FBSDKSettings resetAdvertiserTrackingStatusCache]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:FBSDKSettingsAdvertisingTrackingStatus]; + if ([status unsignedIntegerValue] != FBSDKAdvertisingTrackingUnspecified) { + [FBSDKSettings setAdvertiserTrackingStatus:[status unsignedIntegerValue]]; + } + NSDictionary *dict = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:@"event" + shouldAccessAdvertisingID:YES]; + if (@available(iOS 14.0, *)) { + // If status is unspecified, ATE will be defaultATEStatus + if ([status unsignedIntegerValue] == FBSDKAdvertisingTrackingUnspecified) { + if ([defaultATEStatus unsignedIntegerValue] == FBSDKAdvertisingTrackingUnspecified) { + XCTAssertNil(dict[@"advertiser_tracking_enabled"], @"advertiser_tracking_enabled should not be attached to event payload if ATE is unspecified"); + } else { + BOOL advertiserTrackingEnabled = defaultATEStatus.unsignedIntegerValue == FBSDKAdvertisingTrackingAllowed; + XCTAssertTrue([@(advertiserTrackingEnabled).stringValue isEqualToString:[FBSDKTypeUtility dictionary:dict objectForKey:@"advertiser_tracking_enabled" ofType:NSString.class]], @"advertiser_tracking_enabled should be default value when ATE is not set"); + } + } else { + BOOL advertiserTrackingEnabled = status.unsignedIntegerValue == FBSDKAdvertisingTrackingAllowed; + XCTAssertTrue([@(advertiserTrackingEnabled).stringValue isEqualToString:[FBSDKTypeUtility dictionary:dict objectForKey:@"advertiser_tracking_enabled" ofType:NSString.class]], @"advertiser_tracking_enabled should be equal to ATE explicitly setted via setAdvertiserTrackingStatus"); + } + } else { + XCTAssertNotNil(dict[@"advertiser_tracking_enabled"]); + } + } + } +} + - (void)testIsSensitiveUserData { NSString *text = @"test@sample.com"; From f868801dc8304dd9b7f377eb2c0e6f19e08d0639 Mon Sep 17 00:00:00 2001 From: Zilin Zhang Date: Mon, 28 Sep 2020 07:45:58 -0700 Subject: [PATCH 013/227] More tests Summary: As title Reviewed By: dreamolight Differential Revision: D23956881 fbshipit-source-id: f2150cb5bb15ed96f07324f4a83f548369365081 --- .../AppEvents/FBSDKAppEventsUtilityTests.m | 24 +++++++++++++++++++ .../Internal/FBSDKSettingsTests.m | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 3f3a2af5ca..afc5d3b90b 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -291,6 +291,30 @@ - (void)testAdvertiserTrackingEnabledInAppEventPayload } } +- (void)testDropAppEvent +{ + id mockAppEventsState = OCMClassMock([FBSDKAppEventsState class]); + OCMStub([mockAppEventsState alloc]).andReturn(mockAppEventsState); + OCMStub([mockAppEventsState initWithToken:OCMArg.any appID:OCMArg.any]).andReturn(mockAppEventsState); + [FBSDKSettings setAppID:@"123"]; + + OCMStub([_mockAppEventsUtility shouldDropAppEvent]).andReturn(YES); + [FBSDKAppEvents logEvent:@"event"]; + OCMReject([mockAppEventsState addEvent:OCMArg.any isImplicit:NO]); +} + +- (void)testSendAppEvent +{ + id mockAppEventsState = OCMClassMock([FBSDKAppEventsState class]); + OCMStub([mockAppEventsState alloc]).andReturn(mockAppEventsState); + OCMStub([mockAppEventsState initWithToken:OCMArg.any appID:OCMArg.any]).andReturn(mockAppEventsState); + [FBSDKSettings setAppID:@"123"]; + + OCMStub([_mockAppEventsUtility shouldDropAppEvent]).andReturn(NO); + [FBSDKAppEvents logEvent:@"event"]; + OCMVerify([mockAppEventsState addEvent:OCMArg.any isImplicit:NO]); +} + - (void)testIsSensitiveUserData { NSString *text = @"test@sample.com"; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m index 79fc12770e..958a63102d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m @@ -1153,14 +1153,14 @@ - (void)testFacebookAdvertiserTrackingStatusDefaultValue - (void)testSettingFacebookAdvertiserTrackingStatus { - [FBSDKSettings setAdvertiserTrackingStatus:FBSDKAdvertisingTrackingAllowed]; - if (@available(iOS 14.0, *)) { + XCTAssertTrue([FBSDKSettings setAdvertiserTrackingEnabled:YES]); XCTAssertTrue( [FBSDKSettings getAdvertisingTrackingStatus] == FBSDKAdvertisingTrackingAllowed, "Should use the explicitly set property" ); } else { + XCTAssertFalse([FBSDKSettings setAdvertiserTrackingEnabled:YES]); XCTAssertNil( userDefaultsSpy.capturedValues[@"FacebookAdvertiserTrackingStatus"], "Should be no-op in iOS13 and below" From 276f51417e88955fa6b0b1df9d73176d1534ab3f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 28 Sep 2020 11:05:09 -0700 Subject: [PATCH 014/227] Update Static Libs for Release Configuration Summary: Updates Release configuration so that static libraries build using Xcode12 include the x86_64 architecture. Reviewed By: dreamolight Differential Revision: D23869085 fbshipit-source-id: 8fb2e861a555c99eeb876dc6daf7e9c7dde43f4a --- Configurations/Configuration/Release.xcconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Configurations/Configuration/Release.xcconfig b/Configurations/Configuration/Release.xcconfig index da37f53eba..1ac7fb4397 100644 --- a/Configurations/Configuration/Release.xcconfig +++ b/Configurations/Configuration/Release.xcconfig @@ -36,3 +36,7 @@ ENABLE_TESTABILITY = YES // MTL MTL_ENABLE_DEBUG_INFO = NO + +// Excluding arm64 in Release builds for simulator allows creation of x86_64 slice +// when building with Xcode12. May need to revisit this as Apple Silicon gains adoption. +EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 From 8ba23b3999ebf76b4d1848ed55666bccc225311d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 28 Sep 2020 11:15:09 -0700 Subject: [PATCH 015/227] Unit Test Hardening (#1502) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1502 Adds stub for avoiding a network call on `loadServerConfigurationWithCompletionBlock`. Reviewed By: KylinChang Differential Revision: D23908807 fbshipit-source-id: 166e5a986c5fdb3e87a8ddd9f7cc0fb950acbafe --- FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj | 4 ++-- .../FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m | 3 +++ .../Internal/AppEvents/FBSDKAppEventsTests.m | 2 ++ .../Internal/AppEvents/FBSDKAppEventsUtilityTests.m | 6 +++++- .../FBSDKServerConfigurationFixtures.h | 0 .../FBSDKServerConfigurationFixtures.m | 0 .../FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h | 6 ++++++ .../FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m | 10 ++++++++++ 8 files changed, 28 insertions(+), 3 deletions(-) rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/{ServerConfiguration => Helpers}/FBSDKServerConfigurationFixtures.h (100%) rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/{ServerConfiguration => Helpers}/FBSDKServerConfigurationFixtures.m (100%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 56be80ee27..e13ce111db 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -2698,6 +2698,8 @@ F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */, F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */, F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */, + F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */, + F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, ); path = Helpers; sourceTree = ""; @@ -2705,8 +2707,6 @@ F4E50151243648A100C99262 /* ServerConfiguration */ = { isa = PBXGroup; children = ( - F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */, - F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */, F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */, F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index 4744e1a16f..c9beddc51c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -24,6 +24,7 @@ #import "AppDelegateObserverFake.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" +#import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "SampleAccessToken.h" #import "UserDefaultsSpy.h" @@ -84,6 +85,8 @@ - (void)setUp [self stubAppEventsSingletonWith:self.appEventsMock]; [self stubLoadingAdNetworkReporterConfiguration]; + + [self stubServerConfigurationFetchingWithConfiguration:FBSDKServerConfigurationFixtures.defaultConfig error:nil]; } - (void)tearDown diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index 76f11ba463..0c577407eb 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -33,6 +33,7 @@ #import "FBSDKGraphRequest+Internal.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" +#import "FBSDKServerConfigurationFixtures.h" #import "FBSDKSettings.h" #import "FBSDKTestCase.h" #import "FBSDKUtility.h" @@ -112,6 +113,7 @@ - (void)setUp [super setUp]; [self stubLoadingAdNetworkReporterConfiguration]; + [self stubServerConfigurationFetchingWithConfiguration:FBSDKServerConfigurationFixtures.defaultConfig error:nil]; _mockEventName = @"fb_mock_event"; _mockPayload = @{@"fb_push_payload" : @{@"campaign" : @"testCampaign"}}; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index afc5d3b90b..c0d528ce8d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -23,6 +23,7 @@ #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKTestCase.h" static NSString *const FBSDKSettingsInstallTimestamp = @"com.facebook.sdk:FBSDKSettingsInstallTimestamp"; static NSString *const FBSDKSettingsAdvertisingTrackingStatus = @"com.facebook.sdk:FBSDKSettingsAdvertisingTrackingStatus"; @@ -35,7 +36,7 @@ @interface FBSDKAppEventsConfiguration () - (void)setDefaultATEStatus:(FBSDKAdvertisingTrackingStatus)status; @end -@interface FBSDKAppEventsUtilityTests : XCTestCase +@interface FBSDKAppEventsUtilityTests : FBSDKTestCase @end @@ -48,6 +49,9 @@ @implementation FBSDKAppEventsUtilityTests - (void)setUp { [super setUp]; + + [self stubServerConfigurationFetchingWithConfiguration:[FBSDKServerConfiguration defaultServerConfigurationForAppID:nil] error:nil]; + _mockAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); [FBSDKAppEvents setUserID:@"test-user-id"]; _mockNSLocale = OCMClassMock([NSLocale class]); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationFixtures.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKServerConfigurationFixtures.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationFixtures.h rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKServerConfigurationFixtures.h diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationFixtures.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKServerConfigurationFixtures.m similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationFixtures.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKServerConfigurationFixtures.m diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 40f9360fab..a9a6b6d3dd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -27,6 +27,7 @@ #import "FBSDKMeasurementEventListener.h" #import "FBSDKProfile+Internal.h" #import "FBSDKServerConfiguration.h" +#import "FBSDKServerConfigurationManager.h" #import "FakeAccessTokenCache.h" NS_ASSUME_NONNULL_BEGIN @@ -133,6 +134,11 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKServerConfigurationManager.cachedServerConfiguration` with a specific configuration - (void)stubCachedServerConfigurationWithServerConfiguration:(FBSDKServerConfiguration *)serverConfiguration; +/// Stubs `FBSDKServerConfiguratinManager.loadServerConfigurationWithCompletionBlock:` with arguments to invoke the completion with. +/// If the completion is nil then this will ignore any arguments passed to it. +- (void)stubServerConfigurationFetchingWithConfiguration:(nullable FBSDKServerConfiguration *)configuration + error:(nullable NSError *)error; + /// Stubs `NSBundle.mainBundle` with the provided NSBundle - (void)stubMainBundleWith:(NSBundle *)bundle; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 4af9f70820..096597c75f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -373,4 +373,14 @@ - (void)stubAppEventsUtilityTokenStringToUseForTokenWith:(NSString *)tokenString OCMStub(ClassMethod([_appEventsUtilityClassMock tokenStringToUseFor:OCMArg.any])).andReturn(tokenString); } +- (void)stubServerConfigurationFetchingWithConfiguration:(nullable FBSDKServerConfiguration *)configuration error:(nullable NSError *)error +{ + OCMStub(ClassMethod([_serverConfigurationManagerClassMock loadServerConfigurationWithCompletionBlock:OCMArg.isNotNil])).andDo(^(NSInvocation *invocation) { + void (^completion)(FBSDKServerConfiguration *serverConfiguration, NSError *error); + [invocation getArgument:&completion atIndex:2]; + completion(configuration, error); + }); + OCMStub(ClassMethod([_serverConfigurationManagerClassMock loadServerConfigurationWithCompletionBlock:OCMArg.isNil])); +} + @end From dfc1cbbeb38487e30588d6b6e33a4e86f8f70ec2 Mon Sep 17 00:00:00 2001 From: Stan Wu Date: Thu, 1 Oct 2020 02:53:56 -0700 Subject: [PATCH 016/227] Fix signal handler for crash reporting (#1507) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1507 When fatal signals arise, we should uninstall our signal handlers of crash reporting and use the previous or default signal handlers instead, so app can crash as expected, or resume from bad state with its own handlers. Reviewed By: tianqibt Differential Revision: D24007602 fbshipit-source-id: 02df46b89d377043468f6eba9fdc90cdd621d0c5 --- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index 154316e1a2..7dcf6a8649 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -48,7 +48,6 @@ static void installSignalsHandler(void); static void uninstallSignalsHandler(void); static void FBSDKSignalHandler(int signal, siginfo_t *signalInfo, void *userContext); -static int signalIndex(int signal); static NSUncaughtExceptionHandler *previousExceptionHandler = NULL; static NSString *mappingTableIdentifier = NULL; @@ -211,8 +210,9 @@ static void uninstallSignalsHandler() } } -static void FBSDKSignalHandler(int signal, siginfo_t *signalInfo, void *userContext) +static void FBSDKSignalHandler(int sig, siginfo_t *signalInfo, void *userContext) { + uninstallSignalsHandler(); NSMutableArray *callStack = [[NSThread callStackSymbols] mutableCopy]; if (callStack) { NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]; @@ -220,27 +220,7 @@ static void FBSDKSignalHandler(int signal, siginfo_t *signalInfo, void *userCont [callStack removeObjectsAtIndexes:indexSet]; } } - [FBSDKCrashHandler saveSignal:signal withCallStack:callStack]; - - int index = signalIndex(signal); - if (index > 0) { - if (previousSignalHandlers[index].sa_handler != SIG_IGN) { - void (*previousSignalHandler)(int, siginfo_t *, void *) = previousSignalHandlers[index].sa_sigaction; - if (previousSignalHandler != NULL) { - previousSignalHandler(signal, signalInfo, userContext); - } - } - } -} - -static int signalIndex(int signal) -{ - for (int i = 0; i < fatalSignalsCount; i++) { - if (signal == fatalSignals[i]) { - return i; - } - } - return -1; + [FBSDKCrashHandler saveSignal:sig withCallStack:callStack]; } #pragma mark - Storage From 7bdf7012fa630ef59556b5b33d85fdece97f59b2 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 5 Oct 2020 11:23:53 -0700 Subject: [PATCH 017/227] Add Localization Resources for Swift Package Manager Summary: Resolves T76251268 Reviewed By: yury-dymov Differential Revision: D23995664 fbshipit-source-id: 3423767af736434538f1a8826aaf52de45e94d2f --- .../FBSDKCoreKit/Internal/FBSDKInternalUtility.m | 15 +++++++++++---- Package.swift | 3 ++- Sources/FBSDKCoreKit_Basics/Resources/af.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ar.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/bn.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/cs.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/da.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/de.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/el.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/en.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/es.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/fi.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/fil.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/fr.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/gu.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/he.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/hi.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/hr.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/hu.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/id.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/it.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ja.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/kn.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ko.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ml.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/mr.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ms.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/nb.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/nl.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/pa.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/pl.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/pt.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ru.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/sk.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/sv.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/ta.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/te.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/th.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/tr.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/vi.lproj | 1 + Sources/FBSDKCoreKit_Basics/Resources/zh.lproj | 1 + .../Resources/zh_Hant_HK.lproj | 1 + .../Resources/zh_Hant_TW.lproj | 1 + 46 files changed, 57 insertions(+), 5 deletions(-) create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/af.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ar.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/bn.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/cs.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/da.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/de.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/el.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/en.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/es.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/fi.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/fil.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/fr.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/gu.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/he.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/hi.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/hr.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/hu.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/id.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/it.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ja.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/kn.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ko.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ml.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/mr.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ms.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/nb.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/nl.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pa.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pl.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pt.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ru.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/sk.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/sv.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ta.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/te.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/th.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/tr.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/vi.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/zh.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj create mode 120000 Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 9f5173901f..85c828d9f6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -89,10 +89,17 @@ + (NSBundle *)bundleForStrings static NSBundle *bundle; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *stringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] - pathForResource:@"FacebookSDKStrings" - ofType:@"bundle"]; - bundle = [NSBundle bundleWithPath:stringsBundlePath] ?: [NSBundle mainBundle]; + NSString *spmStringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] + pathForResource:@"Facebook_FBSDKCoreKit_Basics" + ofType:@"bundle"]; + bundle = [NSBundle bundleWithPath:spmStringsBundlePath]; + if (!bundle) { + NSString *stringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] + pathForResource:@"FacebookSDKStrings" + ofType:@"bundle"]; + + bundle = [NSBundle bundleWithPath:stringsBundlePath] ?: [NSBundle mainBundle]; + } }); return bundle; } diff --git a/Package.swift b/Package.swift index a1e75d07b3..85345459a4 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.1 +// swift-tools-version:5.3 // The swift-tools-version declares the minimum version of Swift required to build this package. // Copyright (c) 2016-present, Facebook, Inc. All rights reserved. @@ -23,6 +23,7 @@ import PackageDescription let package = Package( name: "Facebook", + defaultLocalization: "en", platforms: [ .iOS(.v9), .tvOS(.v10) diff --git a/Sources/FBSDKCoreKit_Basics/Resources/af.lproj b/Sources/FBSDKCoreKit_Basics/Resources/af.lproj new file mode 120000 index 0000000000..9e497dfd9b --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/af.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/af.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ar.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ar.lproj new file mode 120000 index 0000000000..981af6f344 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ar.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ar.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/bn.lproj b/Sources/FBSDKCoreKit_Basics/Resources/bn.lproj new file mode 120000 index 0000000000..9c7ac62b94 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/bn.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/bn.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/cs.lproj b/Sources/FBSDKCoreKit_Basics/Resources/cs.lproj new file mode 120000 index 0000000000..53425a072b --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/cs.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/cs.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/da.lproj b/Sources/FBSDKCoreKit_Basics/Resources/da.lproj new file mode 120000 index 0000000000..4d97ecff19 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/da.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/da.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/de.lproj b/Sources/FBSDKCoreKit_Basics/Resources/de.lproj new file mode 120000 index 0000000000..0e7840dd5b --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/de.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/de.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/el.lproj b/Sources/FBSDKCoreKit_Basics/Resources/el.lproj new file mode 120000 index 0000000000..2165ecff0d --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/el.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/el.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/en.lproj b/Sources/FBSDKCoreKit_Basics/Resources/en.lproj new file mode 120000 index 0000000000..7abe3c6254 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/en.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/en.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj b/Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj new file mode 120000 index 0000000000..f3191687b3 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/en_GB.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/es.lproj b/Sources/FBSDKCoreKit_Basics/Resources/es.lproj new file mode 120000 index 0000000000..53cc08f1fb --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/es.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/es.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj b/Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj new file mode 120000 index 0000000000..4ea9e58649 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/es_ES.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/fi.lproj b/Sources/FBSDKCoreKit_Basics/Resources/fi.lproj new file mode 120000 index 0000000000..4addd07307 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/fi.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/fi.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/fil.lproj b/Sources/FBSDKCoreKit_Basics/Resources/fil.lproj new file mode 120000 index 0000000000..6c49ae3424 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/fil.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/fil.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/fr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/fr.lproj new file mode 120000 index 0000000000..9e92a4b0b1 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/fr.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/fr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/gu.lproj b/Sources/FBSDKCoreKit_Basics/Resources/gu.lproj new file mode 120000 index 0000000000..101c99fd53 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/gu.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/gu.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/he.lproj b/Sources/FBSDKCoreKit_Basics/Resources/he.lproj new file mode 120000 index 0000000000..51a7548945 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/he.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/he.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/hi.lproj b/Sources/FBSDKCoreKit_Basics/Resources/hi.lproj new file mode 120000 index 0000000000..a727230d7f --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/hi.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/hi.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/hr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/hr.lproj new file mode 120000 index 0000000000..b29571bbd1 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/hr.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/hr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/hu.lproj b/Sources/FBSDKCoreKit_Basics/Resources/hu.lproj new file mode 120000 index 0000000000..13fe8daa8a --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/hu.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/hu.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/id.lproj b/Sources/FBSDKCoreKit_Basics/Resources/id.lproj new file mode 120000 index 0000000000..a0b6650e73 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/id.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/id.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/it.lproj b/Sources/FBSDKCoreKit_Basics/Resources/it.lproj new file mode 120000 index 0000000000..0524f89286 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/it.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/it.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ja.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ja.lproj new file mode 120000 index 0000000000..83975b93f2 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ja.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ja.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/kn.lproj b/Sources/FBSDKCoreKit_Basics/Resources/kn.lproj new file mode 120000 index 0000000000..55c0cefeb0 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/kn.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/kn.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ko.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ko.lproj new file mode 120000 index 0000000000..d8b6d40713 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ko.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ko.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ml.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ml.lproj new file mode 120000 index 0000000000..a2df1efedf --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ml.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ml.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/mr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/mr.lproj new file mode 120000 index 0000000000..62da38c6f7 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/mr.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/mr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ms.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ms.lproj new file mode 120000 index 0000000000..f57d94d082 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ms.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ms.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/nb.lproj b/Sources/FBSDKCoreKit_Basics/Resources/nb.lproj new file mode 120000 index 0000000000..be7eba63de --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/nb.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/nb.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/nl.lproj b/Sources/FBSDKCoreKit_Basics/Resources/nl.lproj new file mode 120000 index 0000000000..098ca3ac21 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/nl.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/nl.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pa.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pa.lproj new file mode 120000 index 0000000000..5e1d0a1633 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/pa.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/pa.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pl.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pl.lproj new file mode 120000 index 0000000000..0cb54d30f8 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/pl.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/pl.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pt.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pt.lproj new file mode 120000 index 0000000000..b247e2f9bd --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/pt.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/pt.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj new file mode 120000 index 0000000000..6a458f7341 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/pt_PT.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ru.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ru.lproj new file mode 120000 index 0000000000..70cb7992f0 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ru.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ru.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/sk.lproj b/Sources/FBSDKCoreKit_Basics/Resources/sk.lproj new file mode 120000 index 0000000000..e53210c0a5 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/sk.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/sk.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/sv.lproj b/Sources/FBSDKCoreKit_Basics/Resources/sv.lproj new file mode 120000 index 0000000000..8a7ec4affb --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/sv.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/sv.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ta.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ta.lproj new file mode 120000 index 0000000000..720ca2a625 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/ta.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/ta.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/te.lproj b/Sources/FBSDKCoreKit_Basics/Resources/te.lproj new file mode 120000 index 0000000000..e2b6505f92 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/te.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/te.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/th.lproj b/Sources/FBSDKCoreKit_Basics/Resources/th.lproj new file mode 120000 index 0000000000..9777f83ad5 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/th.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/th.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/tr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/tr.lproj new file mode 120000 index 0000000000..15bcb8312a --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/tr.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/tr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/vi.lproj b/Sources/FBSDKCoreKit_Basics/Resources/vi.lproj new file mode 120000 index 0000000000..24b1c44b6a --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/vi.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/vi.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/zh.lproj b/Sources/FBSDKCoreKit_Basics/Resources/zh.lproj new file mode 120000 index 0000000000..aeea788a3e --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/zh.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/zh.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj b/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj new file mode 120000 index 0000000000..ba7fc07d01 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/zh_Hant_HK.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj b/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj new file mode 120000 index 0000000000..4f1475d998 --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj @@ -0,0 +1 @@ +../../../FacebookSDKStrings.bundle/Resources/zh_Hant_TW.lproj \ No newline at end of file From 494ea9b4e64685414cf1fd95cbd13306aafa2b50 Mon Sep 17 00:00:00 2001 From: Julie Yuan Date: Mon, 5 Oct 2020 15:34:27 -0700 Subject: [PATCH 018/227] New method to add a single logging extra to login flow Summary: Add a new method which enables adding a single key:value pair to the `_extras` dictionary which is sent as part of the logging flow for login events. Differential Revision: D23879923 fbshipit-source-id: d8d2b4c37d85ba4c9c107284f80ed7e2ac189ac5 --- .../Internal/FBSDKLoginManagerLogger.h | 2 + .../Internal/FBSDKLoginManagerLogger.m | 5 ++ .../FBSDKLoginManagerLoggerTests.m | 88 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h index 1ce4ddffb2..e214e78ae0 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h @@ -48,6 +48,8 @@ NS_SWIFT_NAME(LoginManagerLogger) - (void)willAttemptAppSwitchingBehavior; - (void)logNativeAppDialogResult:(BOOL)result dialogDuration:(NSTimeInterval)dialogDuration; + +- (void)addSingleLoggingExtra:(id)extra forKey:(NSString *)key; @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m index ecfcc5fdb1..524ff57157 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m @@ -193,6 +193,11 @@ - (void)logNativeAppDialogResult:(BOOL)result dialogDuration:(NSTimeInterval)dia } } +- (void)addSingleLoggingExtra:(id)extra forKey:(NSString *)key +{ + [FBSDKTypeUtility dictionary:_extras setObject:extra forKey:key]; +} + #pragma mark - Private - (NSString *)clientStateForAuthMethod:(NSString *)authMethod andExistingState:(NSDictionary *)existingState diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m new file mode 100644 index 0000000000..e189dbcc3e --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m @@ -0,0 +1,88 @@ +// 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 "FBSDKLoginManager.h" +#import "FBSDKLoginManagerLogger.h" + +@interface FBSDKAppEvents (Testing) + ++ (FBSDKAppEvents *)singleton; + +- (void)instanceLogEvent:(FBSDKAppEventName)eventName + valueToSum:(NSNumber *)valueToSum + parameters:(NSDictionary *)parameters + isImplicitlyLogged:(BOOL)isImplicitlyLogged + accessToken:(FBSDKAccessToken *)accessToken; + +@end + +@interface FBSDKLoginManagerLoggerTests : XCTestCase +@end + +@implementation FBSDKLoginManagerLoggerTests +{ + id _appEventsMock; + id _loginManagerMock; +} + +- (void)setUp +{ + [super setUp]; + _loginManagerMock = OCMClassMock(FBSDKLoginManager.class); + // Set up AppEvents singleton mock + _appEventsMock = OCMClassMock(FBSDKAppEvents.class); + OCMStub([_appEventsMock singleton]).andReturn(_appEventsMock); +} + +- (void)tearDown +{ + [super tearDown]; + [_loginManagerMock stopMocking]; + _loginManagerMock = nil; + [_appEventsMock stopMocking]; + _appEventsMock = nil; +} + +- (void)testExtrasForAddSingleLoggingExtra +{ + FBSDKLoginManagerLogger *logger = [[FBSDKLoginManagerLogger alloc] initWithLoggingToken:nil]; + BOOL (^verifyParameterContents)(NSDictionary *) = ^BOOL (NSDictionary *parameters) { + NSString *extras = [FBSDKTypeUtility dictionary:parameters objectForKey:@"6_extras" ofType:NSString.class]; + NSDictionary *extrasDictionary = [FBSDKBasicUtility objectForJSONString:extras error:nil]; + XCTAssertEqualObjects([FBSDKTypeUtility dictionary:extrasDictionary objectForKey:@"test_extra_key" ofType:NSString.class], @"test_extra_value"); + return YES; + }; + + [logger addSingleLoggingExtra:@"test_extra_value" forKey:@"test_extra_key"]; + [logger startSessionForLoginManager:_loginManagerMock]; + + OCMVerify( + [_appEventsMock instanceLogEvent:OCMArg.any + valueToSum:OCMArg.any + parameters:[OCMArg checkWithBlock:verifyParameterContents] + isImplicitlyLogged:OCMArg.any + accessToken:OCMArg.any] + ); +} + +@end From dcf60b550742c4c404ba625b5ba345de0c5e5e3f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 5 Oct 2020 17:44:24 -0700 Subject: [PATCH 019/227] Back out "Add Localization Resources for Swift Package Manager" Summary: Original commit changeset: 3423767af736 Will wait until next major version release and then add this to that changeset. Reviewed By: robtimp Differential Revision: D24120409 fbshipit-source-id: 6988a1cb151f4793a531192b0be4d2e8ff6e95da --- .../FBSDKCoreKit/Internal/FBSDKInternalUtility.m | 15 ++++----------- Package.swift | 3 +-- Sources/FBSDKCoreKit_Basics/Resources/af.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ar.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/bn.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/cs.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/da.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/de.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/el.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/en.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/es.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/fi.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/fil.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/fr.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/gu.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/he.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/hi.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/hr.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/hu.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/id.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/it.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ja.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/kn.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ko.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ml.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/mr.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ms.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/nb.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/nl.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/pa.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/pl.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/pt.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ru.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/sk.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/sv.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/ta.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/te.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/th.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/tr.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/vi.lproj | 1 - Sources/FBSDKCoreKit_Basics/Resources/zh.lproj | 1 - .../Resources/zh_Hant_HK.lproj | 1 - .../Resources/zh_Hant_TW.lproj | 1 - 46 files changed, 5 insertions(+), 57 deletions(-) delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/af.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ar.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/bn.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/cs.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/da.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/de.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/el.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/en.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/es.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/fi.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/fil.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/fr.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/gu.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/he.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/hi.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/hr.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/hu.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/id.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/it.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ja.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/kn.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ko.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ml.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/mr.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ms.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/nb.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/nl.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pa.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pl.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pt.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ru.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/sk.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/sv.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/ta.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/te.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/th.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/tr.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/vi.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/zh.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj delete mode 120000 Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 85c828d9f6..9f5173901f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -89,17 +89,10 @@ + (NSBundle *)bundleForStrings static NSBundle *bundle; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *spmStringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] - pathForResource:@"Facebook_FBSDKCoreKit_Basics" - ofType:@"bundle"]; - bundle = [NSBundle bundleWithPath:spmStringsBundlePath]; - if (!bundle) { - NSString *stringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] - pathForResource:@"FacebookSDKStrings" - ofType:@"bundle"]; - - bundle = [NSBundle bundleWithPath:stringsBundlePath] ?: [NSBundle mainBundle]; - } + NSString *stringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] + pathForResource:@"FacebookSDKStrings" + ofType:@"bundle"]; + bundle = [NSBundle bundleWithPath:stringsBundlePath] ?: [NSBundle mainBundle]; }); return bundle; } diff --git a/Package.swift b/Package.swift index 85345459a4..a1e75d07b3 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.3 +// swift-tools-version:5.1 // The swift-tools-version declares the minimum version of Swift required to build this package. // Copyright (c) 2016-present, Facebook, Inc. All rights reserved. @@ -23,7 +23,6 @@ import PackageDescription let package = Package( name: "Facebook", - defaultLocalization: "en", platforms: [ .iOS(.v9), .tvOS(.v10) diff --git a/Sources/FBSDKCoreKit_Basics/Resources/af.lproj b/Sources/FBSDKCoreKit_Basics/Resources/af.lproj deleted file mode 120000 index 9e497dfd9b..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/af.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/af.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ar.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ar.lproj deleted file mode 120000 index 981af6f344..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ar.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ar.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/bn.lproj b/Sources/FBSDKCoreKit_Basics/Resources/bn.lproj deleted file mode 120000 index 9c7ac62b94..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/bn.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/bn.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/cs.lproj b/Sources/FBSDKCoreKit_Basics/Resources/cs.lproj deleted file mode 120000 index 53425a072b..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/cs.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/cs.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/da.lproj b/Sources/FBSDKCoreKit_Basics/Resources/da.lproj deleted file mode 120000 index 4d97ecff19..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/da.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/da.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/de.lproj b/Sources/FBSDKCoreKit_Basics/Resources/de.lproj deleted file mode 120000 index 0e7840dd5b..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/de.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/de.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/el.lproj b/Sources/FBSDKCoreKit_Basics/Resources/el.lproj deleted file mode 120000 index 2165ecff0d..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/el.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/el.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/en.lproj b/Sources/FBSDKCoreKit_Basics/Resources/en.lproj deleted file mode 120000 index 7abe3c6254..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/en.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/en.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj b/Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj deleted file mode 120000 index f3191687b3..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/en_GB.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/en_GB.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/es.lproj b/Sources/FBSDKCoreKit_Basics/Resources/es.lproj deleted file mode 120000 index 53cc08f1fb..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/es.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/es.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj b/Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj deleted file mode 120000 index 4ea9e58649..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/es_ES.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/es_ES.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/fi.lproj b/Sources/FBSDKCoreKit_Basics/Resources/fi.lproj deleted file mode 120000 index 4addd07307..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/fi.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/fi.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/fil.lproj b/Sources/FBSDKCoreKit_Basics/Resources/fil.lproj deleted file mode 120000 index 6c49ae3424..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/fil.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/fil.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/fr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/fr.lproj deleted file mode 120000 index 9e92a4b0b1..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/fr.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/fr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/gu.lproj b/Sources/FBSDKCoreKit_Basics/Resources/gu.lproj deleted file mode 120000 index 101c99fd53..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/gu.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/gu.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/he.lproj b/Sources/FBSDKCoreKit_Basics/Resources/he.lproj deleted file mode 120000 index 51a7548945..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/he.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/he.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/hi.lproj b/Sources/FBSDKCoreKit_Basics/Resources/hi.lproj deleted file mode 120000 index a727230d7f..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/hi.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/hi.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/hr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/hr.lproj deleted file mode 120000 index b29571bbd1..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/hr.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/hr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/hu.lproj b/Sources/FBSDKCoreKit_Basics/Resources/hu.lproj deleted file mode 120000 index 13fe8daa8a..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/hu.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/hu.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/id.lproj b/Sources/FBSDKCoreKit_Basics/Resources/id.lproj deleted file mode 120000 index a0b6650e73..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/id.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/id.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/it.lproj b/Sources/FBSDKCoreKit_Basics/Resources/it.lproj deleted file mode 120000 index 0524f89286..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/it.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/it.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ja.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ja.lproj deleted file mode 120000 index 83975b93f2..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ja.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ja.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/kn.lproj b/Sources/FBSDKCoreKit_Basics/Resources/kn.lproj deleted file mode 120000 index 55c0cefeb0..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/kn.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/kn.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ko.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ko.lproj deleted file mode 120000 index d8b6d40713..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ko.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ko.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ml.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ml.lproj deleted file mode 120000 index a2df1efedf..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ml.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ml.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/mr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/mr.lproj deleted file mode 120000 index 62da38c6f7..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/mr.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/mr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ms.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ms.lproj deleted file mode 120000 index f57d94d082..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ms.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ms.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/nb.lproj b/Sources/FBSDKCoreKit_Basics/Resources/nb.lproj deleted file mode 120000 index be7eba63de..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/nb.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/nb.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/nl.lproj b/Sources/FBSDKCoreKit_Basics/Resources/nl.lproj deleted file mode 120000 index 098ca3ac21..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/nl.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/nl.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pa.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pa.lproj deleted file mode 120000 index 5e1d0a1633..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/pa.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/pa.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pl.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pl.lproj deleted file mode 120000 index 0cb54d30f8..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/pl.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/pl.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pt.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pt.lproj deleted file mode 120000 index b247e2f9bd..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/pt.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/pt.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj b/Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj deleted file mode 120000 index 6a458f7341..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/pt_PT.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/pt_PT.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ru.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ru.lproj deleted file mode 120000 index 70cb7992f0..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ru.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ru.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/sk.lproj b/Sources/FBSDKCoreKit_Basics/Resources/sk.lproj deleted file mode 120000 index e53210c0a5..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/sk.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/sk.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/sv.lproj b/Sources/FBSDKCoreKit_Basics/Resources/sv.lproj deleted file mode 120000 index 8a7ec4affb..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/sv.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/sv.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/ta.lproj b/Sources/FBSDKCoreKit_Basics/Resources/ta.lproj deleted file mode 120000 index 720ca2a625..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/ta.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/ta.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/te.lproj b/Sources/FBSDKCoreKit_Basics/Resources/te.lproj deleted file mode 120000 index e2b6505f92..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/te.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/te.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/th.lproj b/Sources/FBSDKCoreKit_Basics/Resources/th.lproj deleted file mode 120000 index 9777f83ad5..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/th.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/th.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/tr.lproj b/Sources/FBSDKCoreKit_Basics/Resources/tr.lproj deleted file mode 120000 index 15bcb8312a..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/tr.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/tr.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/vi.lproj b/Sources/FBSDKCoreKit_Basics/Resources/vi.lproj deleted file mode 120000 index 24b1c44b6a..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/vi.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/vi.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/zh.lproj b/Sources/FBSDKCoreKit_Basics/Resources/zh.lproj deleted file mode 120000 index aeea788a3e..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/zh.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/zh.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj b/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj deleted file mode 120000 index ba7fc07d01..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_HK.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/zh_Hant_HK.lproj \ No newline at end of file diff --git a/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj b/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj deleted file mode 120000 index 4f1475d998..0000000000 --- a/Sources/FBSDKCoreKit_Basics/Resources/zh_Hant_TW.lproj +++ /dev/null @@ -1 +0,0 @@ -../../../FacebookSDKStrings.bundle/Resources/zh_Hant_TW.lproj \ No newline at end of file From ab88d0daaf1038c23a6269a3bcf9cdad6729b696 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 6 Oct 2020 21:59:24 -0700 Subject: [PATCH 020/227] Fix code of conduct link in readme Summary: $title Reviewed By: jingping2015 Differential Revision: D24149903 fbshipit-source-id: 565ddf6844a650b560d0ea346e5ca6d21f5d98a7 --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index a0e783d3cd..a62729b3e9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,7 +9,7 @@ labels: bug - [ ] I've updated to the latest released version of the SDK - [ ] I've searched for existing [GitHub issues](https://github.com/facebook/facebook-ios-sdk/issues) - [ ] I've looked for existing answers on [Stack Overflow](https://facebook.stackoverflow.com), the [Facebook Developer Community Forum](https://developers.facebook.com/community/) and the [Facebook Developers Group](https://www.facebook.com/groups/fbdevelopers) -- [ ] I've read the [Code of Conduct](CODE_OF_CONDUCT.md) +- [ ] I've read the [Code of Conduct](https://github.com/facebook/facebook-ios-sdk/blob/master/CODE_OF_CONDUCT.md) - [ ] This issue is not security related and can safely be disclosed publicly on GitHub ## Environment From 80d3a093e5839a6991a63bee92d14b45012c3f1f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 9 Oct 2020 11:24:47 -0700 Subject: [PATCH 021/227] Xcode 12 related build fixes Summary: Stops linking UIKit binary for static FBSDKGamingServicesKit. Not 100% sure why this is failing the xcode-integration ci job but this might help. This is more consistent with how the other kits are linking (or not linking) UIKit and local testing showed no issue with removing it. Additionally the carthage job is failing for tvos. This is likely due to the xcode 12 rollout. Including the fixes in here so we can fix the build as one diff. allow-large-files Also upgrading carthage binary 0.35.0 -> 0.36.0 to to see if that's the reason for the command failure. Differential Revision: D24196254 fbshipit-source-id: 51cb301b379fffa746deaea982d643d3c701f116 --- Configurations/Configuration/Release.xcconfig | 2 ++ .../FBSDKGamingServicesKit.xcodeproj/project.pbxproj | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Configurations/Configuration/Release.xcconfig b/Configurations/Configuration/Release.xcconfig index 1ac7fb4397..b0caa701f9 100644 --- a/Configurations/Configuration/Release.xcconfig +++ b/Configurations/Configuration/Release.xcconfig @@ -39,4 +39,6 @@ MTL_ENABLE_DEBUG_INFO = NO // Excluding arm64 in Release builds for simulator allows creation of x86_64 slice // when building with Xcode12. May need to revisit this as Apple Silicon gains adoption. +// Also see: https://github.com/Carthage/Carthage/issues/3019 EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 +EXCLUDED_ARCHS[sdk=appletvsimulator*] = arm64 diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj index 684acac692..52b8cf25dd 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj @@ -72,7 +72,6 @@ F4F7CA7723F49D6F0030A346 /* FBSDKGamingImageUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F7C9C223F48F2C0030A346 /* FBSDKGamingImageUploader.m */; }; F4F7CA7823F49D6F0030A346 /* FBSDKGamingImageUploaderConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F7C9B623F48F2C0030A346 /* FBSDKGamingImageUploaderConfiguration.m */; }; F4F7CA7923F49D6F0030A346 /* FBSDKGamingServiceController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F7C9BA23F48F2C0030A346 /* FBSDKGamingServiceController.m */; }; - F4F7CAA223F4A1390030A346 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CAA123F4A1390030A346 /* UIKit.framework */; }; F4F7CAA323F4A1470030A346 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CAA123F4A1390030A346 /* UIKit.framework */; }; /* End PBXBuildFile section */ @@ -328,7 +327,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4F7CAA223F4A1390030A346 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; From 95835b8676cb0e36fb307482cd8b7c1226308a05 Mon Sep 17 00:00:00 2001 From: Xin Wu Date: Fri, 9 Oct 2020 13:14:01 -0700 Subject: [PATCH 022/227] Move sending app events action to background thread Summary: We received iOS Stall Detected at FBGetAdvertisingIdentifier for IG. In order to avoid stall, we are going to move sending app events action to background thread. This diff is for `FBSDK`, we will have another diff for `IGFBSDK`. Reviewed By: tianqibt, KylinChang Differential Revision: D24107807 fbshipit-source-id: b9c79acaad7a0a8bbe2e8d6154b8a6ffdba5cd35 --- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 26 ++++++++++--------- .../Internal/FBSDKAppEventsUtility.h | 1 + .../Internal/FBSDKAppEventsUtility.m | 11 ++++++++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index ca27e40c2c..0e9c6282a7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -965,8 +965,8 @@ - (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason FBSDKAppEventsState *copy = [_appEventsState copy]; _appEventsState = [[FBSDKAppEventsState alloc] initWithToken:copy.tokenString appID:copy.appID]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self flushOnMainQueue:copy forReason:flushReason]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self flushOnBackgroundQueueWithDefaultPriority:copy forReason:flushReason]; }); } } @@ -1316,8 +1316,8 @@ - (void)checkPersistedEvents if (self.flushBehavior == FBSDKAppEventsFlushBehaviorExplicitOnly) { [FBSDKAppEventsStateManager persistAppEventsData:saved]; } else { - dispatch_async(dispatch_get_main_queue(), ^{ - [self flushOnMainQueue:saved forReason:FBSDKAppEventsFlushReasonPersistedEvents]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self flushOnBackgroundQueueWithDefaultPriority:saved forReason:FBSDKAppEventsFlushReasonPersistedEvents]; }); } } @@ -1331,15 +1331,15 @@ - (void)checkPersistedEvents } } -- (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState - forReason:(FBSDKAppEventsFlushReason)reason +- (void)flushOnBackgroundQueueWithDefaultPriority:(FBSDKAppEventsState *)appEventsState + forReason:(FBSDKAppEventsFlushReason)reason { if (appEventsState.events.count == 0) { return; } if (appEventsState.appID.length == 0) { - [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents appEventsState.appID] for [FBSDKAppEvents flushOnMainQueue:]"]; + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents appEventsState.appID] for [FBSDKAppEvents flushOnBackgroundQueueWithDefaultPriority:]"]; return; } @@ -1347,7 +1347,7 @@ - (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState return; } - [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; + [FBSDKAppEventsUtility ensureNotOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; [self fetchServerConfiguration:^(void) { NSString *receipt_data = appEventsState.extractReceiptData; @@ -1399,9 +1399,11 @@ - (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - [self handleActivitiesPostCompletion:error - loggingEntry:loggingEntry - appEventsState:(FBSDKAppEventsState *)appEventsState]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self handleActivitiesPostCompletion:error + loggingEntry:loggingEntry + appEventsState:(FBSDKAppEventsState *)appEventsState]; + }); }]; }]; } @@ -1416,7 +1418,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushResult) { FlushResultNoConnectivity, }; - [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; + [FBSDKAppEventsUtility ensureNotOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; FBSDKAppEventsFlushResult flushResult = FlushResultSuccess; if (error) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h index a52202ed13..c545e818ee 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h @@ -51,6 +51,7 @@ NS_SWIFT_NAME(AppEventsUtility) shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID; + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)className; ++ (void)ensureNotOnMainThread:(NSString *)methodName className:(NSString *)className; + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason; + (void)logAndNotify:(NSString *)msg allowLogAsDeveloperError:(BOOL)allowLogAsDeveloperError; + (void)logAndNotify:(NSString *)msg; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index b0393d8b30..f30dbe6ae5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -196,6 +196,17 @@ + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)classNam ); } ++ (void)ensureNotOnMainThread:(NSString *)methodName className:(NSString *)className +{ + FBSDKConditionalLog( + [NSThread isMainThread] == NO, + FBSDKLoggingBehaviorDeveloperErrors, + @"*** <%@, %@> is called on main thread. This can lead to errors.", + methodName, + className + ); +} + + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason { NSString *result = @"Unknown"; From 6538b2700bade3293182e428fd7823ce6668f2e7 Mon Sep 17 00:00:00 2001 From: Alberto Gragera Cerrajero Date: Sat, 10 Oct 2020 00:39:57 -0700 Subject: [PATCH 023/227] Move FBSDKAppLinkResolv* to its own folder Summary: The main goal of this diff is to remove OHHTPStubs from the FBSDKAppLinkResolver test code. The easiest way to do that has been to extract the request building part from FBSDKAppLinkResolver to it own class. These allows us to: - Assert correctness over some parts of the request independently - Inject a builder mock in FBSDKAppLinkResolver so we can control the FBSDKGraphRequest and inject the response we want, without having to mock the http layer at all. Reviewed By: joesus Differential Revision: D23964906 fbshipit-source-id: 8ca26b40b2defd7fd8e3ea07db25da69ae8426ca --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 14 +++++++++++--- .../AppLink/{ => Resolver}/FBSDKAppLinkResolver.h | 0 .../AppLink/{ => Resolver}/FBSDKAppLinkResolver.m | 0 .../AppLink/{ => Resolver}/FBSDKAppLinkResolving.h | 0 4 files changed, 11 insertions(+), 3 deletions(-) rename FBSDKCoreKit/FBSDKCoreKit/AppLink/{ => Resolver}/FBSDKAppLinkResolver.h (100%) rename FBSDKCoreKit/FBSDKCoreKit/AppLink/{ => Resolver}/FBSDKAppLinkResolver.m (100%) rename FBSDKCoreKit/FBSDKCoreKit/AppLink/{ => Resolver}/FBSDKAppLinkResolving.h (100%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index e13ce111db..9c9156509c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -1749,6 +1749,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 45540D47252717BD008E853E /* Resolver */ = { + isa = PBXGroup; + children = ( + 7E5557361A8D833100344F86 /* FBSDKAppLinkResolver.h */, + 7E5557351A8D833100344F86 /* FBSDKAppLinkResolver.m */, + 52963A69215992F100C7B252 /* FBSDKAppLinkResolving.h */, + ); + path = Resolver; + sourceTree = ""; + }; 5D497700244A3E5700BD45C6 /* Integrity */ = { isa = PBXGroup; children = ( @@ -2483,12 +2493,10 @@ C5188F1C223857D700F4D8BC /* AppLink */ = { isa = PBXGroup; children = ( + 45540D47252717BD008E853E /* Resolver */, C5188F1D223857D700F4D8BC /* Internal */, 52963A70215992F200C7B252 /* FBSDKAppLink.h */, 52963A6C215992F100C7B252 /* FBSDKAppLink.m */, - 7E5557361A8D833100344F86 /* FBSDKAppLinkResolver.h */, - 7E5557351A8D833100344F86 /* FBSDKAppLinkResolver.m */, - 52963A69215992F100C7B252 /* FBSDKAppLinkResolving.h */, 52963A6E215992F200C7B252 /* FBSDKAppLinkReturnToRefererController.h */, 52963A71215992F200C7B252 /* FBSDKAppLinkReturnToRefererController.m */, 52963A73215992F300C7B252 /* FBSDKAppLinkReturnToRefererView.h */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.h b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.h rename to FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.h diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolver.m rename to FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolving.h b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolving.h similarity index 100% rename from FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKAppLinkResolving.h rename to FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolving.h From 6771546b8ed6f859fc1c9f93d79e3a106df7d64a Mon Sep 17 00:00:00 2001 From: Alberto Gragera Cerrajero Date: Sat, 10 Oct 2020 00:39:57 -0700 Subject: [PATCH 024/227] Unit Test Hardening (FBSDKAppLinkResolver) Summary: The main goal of this diff is to remove OHHTPStubs from the FBSDKAppLinkResolver test code. The easiest way to do that has been to extract the request building part from FBSDKAppLinkResolver to it own class. These allows us to: - Assert correctness over some parts of the request independently - Inject a builder mock in FBSDKAppLinkResolver so we can control the FBSDKGraphRequest and inject the response we want, without having to mock the http layer at all. Reviewed By: joesus Differential Revision: D24077192 fbshipit-source-id: 54141fe1a0533bc97503e7a241387c0d0c4da5e3 --- FBSDKCoreKit.podspec | 1 + .../FBSDKCoreKit.xcodeproj/project.pbxproj | 16 + .../AppLink/Resolver/FBSDKAppLinkResolver.m | 121 +-- .../FBSDKAppLinkResolverRequestBuilder.h | 49 ++ .../FBSDKAppLinkResolverRequestBuilder.m | 125 ++++ FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 2 + .../include/FBSDKAppLinkResolver.h | 2 +- .../FBSDKAppLinkResolverRequestBuilder.h | 1 + .../include/FBSDKAppLinkResolving.h | 2 +- .../FBSDKAppLinkResolverRequestBuilderTests.m | 58 ++ .../AppLinks/FBSDKAppLinkResolverTests.m | 687 ++++++------------ .../Internal/Helpers/FBSDKTestCase.h | 12 + .../Internal/Helpers/FBSDKTestCase.m | 37 + 13 files changed, 603 insertions(+), 510 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m create mode 120000 FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolverRequestBuilder.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverRequestBuilderTests.m diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index 400c6b0b23..8218bf08c7 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -62,6 +62,7 @@ Pod::Spec.new do |s| 'FBSDKCoreKit/FBSDKCoreKit/*.h', 'FBSDKCoreKit/FBSDKCoreKit/AppEvents/*.h', 'FBSDKCoreKit/FBSDKCoreKit/AppLink/*.h', + 'FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/*.h', 'FBSDKCoreKit/FBSDKCoreKit/GraphAPI/*.h' ss.private_header_files = 'FBSDKCoreKit/FBSDKCoreKit/Internal/**/*.h', 'FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/**/*.h' diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 9c9156509c..fd9e8d14bb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -68,6 +68,11 @@ 0384CED1208E606B0013D404 /* FBSDKAccessTokenExpirer.m in Sources */ = {isa = PBXBuildFile; fileRef = 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */; }; 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */; }; 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */; }; + 45540D9125271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 45540D9225271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 45540D9325271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45540D9025271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m */; }; + 45540D9425271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45540D9025271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m */; }; + 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 45540DB025271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m */; }; 4AF47CF31F42468E00A57A67 /* FBSDKDeviceUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */; }; 4AF47CF41F42468E00A57A67 /* FBSDKDeviceUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */; }; 4AF47CF51F42468E00A57A67 /* FBSDKDeviceUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF47CF21F42468D00A57A67 /* FBSDKDeviceUtilities.h */; }; @@ -1207,6 +1212,9 @@ 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessTokenExpirer.m; sourceTree = ""; }; 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkUtilityTests.m; sourceTree = ""; }; 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValueTests.m; sourceTree = ""; }; + 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppLinkResolverRequestBuilder.h; sourceTree = ""; }; + 45540D9025271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkResolverRequestBuilder.m; sourceTree = ""; }; + 45540DB025271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppLinkResolverRequestBuilderTests.m; path = AppLinks/FBSDKAppLinkResolverRequestBuilderTests.m; sourceTree = ""; }; 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKDeviceUtilities.m; sourceTree = ""; }; 4AF47CF21F42468D00A57A67 /* FBSDKDeviceUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKDeviceUtilities.h; sourceTree = ""; }; 4AF47CFE1F424A8700A57A67 /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.0.sdk/System/Library/Frameworks/CoreImage.framework; sourceTree = DEVELOPER_DIR; }; @@ -1755,6 +1763,8 @@ 7E5557361A8D833100344F86 /* FBSDKAppLinkResolver.h */, 7E5557351A8D833100344F86 /* FBSDKAppLinkResolver.m */, 52963A69215992F100C7B252 /* FBSDKAppLinkResolving.h */, + 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */, + 45540D9025271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m */, ); path = Resolver; sourceTree = ""; @@ -1860,6 +1870,7 @@ isa = PBXGroup; children = ( 7E55573A1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m */, + 45540DB025271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m */, ); name = AppLinks; sourceTree = ""; @@ -2955,6 +2966,7 @@ 81B71D6F1D19C87400933E93 /* FBSDKInternalUtility.h in Headers */, 81B71D701D19C87400933E93 /* FBSDKConstants.h in Headers */, BFC0244A237B6B0E00A596EE /* FBSDKSuggestedEventsIndexer.h in Headers */, + 45540D9225271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h in Headers */, 81B71D711D19C87400933E93 /* FBSDKWebDialog.h in Headers */, 52963A95215992F400C7B252 /* FBSDKWebViewAppLinkResolver.h in Headers */, 81B71D721D19C87400933E93 /* FBSDKMonotonicTime.h in Headers */, @@ -3039,6 +3051,7 @@ 52963AAC2159A16E00C7B252 /* FBSDKMeasurementEvent.h in Headers */, 899C3CF81A8BF73A00EA8658 /* FBSDKProfilePictureView.h in Headers */, 891687EE1AB38C7C00F55364 /* FBSDKButton.h in Headers */, + 45540D9125271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h in Headers */, F94310F424F8D608002441F1 /* FBSDKSKAdNetworkRule.h in Headers */, 52963A7E215992F400C7B252 /* FBSDKAppLinkResolving.h in Headers */, 894C0AF31A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h in Headers */, @@ -3868,6 +3881,7 @@ 5D81B424238739E600B02B2E /* FBSDKIntegrityManager.m in Sources */, 81B71D011D19C87400933E93 /* FBSDKGraphRequestPiggybackManager.m in Sources */, 81B71D021D19C87400933E93 /* FBSDKAppEventsStateManager.m in Sources */, + 45540D9425271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m in Sources */, 81B71D031D19C87400933E93 /* FBSDKServerConfigurationManager.m in Sources */, 81B71D041D19C87400933E93 /* FBSDKGraphRequest.m in Sources */, F9CBE51424E090590097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, @@ -3997,6 +4011,7 @@ 5D81B423238739E600B02B2E /* FBSDKIntegrityManager.m in Sources */, 9DA81B2A1AA65FA200B9FE0B /* FBSDKGraphRequestPiggybackManager.m in Sources */, 9D0BC1601A8D428700BE8BA4 /* FBSDKAppEventsStateManager.m in Sources */, + 45540D9325271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m in Sources */, 89830F2C1A7805D100226ABB /* FBSDKServerConfigurationManager.m in Sources */, 9DC658961A6EE5C500B85AAF /* FBSDKGraphRequest.m in Sources */, F9CBE51224E085CD0097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, @@ -4165,6 +4180,7 @@ F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */, F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, + 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */, 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */, F40B24C224732DD90059351C /* Fuzzer.swift in Sources */, 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m index 9e9cade28e..cd3291a618 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m @@ -26,6 +26,7 @@ #import "FBSDKAccessToken.h" #import "FBSDKAppLink.h" + #import "FBSDKAppLinkResolverRequestBuilder.h" #import "FBSDKAppLinkTarget.h" #import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequestConnection.h" @@ -48,6 +49,7 @@ @interface FBSDKAppLinkResolver () @property (nonatomic, strong) NSMutableDictionary *cachedFBSDKAppLinks; @property (nonatomic, assign) UIUserInterfaceIdiom userInterfaceIdiom; +@property (nonatomic, strong) FBSDKAppLinkResolverRequestBuilder *requestBuilder; @end @implementation FBSDKAppLinkResolver @@ -62,6 +64,27 @@ - (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceId if (self = [super init]) { self.cachedFBSDKAppLinks = [NSMutableDictionary dictionary]; self.userInterfaceIdiom = userInterfaceIdiom; + self.requestBuilder = [FBSDKAppLinkResolverRequestBuilder new]; + } + return self; +} + +- (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom andRequestBuilder:(FBSDKAppLinkResolverRequestBuilder *)builder +{ + if (self = [super init]) { + self.cachedFBSDKAppLinks = [NSMutableDictionary dictionary]; + self.userInterfaceIdiom = userInterfaceIdiom; + self.requestBuilder = builder; + } + return self; +} + +- (instancetype)initWithRequestBuilder:(FBSDKAppLinkResolverRequestBuilder *)builder +{ + if (self = [super init]) { + self.cachedFBSDKAppLinks = [NSMutableDictionary dictionary]; + self.userInterfaceIdiom = UI_USER_INTERFACE_IDIOM(); + self.requestBuilder = builder; } return self; } @@ -79,9 +102,9 @@ - (void)appLinksFromURLs:(NSArray *)urls handler:(FBSDKAppLinksBlock)ha [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"A user access token or clientToken is required to use FBAppLinkResolver"]; } + NSMutableDictionary *appLinks = [NSMutableDictionary dictionary]; NSMutableArray *toFind = [NSMutableArray array]; - NSMutableArray *toFindStrings = [NSMutableArray array]; @synchronized(self.cachedFBSDKAppLinks) { for (NSURL *url in urls) { @@ -89,86 +112,68 @@ - (void)appLinksFromURLs:(NSArray *)urls handler:(FBSDKAppLinksBlock)ha [FBSDKTypeUtility dictionary:appLinks setObject:self.cachedFBSDKAppLinks[url] forKey:url]; } else { [FBSDKTypeUtility array:toFind addObject:url]; - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - NSString *toFindString = [url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - #pragma clang diagnostic pop - if (toFindString) { - [FBSDKTypeUtility array:toFindStrings addObject:toFindString]; - } } } } if (toFind.count == 0) { // All of the URLs have already been found. - handler(_cachedFBSDKAppLinks, nil); - } - NSMutableArray *fields = [NSMutableArray arrayWithObject:kIOSKey]; - - NSString *idiomSpecificField = nil; - - switch (self.userInterfaceIdiom) { - case UIUserInterfaceIdiomPad: - idiomSpecificField = kIPadKey; - break; - case UIUserInterfaceIdiomPhone: - idiomSpecificField = kIPhoneKey; - break; - default: - break; - } - if (idiomSpecificField) { - [FBSDKTypeUtility array:fields addObject:idiomSpecificField]; + handler(appLinks, nil); + return; } - NSString *path = [NSString stringWithFormat:@"?fields=%@.fields(%@)&ids=%@", - kAppLinksKey, - [fields componentsJoinedByString:@","], - [toFindStrings componentsJoinedByString:@","]]; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path - parameters:nil - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; + + FBSDKGraphRequest *request = [self.requestBuilder requestForURLs:urls]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (error) { handler(@{}, error); return; } - for (NSURL *url in toFind) { - id nestedObject = result[url.absoluteString][kAppLinksKey]; - NSMutableArray *rawTargets = [NSMutableArray array]; - if (idiomSpecificField) { - [rawTargets addObjectsFromArray:nestedObject[idiomSpecificField]]; - } - [rawTargets addObjectsFromArray:nestedObject[kIOSKey]]; - - NSMutableArray *targets = [NSMutableArray arrayWithCapacity:rawTargets.count]; - for (id rawTarget in rawTargets) { - [FBSDKTypeUtility array:targets addObject:[FBSDKAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:rawTarget[kURLKey]] - appStoreId:rawTarget[kIOSAppStoreIdKey] - appName:rawTarget[kIOSAppNameKey]]]; - } - - id webTarget = nestedObject[kWebKey]; - NSString *webFallbackString = webTarget[kURLKey]; - NSURL *fallbackUrl = webFallbackString ? [NSURL URLWithString:webFallbackString] : url; - NSNumber *shouldFallback = webTarget[kShouldFallbackKey]; - if (shouldFallback != nil && !shouldFallback.boolValue) { - fallbackUrl = nil; - } + for (NSURL *url in toFind) { + FBSDKAppLink *link = [self buildAppLinkForURL:url inResults:result]; - FBSDKAppLink *link = [FBSDKAppLink appLinkWithSourceURL:url - targets:targets - webURL:fallbackUrl]; @synchronized(self.cachedFBSDKAppLinks) { [FBSDKTypeUtility dictionary:self.cachedFBSDKAppLinks setObject:link forKey:url]; } + [FBSDKTypeUtility dictionary:appLinks setObject:link forKey:url]; } handler(appLinks, nil); }]; } +- (FBSDKAppLink *)buildAppLinkForURL:(NSURL *)url inResults:(id)result +{ + NSString *idiomSpecificField = [self.requestBuilder getIdiomSpecificField]; + + id nestedObject = result[url.absoluteString][kAppLinksKey]; + NSMutableArray *rawTargets = [NSMutableArray array]; + if (idiomSpecificField) { + [rawTargets addObjectsFromArray:nestedObject[idiomSpecificField]]; + } + [rawTargets addObjectsFromArray:nestedObject[kIOSKey]]; + + NSMutableArray *targets = [NSMutableArray arrayWithCapacity:rawTargets.count]; + for (id rawTarget in rawTargets) { + [FBSDKTypeUtility array:targets addObject:[FBSDKAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:rawTarget[kURLKey]] + appStoreId:rawTarget[kIOSAppStoreIdKey] + appName:rawTarget[kIOSAppNameKey]]]; + } + + id webTarget = nestedObject[kWebKey]; + NSString *webFallbackString = webTarget[kURLKey]; + NSURL *fallbackUrl = webFallbackString ? [NSURL URLWithString:webFallbackString] : url; + + NSNumber *shouldFallback = webTarget[kShouldFallbackKey]; + if (shouldFallback != nil && !shouldFallback.boolValue) { + fallbackUrl = nil; + } + + return [FBSDKAppLink appLinkWithSourceURL:url + targets:targets + webURL:fallbackUrl]; +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (instancetype)resolver diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.h b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.h new file mode 100644 index 0000000000..9f33044f87 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.h @@ -0,0 +1,49 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + +#import + +#import "FBSDKAppLinkResolving.h" +#import "FBSDKGraphRequest.h" +NS_ASSUME_NONNULL_BEGIN + +/** + Class responsible for generating the appropriate FBSDKGraphRequest for a given set of urls + */ +NS_SWIFT_NAME(AppLinkResolverRequestBuilder) +@interface FBSDKAppLinkResolverRequestBuilder : NSObject + +/** + Generates the FBSDKGraphRequest + + @param urls The URLs to build the requests for + */ +- (FBSDKGraphRequest* _Nonnull)requestForURLs:(NSArray * _Nonnull)urls +NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension"); + +- (NSString* _Nullable)getIdiomSpecificField +NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extension"); +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m new file mode 100644 index 0000000000..4cc6263cf9 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m @@ -0,0 +1,125 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + + #import "FBSDKAppLinkResolverRequestBuilder.h" + + #import + + #import "FBSDKCoreKit+Internal.h" + #import "FBSDKGraphRequest+Internal.h" + +static NSString *const kIOSKey = @"ios"; +static NSString *const kIPhoneKey = @"iphone"; +static NSString *const kIPadKey = @"ipad"; +static NSString *const kAppLinksKey = @"app_links"; + +@interface FBSDKAppLinkResolverRequestBuilder () +@property (nonatomic, assign) UIUserInterfaceIdiom userInterfaceIdiom; +@end + +@implementation FBSDKAppLinkResolverRequestBuilder + +- (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom +{ + if (self = [super init]) { + self.userInterfaceIdiom = userInterfaceIdiom; + } + return self; +} + +- (instancetype)init +{ + if ((self = [super init])) { + _userInterfaceIdiom = UI_USER_INTERFACE_IDIOM(); + } + + return self; +} + +- (FBSDKGraphRequest *)requestForURLs:(NSArray *)urls +{ + NSArray *fields = [self getUISpecificFields]; + NSArray *encodedURLs = [self getEncodedURLs:urls]; + + NSString *path = + [NSString stringWithFormat:@"?fields=%@.fields(%@)&ids=%@", + kAppLinksKey, + [fields componentsJoinedByString:@","], + [encodedURLs componentsJoinedByString:@","]]; + return [[FBSDKGraphRequest alloc] + initWithGraphPath:path + parameters:nil + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError + | FBSDKGraphRequestFlagDisableErrorRecovery]; +} + +- (NSString *_Nullable)getIdiomSpecificField +{ + NSString *idiomSpecificField = nil; + + switch (self.userInterfaceIdiom) { + case UIUserInterfaceIdiomPad: + idiomSpecificField = kIPadKey; + break; + case UIUserInterfaceIdiomPhone: + idiomSpecificField = kIPhoneKey; + break; + default: + break; + } + + return idiomSpecificField; +} + +- (NSArray *)getUISpecificFields +{ + NSMutableArray *fields = [NSMutableArray arrayWithObject:kIOSKey]; + NSString *idiomSpecificField = [self getIdiomSpecificField]; + + if (idiomSpecificField) { + [FBSDKTypeUtility array:fields addObject:idiomSpecificField]; + } + + return fields; +} + +- (NSArray *)getEncodedURLs:(NSArray *)urls +{ + NSMutableArray *encodedURLs = [NSMutableArray array]; + + for (NSURL *url in urls) { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSString *encodedURL = [url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + #pragma clang diagnostic pop + if (encodedURL) { + [FBSDKTypeUtility array:encodedURLs addObject:encodedURL]; + } + } + + return encodedURLs; +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 701dea4780..2c25121fb5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -43,6 +43,7 @@ #import #import #import + #import #import #import #import @@ -79,6 +80,7 @@ #import "FBSDKAppLink.h" #import "FBSDKAppLinkNavigation.h" #import "FBSDKAppLinkResolver.h" + #import "FBSDKAppLinkResolverRequestBuilder.h" #import "FBSDKAppLinkResolving.h" #import "FBSDKAppLinkReturnToRefererController.h" #import "FBSDKAppLinkReturnToRefererView.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolver.h b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolver.h index bad15cf41d..edffd6948a 120000 --- a/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolver.h +++ b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolver.h @@ -1 +1 @@ -../AppLink/FBSDKAppLinkResolver.h \ No newline at end of file +../AppLink/Resolver/FBSDKAppLinkResolver.h \ No newline at end of file diff --git a/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolverRequestBuilder.h b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolverRequestBuilder.h new file mode 120000 index 0000000000..e62088ccc9 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolverRequestBuilder.h @@ -0,0 +1 @@ +../AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.h \ No newline at end of file diff --git a/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolving.h b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolving.h index f1abae564d..30a0800028 120000 --- a/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolving.h +++ b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAppLinkResolving.h @@ -1 +1 @@ -../AppLink/FBSDKAppLinkResolving.h \ No newline at end of file +../AppLink/Resolver/FBSDKAppLinkResolving.h \ No newline at end of file diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverRequestBuilderTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverRequestBuilderTests.m new file mode 100644 index 0000000000..b56b46234a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverRequestBuilderTests.m @@ -0,0 +1,58 @@ +// 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 "FBSDKAppLinkResolverRequestBuilder.h" +#import "FBSDKTestCase.h" + +@interface FBSDKAppLinkResolverRequestBuilder (FBSDKAppLinkResolverTests) + +- (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom; + +@end + +@interface FBSDKAppLinkResolverRequestBuilderTests : FBSDKTestCase +@end + +@implementation FBSDKAppLinkResolverRequestBuilderTests +#pragma mark - test cases + +- (void)testAsksForPhoneDataOnPhone +{ + FBSDKAppLinkResolverRequestBuilder *builder = [[FBSDKAppLinkResolverRequestBuilder alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPhone]; + + FBSDKGraphRequest *request = [builder requestForURLs:@[]]; + BOOL askedForPhone = [request.parameters[@"fields"] rangeOfString:@"iphone"].location != NSNotFound; + + XCTAssertTrue(askedForPhone); +} + +- (void)testAsksForPadDataOnPad +{ + FBSDKAppLinkResolverRequestBuilder *builder = [[FBSDKAppLinkResolverRequestBuilder alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPad]; + + FBSDKGraphRequest *request = [builder requestForURLs:@[]]; + BOOL askedForPad = [request.parameters[@"fields"] rangeOfString:@"iphone"].location != NSNotFound; + + XCTAssertTrue(askedForPad); +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m index 4eac74e3a9..74b1d181ce 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppLinks/FBSDKAppLinkResolverTests.m @@ -20,19 +20,15 @@ #import #import -#import #import "FBSDKAppLinkResolver.h" -#import "FBSDKCoreKitTestUtility.h" -#import "FBSDKInternalUtility.h" -#import "FBSDKSettings.h" +#import "FBSDKTestCase.h" static NSString *const kAppLinkURLString = @"http://example.com/1234567890"; static NSString *const kAppLinkURL2String = @"http://example.com/0987654321"; static NSString *const kAppLinksKey = @"app_links"; - -typedef void (^HTTPStubCallback)(NSURLRequest *request); -typedef _Nullable id (^StringURLBlock)(NSString *urlString); +static NSString *const kIphoneKey = @"iphone"; +static NSString *const kIpadKey = @"ipad"; @interface NSURL (FBSDKAppLinkResolverTests) @@ -43,147 +39,87 @@ @interface NSURL (FBSDKAppLinkResolverTests) @interface FBSDKAppLinkResolver (FBSDKAppLinkResolverTests) - (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom; +- (instancetype)initWithRequestBuilder:(FBSDKAppLinkResolverRequestBuilder *)builder; +- (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom andRequestBuilder:(FBSDKAppLinkResolverRequestBuilder *)builder; @end -@interface FBSDKAppLinkResolverTests : XCTestCase +@interface FBSDKAppLinkResolverTests : FBSDKTestCase @end @implementation FBSDKAppLinkResolverTests + +#pragma mark - Mock requests + +- (void)mockAppLinkRequestWithResult:(id)result { - id _mockNSBundle; + [self mockAppLinkRequestWithResult:result error:nil idiomSpecificField:kIphoneKey]; } -#pragma mark - HTTP stubbing helpers - -- (void)stubAllResponsesWithResult:(id)result +- (void)mockAppLinkRequestWithError { - [self stubAllResponsesWithResult:result statusCode:200]; + [self mockAppLinkRequestWithResult:@{@"error" : @{}} + error:[[NSError alloc] + initWithDomain:FBSDKErrorDomain + code:-1 + userInfo:nil] + idiomSpecificField:kIphoneKey]; } -- (void)stubAllResponsesWithResult:(id)result - statusCode:(int)statusCode +- (void)mockAppLinkRequestWithResult:(id)result idiomSpecificField:(NSString *)field { - [self stubAllResponsesWithResult:result statusCode:statusCode callback:nil]; + [self mockAppLinkRequestWithResult:result error:nil idiomSpecificField:field]; } -- (void)stubAllResponsesWithResult:(id)result - statusCode:(int)statusCode - callback:(HTTPStubCallback)callback +- (void)mockAppLinkRequestWithResult:(id)result error:(NSError *)error idiomSpecificField:(NSString *)field { - return [self stubMatchingRequestsWithResponses:@{@"" : result} - statusCode:statusCode - callback:callback]; + [self mockAppLinkRequestWithResult:result error:error idiomSpecificField:field andDo:nil]; } -- (void)stubMatchingRequestsWithResponses:(NSDictionary *)requestsAndResponses - statusCode:(int)statusCode - callback:(HTTPStubCallback)callback +- (void)mockAppLinkRequestWithResult:(id)result error:(NSError *)error idiomSpecificField:(NSString *)field andDo:(void (^_Nullable)(NSInvocation *))block { - StringURLBlock matchingKey = ^id (NSString *urlString) { - for (NSString *substring in requestsAndResponses.allKeys) { - // The first @"" always matches - if (substring.length == 0 - || [urlString rangeOfString:substring].location != NSNotFound) { - return substring; - } - } - return nil; - }; + [self stubGraphRequestWithResult:result error:error connection:nil]; + [self stubAppLinkResolverRequestBuilderWithIdiomSpecificField:field]; - [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { - if (callback) { - callback(request); - } - - return matchingKey(request.URL.absoluteString) != nil; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - id result = requestsAndResponses[matchingKey(request.URL.absoluteString)]; - NSData *data = [[FBSDKBasicUtility JSONStringForObject:result - error:NULL - invalidObjectHandler:NULL] dataUsingEncoding:NSUTF8StringEncoding]; - - return [OHHTTPStubsResponse responseWithData:data - statusCode:statusCode - headers:nil]; - }]; + OCMStub([self.appLinkResolverRequestBuilderMock requestForURLs:[OCMArg any]]).andReturn(self.graphRequestMock).andDo(block); } #pragma mark - test cases -- (void)setUp -{ - _mockNSBundle = [FBSDKCoreKitTestUtility mainBundleMock]; -} - -/* -- (void)testAsksForPhoneDataOnPhone +- (void)testUsesPhoneDataOnPhone { - XCTestExpectation *expectation = [self expectationWithDescription:@"asksForPhoneDataOnPhone"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - __block BOOL askedForPhone = NO; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - NSDictionary *queryParameters = - [FBSDKInternalUtility dictionaryFromFBURL:request.URL]; - askedForPhone = [queryParameters[@"fields"] rangeOfString:@"iphone"].location != NSNotFound; - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - return [OHHTTPStubsResponse responseWithData:[NSData data] - statusCode:200 - headers:nil]; - }]; + XCTestExpectation *expectation = [self expectationWithDescription:@"usesPhoneDataOnPhone"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + kIphoneKey : @[ + @{ + @"app_name" : @"Example", + @"app_store_id" : @"456", + @"url" : @"example://things/1234567890" + } + ], + @"ios" : @[ + @{ + @"app_name" : @"Example", + @"app_store_id" : @"123", + @"url" : @"example://things/1234567890" + } + ], + }, + @"id" : kAppLinkURLString + } + }; - FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPhone]; - [resolver - appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable appLink, NSError * _Nullable error) { - XCTAssertTrue(askedForPhone); - [expectation fulfill]; - }]; + [self mockAppLinkRequestWithResult:result idiomSpecificField:kIphoneKey]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { - XCTAssertNil(error); - }]; - [FBSDKSettings setClientToken:nil]; -} -*/ + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPhone andRequestBuilder:self.appLinkResolverRequestBuilderMock]; -/* -- (void)testUsesPhoneDataOnPhone -{ - XCTestExpectation *expectation = [self expectationWithDescription:@"usesPhoneDataOnPhone"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey: @{ - @"iphone": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"456", - @"url": @"example://things/1234567890" - } - ], - @"ios": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"123", - @"url": @"example://things/1234567890" - } - ], - }, - @"id": kAppLinkURLString - } - }]; - - FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPhone]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { - + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqual(link.sourceURL.absoluteString, kAppLinkURLString); XCTAssertEqualObjects([link.targets[0] appStoreId], @"456"); @@ -192,82 +128,45 @@ - (void)testUsesPhoneDataOnPhone [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* -- (void)testAsksForPadDataOnPad +- (void)testUsesPadDataOnPad { - XCTestExpectation *expectation = [self expectationWithDescription:@"asksForPadDataOnPad"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - __block BOOL askedForPad = NO; - [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { - NSDictionary *queryParameters = - [FBSDKInternalUtility dictionaryFromFBURL:request.URL]; - // do an "OR" because we only need to verify we asked for it once (in cases where unrelated network requests - // were resetting the flag incorrectly back to NO). - askedForPad |= [queryParameters[@"fields"] rangeOfString:@"ipad"].location != NSNotFound; - return YES; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - return [OHHTTPStubsResponse responseWithData:[NSData data] - statusCode:200 - headers:nil]; - }]; + XCTestExpectation *expectation = [self expectationWithDescription:@"usesPadDataOnPad"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + @"ipad" : @[ + @{ + @"app_name" : @"Example", + @"app_store_id" : @"456", + @"url" : @"example://things/1234567890" + } + ], + @"ios" : @[ + @{ + @"app_name" : @"Example", + @"app_store_id" : @"123", + @"url" : @"example://things/1234567890" + } + ], + }, + @"id" : kAppLinkURLString + } + }; - FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPad]; - [resolver - appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { - XCTAssertTrue(askedForPad); - [expectation fulfill]; - }]; + [self mockAppLinkRequestWithResult:result idiomSpecificField:kIpadKey]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { - XCTAssertNil(error); - }]; - [FBSDKSettings setClientToken:nil]; -} -*/ + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPad andRequestBuilder:self.appLinkResolverRequestBuilderMock]; -/* -- (void)testUsesPadDataOnPad -{ - XCTestExpectation *expectation = [self expectationWithDescription:@"usesPadDataOnPad"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey: @{ - @"ipad": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"456", - @"url": @"example://things/1234567890" - } - ], - @"ios": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"123", - @"url": @"example://things/1234567890" - } - ], - }, - @"id": kAppLinkURLString - } - }]; - - FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithUserInterfaceIdiom:UIUserInterfaceIdiomPad]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqual(link.sourceURL.absoluteString, kAppLinkURLString); XCTAssertEqualObjects([link.targets[0] appStoreId], @"456"); @@ -276,76 +175,73 @@ - (void)testUsesPadDataOnPad [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } - - (void)testIgnoresAndroidData { XCTestExpectation *expectation = [self expectationWithDescription:@"ignoresAndroidData"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; + [self stubClientTokenWith:@"clienttoken"]; // We are not asking for it, but just make sure we ignore any non-iOS-platform data we get, to be safe. - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey: @{ - @"android": @[ - @{ - @"app_name": @"Example", - @"package": @"com.example.app", - @"url": @"example://things/1234567890" - } - ], - @"ios": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"123", - @"url": @"example://things/1234567890" - } - ], - }, - @"id": kAppLinkURLString - } - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + @"android" : @[ + @{ + @"app_name" : @"Example", + @"package" : @"com.example.app", + @"url" : @"example://things/1234567890" + } + ], + @"ios" : @[ + @{ + @"app_name" : @"Example", + @"app_store_id" : @"123", + @"url" : @"example://things/1234567890" + } + ], + }, + @"id" : kAppLinkURLString + } + }; + + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; + [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqualObjects([link.targets[0] appStoreId], @"123"); [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testHandlesNoTargets { XCTestExpectation *expectation = [self expectationWithDescription:@"handlesNoTargets"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + @"id" : kAppLinkURLString + } + }; - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - @"id": kAppLinkURLString - } - }]; + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqual(link.sourceURL.absoluteString, kAppLinkURLString); XCTAssertEqual(link.targets.count, 0); @@ -353,33 +249,31 @@ - (void)testHandlesNoTargets [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testHandlesMultipleURLs { XCTestExpectation *expectation = [self expectationWithDescription:@"handlesMultipleURLs"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - @"id": kAppLinkURLString - }, - kAppLinkURL2String : @{ - @"id": kAppLinkURL2String - } - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + @"id" : kAppLinkURLString + }, + kAppLinkURL2String : @{ + @"id" : kAppLinkURL2String + } + }; + + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; + [resolver appLinksFromURLs:@[[NSURL URLWithString:kAppLinkURLString], [NSURL URLWithString:kAppLinkURL2String]] - handler:^(NSDictionary * _Nonnull links, NSError * _Nullable error) { + handler:^(NSDictionary *_Nonnull links, NSError *_Nullable error) { XCTAssertNotNil(links); XCTAssertEqual(links.count, 2); XCTAssertEqual([links[[NSURL URLWithString:kAppLinkURLString]] sourceURL].absoluteString, kAppLinkURLString); @@ -388,311 +282,204 @@ - (void)testHandlesMultipleURLs [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testSetsFallbackIfNotSpecified { XCTestExpectation *expectation = [self expectationWithDescription:@"setsFallbackIfNotSpecified"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + @"id" : kAppLinkURLString + } + }; - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - @"id": kAppLinkURLString - } - }]; + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqual(link.webURL.absoluteString, kAppLinkURLString); [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testSetsFallbackIfSpecified { XCTestExpectation *expectation = [self expectationWithDescription:@"setsFallbackIfSpecified"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + @"web" : @{ + @"url" : @"http://www.example.com/somethingelse", + @"should_fallback" : @"true" + } + }, + @"id" : kAppLinkURLString + } + }; + + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey : @{ - @"web": @{ - @"url" : @"http://www.example.com/somethingelse", - @"should_fallback": @"true" - } - }, - @"id": kAppLinkURLString - } - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqualObjects(link.webURL.absoluteString, @"http://www.example.com/somethingelse"); [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testUsesSourceAsFallbackIfSpecified { XCTestExpectation *expectation = [self expectationWithDescription:@"usesSourceAsFallbackIfSpecified"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + @"web" : @{ + @"should_fallback" : @"true" + } + }, + @"id" : kAppLinkURLString, + } + }; + + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey: @{ - @"web": @{ - @"should_fallback": @"true" - } - }, - @"id": kAppLinkURLString, - } - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertEqual(link.webURL.absoluteString, kAppLinkURLString); [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testSetsNoFallbackIfSpecified { XCTestExpectation *expectation = [self expectationWithDescription:@"setsNoFallbackIfSpecified"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + @"web" : @{ + @"url" : @"http://www.example.com/somethingelse", + @"should_fallback" : @"false" + } + }, + @"id" : kAppLinkURLString + } + }; + + [self mockAppLinkRequestWithResult:result]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey : @{ - @"web": @{ - @"url" : @"http://www.example.com/somethingelse", - @"should_fallback": @"false" - } - }, - @"id": kAppLinkURLString - } - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNotNil(link); XCTAssertNil(link.webURL.absoluteString); [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testHandlesError { XCTestExpectation *expectation = [self expectationWithDescription:@"handlesError"]; + [self stubClientTokenWith:@"clienttoken"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; + [self mockAppLinkRequestWithError]; + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; - // We are not asking for it, but just make sure we ignore any non-iOS-platform data we get, to be safe. - [self stubAllResponsesWithResult:@{ - @"error" : @{} - } - statusCode:404]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link, NSError * _Nullable error) { + handler:^(FBSDKAppLink *_Nullable link, NSError *_Nullable error) { XCTAssertNil(link); XCTAssertNotNil(error); [expectation fulfill]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ -/* - (void)testResultsAreCachedAndCacheIsUsed { XCTestExpectation *expectation = [self expectationWithDescription:@"handlesCache"]; + [self stubClientTokenWith:@"clienttoken"]; + + id result = @{ + kAppLinkURLString : @{ + kAppLinksKey : @{ + @"iphone" : @[ + @{ + @"app_name" : @"Example", + @"app_store_id" : @"456", + @"url" : @"example://things/1234567890" + } + ], + }, + @"id" : kAppLinkURLString + } + }; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - __block NSUInteger callCount = 0; - - [self stubAllResponsesWithResult:@{ - kAppLinkURLString : @{ - kAppLinksKey : @{ - @"iphone": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"456", - @"url": @"example://things/1234567890" - } - ], - }, - @"id": kAppLinkURLString - } - } - statusCode:200 - callback:^(NSURLRequest *request) { - ++callCount; - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; - [resolver - appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link1, NSError * _Nullable error1) { - // Note: callCount is not necessarily 1, as the callback may be called multiple times during processing of the request. - NSUInteger expectedCallCount = callCount; - - [resolver - appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable link2, NSError * _Nullable error2) { - XCTAssertEqual(callCount, expectedCallCount); - [expectation fulfill]; - }]; - }]; - - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { - XCTAssertNil(error); + // We can change the approach and do OCMVerify(exactly(1), [_mockRequestBuilder requestForURLs]); + // in the inner block of the double call instead of using this counter. + __block int callCount = 0; + [self mockAppLinkRequestWithResult:result error:nil idiomSpecificField:kIphoneKey andDo:^(NSInvocation *invocation) { + callCount++; }]; - [FBSDKSettings setClientToken:nil]; -} -*/ -/* -- (void)testMixOfCachedAndUncached -{ - XCTestExpectation *expectation = [self expectationWithDescription:@"mixOfCachedAndUncached"]; - - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; - - __block NSMutableDictionary *callCounts = - [NSMutableDictionary dictionary]; - - [self stubMatchingRequestsWithResponses:@{ - @"1234567890" : @{ - kAppLinkURLString : @{ - kAppLinksKey : @{ - @"iphone": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"456", - @"url": @"example://things/1234567890" - } - ], - }, - @"id": kAppLinkURLString - } - }, - @"0987654321" : @{ - kAppLinkURL2String : @{ - kAppLinksKey : @{ - @"iphone": @[ - @{ - @"app_name": @"Example", - @"app_store_id": @"456", - @"url": @"example://things/1234567890" - } - ], - }, - @"id": kAppLinkURL2String - } - } - } - statusCode:200 - callback:^(NSURLRequest *request) { - NSUInteger callCount = callCounts[request.URL.absoluteString].unsignedIntegerValue; - ++callCount; - callCounts[request.URL.absoluteString] = @(callCount); - }]; - - FBSDKAppLinkResolver *resolver = [FBSDKAppLinkResolver resolver]; - - // Prime the cache with kAppLinkURL + FBSDKAppLinkResolver *resolver = [[FBSDKAppLinkResolver alloc] initWithRequestBuilder:self.appLinkResolverRequestBuilderMock]; + [resolver appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] - handler:^(FBSDKAppLink * _Nullable appLink, NSError * _Nullable error1) { - XCTAssertEqual(callCounts.count, 1); - - // Note: callCount is not necessarily 1, as the callback may be called multiple times during processing of the request. - NSString *firstCallKey = callCounts.allKeys[0]; - NSUInteger expectedCallCount = callCounts[firstCallKey].unsignedIntegerValue; - - // Now request them both; we expect the call count for kAppLinkURL to be unchanged. + handler:^(FBSDKAppLink *_Nullable link1, NSError *_Nullable error1) { [resolver - appLinksFromURLs:@[[NSURL URLWithString:kAppLinkURLString], [NSURL URLWithString:kAppLinkURL2String]] - handler:^(NSDictionary * _Nonnull links, NSError * _Nullable error2) { - XCTAssertEqual(callCounts.count, 2); - XCTAssertEqual([callCounts[firstCallKey] unsignedIntegerValue], expectedCallCount); - - XCTAssertEqual(links.count, 2); + appLinkFromURL:[NSURL URLWithString:kAppLinkURLString] + handler:^(FBSDKAppLink *_Nullable link2, NSError *_Nullable error2) { + XCTAssertEqual(callCount, 1); [expectation fulfill]; - }]; + }]; }]; - [self waitForExpectationsWithTimeout:2 handler:^(NSError * _Nullable error) { + [self waitForExpectationsWithTimeout:2 handler:^(NSError *_Nullable error) { XCTAssertNil(error); }]; - [FBSDKSettings setClientToken:nil]; } -*/ @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index a9a6b6d3dd..bb4a0a789c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -67,6 +67,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKAppEventsUtility` class mock between tests @property (nullable, nonatomic, assign) id appEventsUtilityClassMock; +/// Used for sharing an `FBSDKAppLinkResolverRequestBuilder` class mock between tests +@property (nullable, assign) id appLinkResolverRequestBuilderMock; + /// Used for sharing an `FBSDKApplicationDelegate` class mock between tests @property (nullable, assign) id fbApplicationDelegateClassMock; @@ -76,6 +79,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing an `FBSDKGatekeeperManager` class mock between tests @property (nullable, assign) id gatekeeperManagerClassMock; +/// Used for sharing an `FBSDKGraphRequest` class mock between tests +@property (nullable, assign) id graphRequestMock; + /// Used for sharing an `NSBundle` class mock between tests @property (nullable, assign) id nsBundleClassMock; @@ -199,6 +205,12 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKAppEventsUtility.tokenStringToUseFor:` and returns the provided string - (void)stubAppEventsUtilityTokenStringToUseForTokenWith:(NSString *)tokenString; +/// Stubs `FBSDKGraphRequest.startWithCompletionHandler:` and returns the provided result, error and connection +- (void)stubGraphRequestWithResult:(id)result error:(nullable NSError *)error connection:(nullable FBSDKGraphRequestConnection *)connection; + +/// Stubs `FBSDKGraphRequest.startWithCompletionHandler:` and returns the provided result, error and connection +- (void)stubAppLinkResolverRequestBuilderWithIdiomSpecificField:(nullable NSString *)field; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 096597c75f..8fa2f62ede 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -73,6 +73,8 @@ - (void)setUp [self setUpTimeSpendDataMock]; [self setUpInternalUtilityMock]; [self setUpAdNetworkReporterMock]; + [self setUpAppLinkResolverRequestBuilderMock]; + [self setUpGraphRequestMock]; } - (void)tearDown @@ -132,6 +134,12 @@ - (void)tearDown [_adNetworkReporterClassMock stopMocking]; _adNetworkReporterClassMock = nil; + + [_appLinkResolverRequestBuilderMock stopMocking]; + _appLinkResolverRequestBuilderMock = nil; + + [_graphRequestMock stopMocking]; + _graphRequestMock = nil; } - (void)setUpSettingsMock @@ -225,6 +233,16 @@ - (void)setUpAdNetworkReporterMock self.adNetworkReporterClassMock = OCMClassMock(FBSDKSKAdNetworkReporter.class); } +- (void)setUpAppLinkResolverRequestBuilderMock +{ + _appLinkResolverRequestBuilderMock = OCMStrictClassMock(FBSDKAppLinkResolverRequestBuilder.class); +} + +- (void)setUpGraphRequestMock +{ + _graphRequestMock = OCMStrictClassMock(FBSDKGraphRequest.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID @@ -383,4 +401,23 @@ - (void)stubServerConfigurationFetchingWithConfiguration:(nullable FBSDKServerCo OCMStub(ClassMethod([_serverConfigurationManagerClassMock loadServerConfigurationWithCompletionBlock:OCMArg.isNil])); } +- (void)stubGraphRequestWithResult:(id)result error:(nullable NSError *)error connection:(nullable FBSDKGraphRequestConnection *)connection +{ + OCMStub([_graphRequestMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:[self nsNullIfNil:connection], [self nsNullIfNil:result], [self nsNullIfNil:error], nil])]); +} + +- (void)stubAppLinkResolverRequestBuilderWithIdiomSpecificField:(nullable NSString *)field +{ + OCMStub([_appLinkResolverRequestBuilderMock getIdiomSpecificField]).andReturn(field); +} + +- (id)nsNullIfNil:(id)nilValue +{ + id converted = nilValue; + if (!nilValue) { + converted = [NSNull null]; + } + return converted; +} + @end From df3d295f80d71d0ce735ef5ff469919ce18ceb48 Mon Sep 17 00:00:00 2001 From: Xin Wu Date: Mon, 12 Oct 2020 15:05:32 -0700 Subject: [PATCH 025/227] Revert previous changes Summary: as title, revert D24107807 (https://github.com/facebook/facebook-ios-sdk/commit/95835b8676cb0e36fb307482cd8b7c1226308a05) Reason: we want to fix IG stall issues we received first. Will update iOS SDK correspondingly after IG fix has no issues. Reviewed By: dreamolight Differential Revision: D24262028 fbshipit-source-id: bdbe28180103c1d3eb0e3ed6adb8f473a5c05cac --- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 26 +++++++++---------- .../Internal/FBSDKAppEventsUtility.h | 1 - .../Internal/FBSDKAppEventsUtility.m | 11 -------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index 0e9c6282a7..ca27e40c2c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -965,8 +965,8 @@ - (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason FBSDKAppEventsState *copy = [_appEventsState copy]; _appEventsState = [[FBSDKAppEventsState alloc] initWithToken:copy.tokenString appID:copy.appID]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self flushOnBackgroundQueueWithDefaultPriority:copy forReason:flushReason]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self flushOnMainQueue:copy forReason:flushReason]; }); } } @@ -1316,8 +1316,8 @@ - (void)checkPersistedEvents if (self.flushBehavior == FBSDKAppEventsFlushBehaviorExplicitOnly) { [FBSDKAppEventsStateManager persistAppEventsData:saved]; } else { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self flushOnBackgroundQueueWithDefaultPriority:saved forReason:FBSDKAppEventsFlushReasonPersistedEvents]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self flushOnMainQueue:saved forReason:FBSDKAppEventsFlushReasonPersistedEvents]; }); } } @@ -1331,15 +1331,15 @@ - (void)checkPersistedEvents } } -- (void)flushOnBackgroundQueueWithDefaultPriority:(FBSDKAppEventsState *)appEventsState - forReason:(FBSDKAppEventsFlushReason)reason +- (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState + forReason:(FBSDKAppEventsFlushReason)reason { if (appEventsState.events.count == 0) { return; } if (appEventsState.appID.length == 0) { - [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents appEventsState.appID] for [FBSDKAppEvents flushOnBackgroundQueueWithDefaultPriority:]"]; + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Missing [FBSDKAppEvents appEventsState.appID] for [FBSDKAppEvents flushOnMainQueue:]"]; return; } @@ -1347,7 +1347,7 @@ - (void)flushOnBackgroundQueueWithDefaultPriority:(FBSDKAppEventsState *)appEven return; } - [FBSDKAppEventsUtility ensureNotOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; + [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; [self fetchServerConfiguration:^(void) { NSString *receipt_data = appEventsState.extractReceiptData; @@ -1399,11 +1399,9 @@ - (void)flushOnBackgroundQueueWithDefaultPriority:(FBSDKAppEventsState *)appEven flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [self handleActivitiesPostCompletion:error - loggingEntry:loggingEntry - appEventsState:(FBSDKAppEventsState *)appEventsState]; - }); + [self handleActivitiesPostCompletion:error + loggingEntry:loggingEntry + appEventsState:(FBSDKAppEventsState *)appEventsState]; }]; }]; } @@ -1418,7 +1416,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushResult) { FlushResultNoConnectivity, }; - [FBSDKAppEventsUtility ensureNotOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; + [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; FBSDKAppEventsFlushResult flushResult = FlushResultSuccess; if (error) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h index c545e818ee..a52202ed13 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.h @@ -51,7 +51,6 @@ NS_SWIFT_NAME(AppEventsUtility) shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID; + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)className; -+ (void)ensureNotOnMainThread:(NSString *)methodName className:(NSString *)className; + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason; + (void)logAndNotify:(NSString *)msg allowLogAsDeveloperError:(BOOL)allowLogAsDeveloperError; + (void)logAndNotify:(NSString *)msg; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m index f30dbe6ae5..b0393d8b30 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEventsUtility.m @@ -196,17 +196,6 @@ + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)classNam ); } -+ (void)ensureNotOnMainThread:(NSString *)methodName className:(NSString *)className -{ - FBSDKConditionalLog( - [NSThread isMainThread] == NO, - FBSDKLoggingBehaviorDeveloperErrors, - @"*** <%@, %@> is called on main thread. This can lead to errors.", - methodName, - className - ); -} - + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason { NSString *result = @"Unknown"; From 9d3337366533ecdaff503acbb6b2d135aebc79cf Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 13 Oct 2020 13:42:15 -0700 Subject: [PATCH 026/227] Fix CircleCI job error about user interface idiom deprecation (#1520) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1520 CircleCI is failing with the error: ``` error: 'UI_USER_INTERFACE_IDIOM' is deprecated: first deprecated in macCatalyst 13.0 - Use -[UIDevice userInterfaceIdiom] directly. [-Werror,-Wdeprecated-declarations] ``` Differential Revision: D24265594 fbshipit-source-id: 35c3cc9a23e959552e0103e88e04dffa3693041a --- .../FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m | 5 +---- .../FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m | 4 ++-- .../AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m | 2 +- .../FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m index 1d02acf27e..d018943687 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m @@ -265,10 +265,7 @@ - (FBSDKAppLink *)appLinkFromALData:(NSDictionary *)appLinkDict NSMutableArray *linkTargets = [NSMutableArray array]; NSArray *platformData = nil; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - const UIUserInterfaceIdiom idiom = UI_USER_INTERFACE_IDIOM(); -#pragma clang diagnostic pop + const UIUserInterfaceIdiom idiom = UIDevice.currentDevice.userInterfaceIdiom; if (idiom == UIUserInterfaceIdiomPad) { platformData = @[ appLinkDict[FBSDKWebViewAppLinkResolverIPadKey] ?: @{}, appLinkDict[FBSDKWebViewAppLinkResolverIOSKey] ?: @{} ]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m index cd3291a618..e8c6041925 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolver.m @@ -83,7 +83,7 @@ - (instancetype)initWithRequestBuilder:(FBSDKAppLinkResolverRequestBuilder *)bui { if (self = [super init]) { self.cachedFBSDKAppLinks = [NSMutableDictionary dictionary]; - self.userInterfaceIdiom = UI_USER_INTERFACE_IDIOM(); + self.userInterfaceIdiom = UIDevice.currentDevice.userInterfaceIdiom; self.requestBuilder = builder; } return self; @@ -178,7 +178,7 @@ - (FBSDKAppLink *)buildAppLinkForURL:(NSURL *)url inResults:(id)result #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (instancetype)resolver { - return [[self alloc] initWithUserInterfaceIdiom:UI_USER_INTERFACE_IDIOM()]; + return [[self alloc] initWithUserInterfaceIdiom:UIDevice.currentDevice.userInterfaceIdiom]; } #pragma clang diagnostic pop diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m index 4cc6263cf9..38b29a9ac9 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/Resolver/FBSDKAppLinkResolverRequestBuilder.m @@ -50,7 +50,7 @@ - (instancetype)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceId - (instancetype)init { if ((self = [super init])) { - _userInterfaceIdiom = UI_USER_INTERFACE_IDIOM(); + _userInterfaceIdiom = UIDevice.currentDevice.userInterfaceIdiom; } return self; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m index 20ed7e20a1..d2fe53c42c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m @@ -116,7 +116,7 @@ - (void)layoutSubviews [super layoutSubviews]; CGRect bounds = self.bounds; - if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { CGFloat horizontalInset = CGRectGetWidth(bounds) * 0.2; CGFloat verticalInset = CGRectGetHeight(bounds) * 0.2; UIEdgeInsets iPadInsets = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset); From 44694182e5b3fd6f0ac7686a767c58d60db372df Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 14 Oct 2020 11:19:51 -0700 Subject: [PATCH 027/227] Fix Carthage for Xcode 12 (#1517) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1517 Fixes Carthage build for Xcode 12 by following script proposed in https://github.com/Carthage/Carthage/blob/master/Documentation/Xcode12Workaround.md Reviewed By: d16r Differential Revision: D24227997 fbshipit-source-id: 475b6dcff7347e895b0ae40a90169580310dad40 --- .circleci/config.yml | 2 +- Configurations/Configuration/Release.xcconfig | 6 ----- scripts/carthage.sh | 8 ++++++ scripts/exclude-architectures.sh | 26 +++++++++++++++++++ scripts/run.sh | 8 +++--- scripts/xcode/build-universal-framework.sh | 11 ++++++-- .../xcode/build-universal-tvos-framework.sh | 4 +++ 7 files changed, 52 insertions(+), 13 deletions(-) create mode 100755 scripts/carthage.sh create mode 100755 scripts/exclude-architectures.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 80701c2298..c71f909a20 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,7 +50,7 @@ commands: steps: - attach_workspace: at: . - - run: carthage build --no-skip-current + - run: CARTHAGE_BIN_PATH=$( which carthage ) sh scripts/carthage.sh build --no-skip-current build_for_release: description: Builds libraries for release diff --git a/Configurations/Configuration/Release.xcconfig b/Configurations/Configuration/Release.xcconfig index b0caa701f9..da37f53eba 100644 --- a/Configurations/Configuration/Release.xcconfig +++ b/Configurations/Configuration/Release.xcconfig @@ -36,9 +36,3 @@ ENABLE_TESTABILITY = YES // MTL MTL_ENABLE_DEBUG_INFO = NO - -// Excluding arm64 in Release builds for simulator allows creation of x86_64 slice -// when building with Xcode12. May need to revisit this as Apple Silicon gains adoption. -// Also see: https://github.com/Carthage/Carthage/issues/3019 -EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 -EXCLUDED_ARCHS[sdk=appletvsimulator*] = arm64 diff --git a/scripts/carthage.sh b/scripts/carthage.sh new file mode 100755 index 0000000000..8cf6495c77 --- /dev/null +++ b/scripts/carthage.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# carthage.sh + +# shellcheck disable=SC1091 +# shellcheck source=exclude-architectures.sh +. "$(dirname "$0")/exclude-architectures.sh" + +"$CARTHAGE_BIN_PATH" "$@" diff --git a/scripts/exclude-architectures.sh b/scripts/exclude-architectures.sh new file mode 100755 index 0000000000..6b150aa3b1 --- /dev/null +++ b/scripts/exclude-architectures.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# carthage.sh +# Xcode 12 workaround. +# See: https://github.com/Carthage/Carthage/blob/master/Documentation/Xcode12Workaround.md +# +# Usage example: ./carthage.sh build --platform iOS + +set -euo pipefail + +xcconfig=$(mktemp /tmp/static.xcconfig.XXXXXX) +trap 'rm -f "$xcconfig"' INT TERM HUP EXIT + +# For Xcode 12 make sure EXCLUDED_ARCHS is set to arm architectures otherwise +# the build will fail on lipo due to duplicate architectures. + +CURRENT_XCODE_VERSION=$(xcodebuild -version | grep "Build version" | cut -d' ' -f3) + +# Disabling check since Xcode will be expanding vars +# shellcheck disable=SC2016 +{ + echo "EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200__BUILD_$CURRENT_XCODE_VERSION = arm64 arm64e armv7 armv7s armv6 armv8 i386" + echo 'EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200 = $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64__XCODE_1200__BUILD_$(XCODE_PRODUCT_BUILD_VERSION))' + echo 'EXCLUDED_ARCHS = $(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT)__XCODE_$(XCODE_VERSION_MAJOR))' +} >> "$xcconfig" + +export XCODE_XCCONFIG_FILE="$xcconfig" diff --git a/scripts/run.sh b/scripts/run.sh index 3f62611c03..cf3d424929 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -287,10 +287,10 @@ build_sdk() { } build_carthage() { - carthage build --no-skip-current + CARTHAGE_BIN_PATH=$( which carthage ) sh scripts/carthage.sh build --no-skip-current if [ "${1:-}" == "--archive" ]; then - carthage archive --output Carthage/Release/ + CARTHAGE_BIN_PATH=$( which carthage ) sh scripts/carthage.sh archive --output Carthage/Release/ fi } @@ -434,8 +434,8 @@ release_sdk() { # Release frameworks in dynamic (mostly for Carthage) release_dynamic() { - carthage build --no-skip-current - carthage archive --output build/Release/ + CARTHAGE_BIN_PATH=$( which carthage ) sh scripts/carthage.sh build --no-skip-current + CARTHAGE_BIN_PATH=$( which carthage ) sh scripts/carthage.sh archive --output build/Release/ mv build/Release/FBSDKCoreKit.framework.zip build/Release/FacebookSDK_Dynamic.framework.zip } diff --git a/scripts/xcode/build-universal-framework.sh b/scripts/xcode/build-universal-framework.sh index 648bc3175c..e16d9b538c 100755 --- a/scripts/xcode/build-universal-framework.sh +++ b/scripts/xcode/build-universal-framework.sh @@ -21,6 +21,10 @@ # Main Script # -------------- +# shellcheck disable=SC1091 +# shellcheck source=exclude-architectures.sh +. "${SOURCE_ROOT}/../scripts/exclude-architectures.sh" + UNIVERSAL_BUILD_FOLDER=../build/ # make the output directory and delete the framework directory @@ -51,8 +55,11 @@ xcodebuild -target "${TARGET}" \ cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_BUILD_FOLDER}/" # Step 3. Copy the swiftmodule files created during the simulator build -rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" \ - "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" +# TODO: remove the conditional check when we drop support for Xcode 11 +if [ -f "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" ]; then + rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" \ + "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" +fi # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory lipo -create -output "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" diff --git a/scripts/xcode/build-universal-tvos-framework.sh b/scripts/xcode/build-universal-tvos-framework.sh index d4768edd9f..4f43bdff1d 100755 --- a/scripts/xcode/build-universal-tvos-framework.sh +++ b/scripts/xcode/build-universal-tvos-framework.sh @@ -21,6 +21,10 @@ # Main Script # -------------- +# shellcheck disable=SC1091 +# shellcheck source=exclude-architectures.sh +. "${SOURCE_ROOT}/../scripts/exclude-architectures.sh" + UNIVERSAL_TV_BUILD_FOLDER=../build/tv/ # make the output directory and delete the framework directory From 6dedbbd5b3f4d486d826bc21b0346bf1a5349bea Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 15 Oct 2020 13:13:08 -0700 Subject: [PATCH 028/227] Fix Rsync Step (#1525) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1525 I made some faulty assumptions about why I was getting an rsync warning so I gated it behind a file check. This led to a false positive where it appeared that the files were being synced when they were not. This updated code ignores the output of the step when it fails since it will fail for GamingServicesKit (because it contains no Swift files at the moment). Reviewed By: tianqibt, dreamolight Differential Revision: D24339344 fbshipit-source-id: fe5eccaf4e6bf379eb8b2f2ceffbf3d11fd0e65f --- scripts/xcode/build-universal-framework.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/xcode/build-universal-framework.sh b/scripts/xcode/build-universal-framework.sh index e16d9b538c..c3c774ef3c 100755 --- a/scripts/xcode/build-universal-framework.sh +++ b/scripts/xcode/build-universal-framework.sh @@ -55,11 +55,8 @@ xcodebuild -target "${TARGET}" \ cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_BUILD_FOLDER}/" # Step 3. Copy the swiftmodule files created during the simulator build -# TODO: remove the conditional check when we drop support for Xcode 11 -if [ -f "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" ]; then - rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" \ - "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" -fi +rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" \ + "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" || true # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory lipo -create -output "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" From 584f77c852b3172a00a635f3203631d7c744cf11 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 16 Oct 2020 08:42:33 -0700 Subject: [PATCH 029/227] Make Basics an actual dependency 1/n Summary: ## Context: In terms of BUCK, CocoaPods and Swift Package Manager, CoreKitBasics is its own module. Even in terms of xcodeproj it's its own target. This formalizes that dependency relationship. ## Why do this? This allows us to avoid a lot of the messiness where we have something like: ``` #if defined FBSDKCOCOAPODS #import #elif defined BUCK #import #else #import "FBSDKCoreKit_Basics.h" #endif ``` Now we can just do: ``` #import ``` and it will "just work" ## This diff Adds two new config files so that Basics is able to be imported as it's own library. This means we can import with `` Reviewed By: dreamolight Differential Revision: D24179750 fbshipit-source-id: 75c04b3f01552421b6f16560909f501f3c56d777 --- .../FBSDKCoreKit_Basics-Dynamic.xcconfig | 30 +++++++++++++++++++ .../FBSDKCoreKit_Basics.xcconfig | 28 +++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig create mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig new file mode 100644 index 0000000000..41b967ed71 --- /dev/null +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig @@ -0,0 +1,30 @@ +// 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. + +#include "Shared/Platform/iOS.xcconfig" +#include "Shared/Target/DynamicFramework.xcconfig" +#include "Shared/Version.xcconfig" + +PRODUCT_NAME = FBSDKCoreKit_Basics +PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics + +CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) + +INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist + +IPHONEOS_DEPLOYMENT_TARGET = 9.0 diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig new file mode 100644 index 0000000000..5bea63d45a --- /dev/null +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig @@ -0,0 +1,28 @@ +// 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. + +#include "Shared/Platform/iOS.xcconfig" +#include "Shared/Target/StaticFramework.xcconfig" +#include "Shared/Version.xcconfig" + +PRODUCT_NAME = FBSDKCoreKit_Basics +PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics + +CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) + +INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist From 1a8aa340817538fd560d8c2852fb1a28acf39c8e Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 16 Oct 2020 08:42:33 -0700 Subject: [PATCH 030/227] Make Basics an actual dependency 2/n (#1526) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1526 ## Context: In terms of BUCK, CocoaPods and Swift Package Manager, CoreKitBasics is its own module. Even in terms of xcodeproj it's its own target. This formalizes that dependency relationship. ## Why do this? This allows us to avoid a lot of the messiness where we have something like: ``` #if defined FBSDKCOCOAPODS #import #elif defined BUCK #import #else #import "FBSDKCoreKit_Basics.h" #endif ``` Now we can just do: ``` #import ``` and it will "just work" **Correction**: CocoaPods considers anything in a podspec to be part of the same module. Either future work will be needed to publish basics as its own module or we'll have to live with fragmented header imports. So really the why do this comes down to having the correct code boundaries. In CocoaPods this is a subspec but in other areas it's on the module/product/target level. ## This diff Adds FBSDKCoreKit basics as a linked dependency to the other kits. This relationship is not new but it was previously hidden by having Basics source files added to the other CoreKit targets. This also fixes the CoreKit+Internal dependency to depend on the library instead of just importing the header. Reviewed By: dreamolight Differential Revision: D24179749 fbshipit-source-id: 32a9332a2d0319c1d7579a28895d9d102dec0505 --- .../FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig | 28 ++ .../FBSDKCoreKit_Basics-tvOS.xcconfig | 28 ++ .../FBSDKCoreKit.xcodeproj/project.pbxproj | 347 ++++++++++++------ .../Internal/FBSDKCoreKit+Internal.h | 7 +- .../project.pbxproj | 28 +- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 18 +- .../FBSDKShareKit.xcodeproj/project.pbxproj | 12 +- scripts/xcode/build-universal-framework.sh | 13 +- .../xcode/build-universal-tvos-framework.sh | 9 +- 9 files changed, 328 insertions(+), 162 deletions(-) create mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig create mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig new file mode 100644 index 0000000000..58adbacc24 --- /dev/null +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig @@ -0,0 +1,28 @@ +// 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. + +#include "Shared/Platform/tvOS.xcconfig" +#include "Shared/Target/DynamicFramework.xcconfig" +#include "Shared/Version.xcconfig" + +PRODUCT_NAME = FBSDKCoreKit_Basics +PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics + +CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) + +INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig new file mode 100644 index 0000000000..97f7c38772 --- /dev/null +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig @@ -0,0 +1,28 @@ +// 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. + +#include "Shared/Platform/tvOS.xcconfig" +#include "Shared/Target/StaticFramework.xcconfig" +#include "Shared/Version.xcconfig" + +PRODUCT_NAME = FBSDKCoreKit_Basics +PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics + +CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) + +INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index fd9e8d14bb..41f0eec158 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -747,18 +747,8 @@ C5696FA8209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; C5696FA9209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; C5696FAA209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; - C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D724E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; - C57044D824E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; - C57044D924E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; - C57044DA24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; C57044DB24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; C57044DC24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; C57044DD24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; @@ -829,6 +819,33 @@ F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */; }; F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.m */; }; + F4583A7B252E62050051E280 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4583A7A252E62050051E280 /* UIKit.framework */; }; + F4583A7C252E620C0051E280 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F4583A78252E61DB0051E280 /* libz.tbd */; }; + F4583A83252E641F0051E280 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F4583A87252E64E00051E280 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A88252E64E00051E280 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A89252E64E00051E280 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A8A252E64E00051E280 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A8B252E64E00051E280 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A8C252E64E00051E280 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A8D252E64E00051E280 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A8E252E64E00051E280 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A8F252E64E00051E280 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A90252E64E00051E280 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A91252E64E00051E280 /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A92252E65110051E280 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A93252E65110051E280 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A94252E65110051E280 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A95252E65110051E280 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A96252E65110051E280 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A97252E65110051E280 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A98252E65110051E280 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A99252E65110051E280 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A9A252E65120051E280 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A9B252E65120051E280 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583A9C252E65120051E280 /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4583AC3252E7D350051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */; }; + F4583AC9252E7F850051E280 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B71DA31D19C87400933E93 /* FBSDKCoreKit.framework */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -854,50 +871,26 @@ F468B2A124C2457000979F8D /* FBSDKRestrictiveData.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */; }; F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; F468B2A724C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; - F468B30A24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; - F468B30B24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; - F468B30C24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; - F468B30D24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B30E24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B30F24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B31024C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B31124C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; - F468B31A24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; - F468B31B24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; - F468B31C24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; - F468B31D24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B31E24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B31F24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B32024C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B32124C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; - F468B32224C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; - F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; - F468B32424C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; - F468B32524C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32624C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32724C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32824C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32924C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; - F468B34224C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; - F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; - F468B34424C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; - F468B34524C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34624C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34724C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34824C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34924C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; - F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; - F468B34B24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; - F468B34C24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; - F468B34D24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B34E24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B34F24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B35024C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B35124C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; - F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; - F468B35324C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; - F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; - F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35624C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35724C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35824C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; @@ -948,6 +941,30 @@ F4BF22AA241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; + F4C39A4F2538E79A00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39A5C2538E79B00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39BC32538EE7C00A04DA3 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F4C39BD32538EEEB00A04DA3 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F4C39BD22538EEE100A04DA3 /* libz.tbd */; }; + F4C39BF52538EF0000A04DA3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4C39BF42538EF0000A04DA3 /* UIKit.framework */; }; + F4C39C0D2538EFA000A04DA3 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */; }; + F4C39C3B2538FC4600A04DA3 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C5C2538FC4700A04DA3 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C7E2538FC6E00A04DA3 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C7F2538FC6E00A04DA3 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C802538FC6E00A04DA3 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C812538FC6E00A04DA3 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C822538FC6E00A04DA3 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C832538FC6E00A04DA3 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C842538FC6E00A04DA3 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C852538FC6E00A04DA3 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C912538FC7000A04DA3 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C922538FC7000A04DA3 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C932538FC7000A04DA3 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C942538FC7000A04DA3 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C952538FC7000A04DA3 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C962538FC7000A04DA3 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C972538FC7000A04DA3 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4C39C982538FC7000A04DA3 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4D8D8DC2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DD2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; @@ -961,24 +978,14 @@ F4E50155243648A100C99262 /* FBSDKServerConfigurationFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */; }; F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */; }; F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */; }; - F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; - F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; - F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; - F4F98C5624CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5724CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5824CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5924CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5A24CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; - F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; - F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; - F4FE998124D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; - F4FE998224D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998324D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998424D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998524D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998624D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; - F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; - F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */; }; @@ -1198,15 +1205,68 @@ remoteGlobalIDString = C5C4B3BE2276B67200CA3706; remoteInfo = FBSDKCoreKit_Basics_TV; }; - F410D0332370CBC2005B9318 /* PBXContainerItemProxy */ = { + F4583A69252E5FBD0051E280 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; + proxyType = 1; + remoteGlobalIDString = C5C4B2E62276B51500CA3706; + remoteInfo = FBSDKCoreKit_Basics; + }; + F4583AC7252E7D8B0051E280 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; proxyType = 1; remoteGlobalIDString = 81B71CFC1D19C87400933E93; remoteInfo = "FBSDKCoreKit-Dynamic"; }; + F4583ACC252E85080051E280 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; + proxyType = 1; + remoteGlobalIDString = C5C4B2E62276B51500CA3706; + remoteInfo = FBSDKCoreKit_Basics; + }; + F4C39BC42538EE7C00A04DA3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; + proxyType = 1; + remoteGlobalIDString = C5C4B3BE2276B67200CA3706; + remoteInfo = FBSDKCoreKit_Basics_TV; + }; + F4C39C192538FB6B00A04DA3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; + proxyType = 1; + remoteGlobalIDString = C5C4B4DC2276BA8D00CA3706; + remoteInfo = "FBSDKCoreKit_Basics_TV-Dynamic"; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + F4583A86252E641F0051E280 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F4583A83252E641F0051E280 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F4C39BC62538EE7C00A04DA3 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F4C39BC32538EE7C00A04DA3 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 033429B020894D4700C94913 /* FBSDKAccessTokenExpirer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessTokenExpirer.h; sourceTree = ""; }; 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessTokenExpirer.m; sourceTree = ""; }; @@ -1508,10 +1568,10 @@ C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSwizzler.m; sourceTree = ""; }; C57044CD24E26678009637AD /* FBSDKUserDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKUserDataStore.h; sourceTree = ""; }; C57044CE24E26678009637AD /* FBSDKUserDataStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUserDataStore.m; sourceTree = ""; }; - C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKFeatureManager.h; sourceTree = ""; }; C5C7B74922D84F64004A5A0C /* FBSDKFeatureManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKFeatureManager.m; sourceTree = ""; }; C5D25D3421795B790037B13D /* FBSDKCodelessIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCodelessIndexer.h; sourceTree = ""; }; @@ -1542,6 +1602,10 @@ F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationManagerTests.m; sourceTree = ""; }; F43960CE2425513100C1868F /* FakeMonitorStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeMonitorStore.h; sourceTree = ""; }; F43960CF2425513100C1868F /* FakeMonitorStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeMonitorStore.m; sourceTree = ""; }; + F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKCoreKit_Basics-Dynamic.xcconfig"; sourceTree = ""; }; + F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FBSDKCoreKit_Basics.xcconfig; sourceTree = ""; }; + F4583A78252E61DB0051E280 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + F4583A7A252E62050051E280 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.7.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKBasicUtility.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKBasicUtility.h; sourceTree = ""; }; F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCoreKit_Basics.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCoreKit_Basics.h; sourceTree = ""; }; F468B22024C2399800979F8D /* FBSDKCrashObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCrashObserving.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCrashObserving.h; sourceTree = ""; }; @@ -1608,6 +1672,10 @@ F4BF2292241954B400BFB494 /* FBSDKMonitorStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStoreTests.m; sourceTree = ""; }; F4BF22A1241954D800BFB494 /* FBSDKMonitorStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorStore.h; sourceTree = ""; }; F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStore.m; sourceTree = ""; }; + F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig"; sourceTree = ""; }; + F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKCoreKit_Basics-tvOS.xcconfig"; sourceTree = ""; }; + F4C39BD22538EEE100A04DA3 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; + F4C39BF42538EF0000A04DA3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorNetworker.h; sourceTree = ""; }; F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworker.m; sourceTree = ""; }; F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworkerTests.m; sourceTree = ""; }; @@ -1673,6 +1741,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F4C39C0D2538EFA000A04DA3 /* FBSDKCoreKit_Basics.framework in Frameworks */, F9FFE01F2252D66E007B2346 /* libz.tbd in Frameworks */, F9A18071252150610062E634 /* AdSupport.framework in Frameworks */, 4AF47D131F424A8700A57A67 /* CoreImage.framework in Frameworks */, @@ -1685,6 +1754,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F4583AC3252E7D350051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */, F9A80C9E237D02860019D7E0 /* Accelerate.framework in Frameworks */, F9A180732521506C0062E634 /* AdSupport.framework in Frameworks */, C52C02ED2315039400F30E2A /* WebKit.framework in Frameworks */, @@ -1709,6 +1779,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F4583AC9252E7F850051E280 /* FBSDKCoreKit.framework in Frameworks */, FDB2B4F32398D73D00AE087E /* Accelerate.framework in Frameworks */, 7E55576C1A8EAC7D00344F86 /* libOHHTTPStubs.a in Frameworks */, 9DAD87761A8AA75700FFA324 /* libOCMock.a in Frameworks */, @@ -1744,6 +1815,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F4583A7C252E620C0051E280 /* libz.tbd in Frameworks */, + F4583A7B252E62050051E280 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1751,6 +1824,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F4C39BD32538EEEB00A04DA3 /* libz.tbd in Frameworks */, + F4C39BF52538EF0000A04DA3 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1925,10 +2000,14 @@ 81A4A6011D19BE0400D5BF66 /* Configurations */ = { isa = PBXGroup; children = ( - 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */, - 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */, + F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */, + F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */, 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */, 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */, + F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */, + 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */, + F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */, + 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */, 814AC8CB1D1B5CAC00D61E6C /* FBSDKCoreKitTests.xcconfig */, 81A4A6041D19BE0400D5BF66 /* Shared */, ); @@ -2024,6 +2103,10 @@ 893F44A31A644536001DB0B6 /* Frameworks */ = { isa = PBXGroup; children = ( + F4C39BF42538EF0000A04DA3 /* UIKit.framework */, + F4C39BD22538EEE100A04DA3 /* libz.tbd */, + F4583A7A252E62050051E280 /* UIKit.framework */, + F4583A78252E61DB0051E280 /* libz.tbd */, F9A18062252150610062E634 /* AdSupport.framework */, F9A180722521506C0062E634 /* AdSupport.framework */, F9A80C9D237D02860019D7E0 /* Accelerate.framework */, @@ -2264,10 +2347,10 @@ 9DB0FA731BC1CA71005EB8B1 /* FBSDKCoreKit.framework */, 81B71DA31D19C87400933E93 /* FBSDKCoreKit.framework */, 814AC8571D1B528900D61E6C /* FBSDKCoreKit.framework */, - C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */, - C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */, - C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */, - C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */, + C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */, + C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */, + C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit_Basics.framework */, + C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */, ); name = Products; sourceTree = ""; @@ -2858,7 +2941,6 @@ 814AC8411D1B528900D61E6C /* FBSDKDynamicFrameworkLoader.h in Headers */, 814AC8421D1B528900D61E6C /* FBSDKServerConfiguration.h in Headers */, 814AC8431D1B528900D61E6C /* FBSDKGraphRequestPiggybackManager.h in Headers */, - C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */, 814AC8441D1B528900D61E6C /* FBSDKAppEventsUtility.h in Headers */, 5D90CDE92343D4D200AF326A /* FBSDKCrashShield.h in Headers */, 814AC8471D1B528900D61E6C /* FBSDKCopying.h in Headers */, @@ -3005,7 +3087,6 @@ 81B71D901D19C87400933E93 /* FBSDKSettings.h in Headers */, 81B71D911D19C87400933E93 /* FBSDKServerConfiguration.h in Headers */, F468B23524C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, - C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */, BFC02456237B6B9300A596EE /* FBSDKModelRuntime.hpp in Headers */, 81B71D921D19C87400933E93 /* FBSDKAppEventsStateManager.h in Headers */, 81B71D931D19C87400933E93 /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -3152,7 +3233,6 @@ F468B23424C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, FD9E154D23777AC900A005EC /* FBSDKModelRuntime.hpp in Headers */, 9D0BC1571A8D23E200BE8BA4 /* FBSDKAppEvents.h in Headers */, - C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */, 9DC658951A6EE5C500B85AAF /* FBSDKGraphRequest.h in Headers */, C5188DF9222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */, 894C0AF61A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */, @@ -3247,7 +3327,6 @@ 81C969331C114723002FC037 /* FBSDKDynamicFrameworkLoader.h in Headers */, 9D6DEED01BC23A71001A94ED /* FBSDKServerConfiguration.h in Headers */, 9DB0FAA81BC22D6A005EB8B1 /* FBSDKGraphRequestPiggybackManager.h in Headers */, - C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */, 9DB0FA8C1BC1CEEC005EB8B1 /* FBSDKAppEventsUtility.h in Headers */, 5D90CDE82343D4D200AF326A /* FBSDKCrashShield.h in Headers */, 9DB0FA821BC1CB93005EB8B1 /* FBSDKCopying.h in Headers */, @@ -3278,8 +3357,17 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, - C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */, + F4583A8F252E64E00051E280 /* FBSDKCoreKit_Basics.h in Headers */, + F4583A87252E64E00051E280 /* FBSDKTypeUtility.h in Headers */, + F4583A88252E64E00051E280 /* FBSDKURLSessionTask.h in Headers */, + F4583A89252E64E00051E280 /* FBSDKSafeCast.h in Headers */, + F4583A8A252E64E00051E280 /* FBSDKCrashHandler.h in Headers */, + F4583A8B252E64E00051E280 /* FBSDKLibAnalyzer.h in Headers */, + F4583A8C252E64E00051E280 /* FBSDKBasicUtility.h in Headers */, + F4583A8D252E64E00051E280 /* FBSDKJSONValue.h in Headers */, + F4583A8E252E64E00051E280 /* FBSDKURLSession.h in Headers */, + F4583A90252E64E00051E280 /* FBSDKCrashObserving.h in Headers */, + F4583A91252E64E00051E280 /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3288,7 +3376,17 @@ buildActionMask = 2147483647; files = ( F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + F4C39C842538FC6E00A04DA3 /* FBSDKCrashHandler.h in Headers */, + F4C39C812538FC6E00A04DA3 /* FBSDKSafeCast.h in Headers */, + F4C39C3B2538FC4600A04DA3 /* FBSDKBasicUtility.h in Headers */, + F4C39C832538FC6E00A04DA3 /* FBSDKJSONValue.h in Headers */, C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */, + F4C39C822538FC6E00A04DA3 /* FBSDKURLSession.h in Headers */, + F4C39C7F2538FC6E00A04DA3 /* FBSDKURLSessionTask.h in Headers */, + F4C39A4F2538E79A00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */, + F4C39C7E2538FC6E00A04DA3 /* FBSDKCrashObserving.h in Headers */, + F4C39C802538FC6E00A04DA3 /* FBSDKTypeUtility.h in Headers */, + F4C39C852538FC6E00A04DA3 /* FBSDKLibAnalyzer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3296,8 +3394,17 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, - C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */, + F4583A9A252E65120051E280 /* FBSDKCoreKit_Basics.h in Headers */, + F4583A92252E65110051E280 /* FBSDKTypeUtility.h in Headers */, + F4583A93252E65110051E280 /* FBSDKURLSessionTask.h in Headers */, + F4583A94252E65110051E280 /* FBSDKSafeCast.h in Headers */, + F4583A95252E65110051E280 /* FBSDKCrashHandler.h in Headers */, + F4583A96252E65110051E280 /* FBSDKLibAnalyzer.h in Headers */, + F4583A97252E65110051E280 /* FBSDKBasicUtility.h in Headers */, + F4583A98252E65110051E280 /* FBSDKJSONValue.h in Headers */, + F4583A99252E65110051E280 /* FBSDKURLSession.h in Headers */, + F4583A9B252E65120051E280 /* FBSDKCrashObserving.h in Headers */, + F4583A9C252E65120051E280 /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3306,7 +3413,17 @@ buildActionMask = 2147483647; files = ( F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + F4C39C972538FC7000A04DA3 /* FBSDKCrashHandler.h in Headers */, + F4C39C942538FC7000A04DA3 /* FBSDKSafeCast.h in Headers */, + F4C39C5C2538FC4700A04DA3 /* FBSDKBasicUtility.h in Headers */, + F4C39C962538FC7000A04DA3 /* FBSDKJSONValue.h in Headers */, C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */, + F4C39C952538FC7000A04DA3 /* FBSDKURLSession.h in Headers */, + F4C39C922538FC7000A04DA3 /* FBSDKURLSessionTask.h in Headers */, + F4C39A5C2538E79B00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */, + F4C39C912538FC7000A04DA3 /* FBSDKCrashObserving.h in Headers */, + F4C39C932538FC7000A04DA3 /* FBSDKTypeUtility.h in Headers */, + F4C39C982538FC7000A04DA3 /* FBSDKLibAnalyzer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3321,10 +3438,12 @@ 814AC8141D1B528900D61E6C /* Frameworks */, 814AC8161D1B528900D61E6C /* Headers */, 814AC8531D1B528900D61E6C /* Resources */, + F4C39BC62538EE7C00A04DA3 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( + F4C39BC52538EE7C00A04DA3 /* PBXTargetDependency */, ); name = "FBSDKCoreKit_TV-Dynamic"; productName = "FBSDKCoreKit (TV)"; @@ -3339,10 +3458,12 @@ 81B71D451D19C87400933E93 /* Frameworks */, 81B71D471D19C87400933E93 /* Headers */, 81B71D9F1D19C87400933E93 /* Resources */, + F4583A86252E641F0051E280 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( + F4583ACD252E85080051E280 /* PBXTargetDependency */, ); name = "FBSDKCoreKit-Dynamic"; productName = FBSDKCoreKit; @@ -3362,6 +3483,7 @@ buildRules = ( ); dependencies = ( + F4583A6A252E5FBD0051E280 /* PBXTargetDependency */, ); name = FBSDKCoreKit; productName = FBSDKCoreKit; @@ -3379,7 +3501,7 @@ buildRules = ( ); dependencies = ( - F410D0342370CBC2005B9318 /* PBXTargetDependency */, + F4583AC8252E7D8B0051E280 /* PBXTargetDependency */, 9DAD79FB1B7B27DE00DFEF8F /* PBXTargetDependency */, ); name = FBSDKCoreKitTests; @@ -3399,6 +3521,7 @@ buildRules = ( ); dependencies = ( + F4C39C1A2538FB6B00A04DA3 /* PBXTargetDependency */, ); name = FBSDKCoreKit_TV; productName = "FBSDKCoreKit (TV)"; @@ -3420,7 +3543,7 @@ ); name = FBSDKCoreKit_Basics; productName = FBSDKCoreKit; - productReference = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */; + productReference = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */; productType = "com.apple.product-type.framework"; }; C5C4B3BE2276B67200CA3706 /* FBSDKCoreKit_Basics_TV */ = { @@ -3438,7 +3561,7 @@ ); name = FBSDKCoreKit_Basics_TV; productName = FBSDKCoreKit; - productReference = C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */; + productReference = C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */; productType = "com.apple.product-type.framework"; }; C5C4B4012276BA1200CA3706 /* FBSDKCoreKit_Basics-Dynamic */ = { @@ -3456,7 +3579,7 @@ ); name = "FBSDKCoreKit_Basics-Dynamic"; productName = FBSDKCoreKit; - productReference = C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */; + productReference = C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit_Basics.framework */; productType = "com.apple.product-type.framework"; }; C5C4B4DC2276BA8D00CA3706 /* FBSDKCoreKit_Basics_TV-Dynamic */ = { @@ -3474,7 +3597,7 @@ ); name = "FBSDKCoreKit_Basics_TV-Dynamic"; productName = FBSDKCoreKit; - productReference = C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */; + productReference = C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -3800,19 +3923,16 @@ 814AC7E41D1B528900D61E6C /* FBSDKAppEventsUtility.m in Sources */, 814AC7E51D1B528900D61E6C /* FBSDKServerConfigurationManager.m in Sources */, 814AC7E61D1B528900D61E6C /* FBSDKAccessTokenCache.m in Sources */, - F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E323219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 814AC7E71D1B528900D61E6C /* FBSDKUtility.m in Sources */, 814AC7E81D1B528900D61E6C /* FBSDKBase64.m in Sources */, F420D1912433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, - F468B34524C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 814AC7E91D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 814AC7EA1D1B528900D61E6C /* FBSDKGraphRequestMetadata.m in Sources */, 814AC7EB1D1B528900D61E6C /* FBSDKServerConfiguration.m in Sources */, 814AC7EC1D1B528900D61E6C /* FBSDKDynamicFrameworkLoader.m in Sources */, F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 814AC7ED1D1B528900D61E6C /* FBSDKDialogConfiguration.m in Sources */, - F468B30D24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 814AC7EE1D1B528900D61E6C /* FBSDKKeychainStoreViaBundleID.m in Sources */, FD147F672387215A000B216E /* FBSDKRestrictiveDataFilterManager.m in Sources */, 814AC7EF1D1B528900D61E6C /* FBSDKInternalUtility.m in Sources */, @@ -3821,7 +3941,6 @@ 814AC7F11D1B528900D61E6C /* FBSDKDeviceViewControllerBase.m in Sources */, F4A52B17242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */, 814AC7F21D1B528900D61E6C /* FBSDKAppEventsState.m in Sources */, - F4FE998224D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 814AC7F31D1B528900D61E6C /* FBSDKPaymentObserver.m in Sources */, F9FD9A8021659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, @@ -3840,26 +3959,21 @@ F42004982416C30300AD7006 /* FBSDKMonitor.m in Sources */, 814AC7FC1D1B528900D61E6C /* FBSDKAccessToken.m in Sources */, 814AC7FD1D1B528900D61E6C /* FBSDKGraphRequestBody.m in Sources */, - F468B34D24C25AB600979F8D /* FBSDKURLSession.m in Sources */, C5C7B75122D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, 814AC7FE1D1B528900D61E6C /* FBSDKErrorConfiguration.m in Sources */, F9A06DD62510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, C554DB1A2304D11A00A32E8B /* FBSDKErrorReport.m in Sources */, 814AC7FF1D1B528900D61E6C /* FBSDKViewImpressionTracker.m in Sources */, 814AC8001D1B528900D61E6C /* FBSDKSettings.m in Sources */, - F468B31D24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 814AC8021D1B528900D61E6C /* FBSDKAppEvents.m in Sources */, 814AC8031D1B528900D61E6C /* FBSDKTestUsersManager.m in Sources */, C5696FAA209CCEB4009C931F /* FBSDKSwizzler.m in Sources */, 814AC8041D1B528900D61E6C /* FBSDKGraphRequest.m in Sources */, 52D4F0D21D91A18F0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 814AC8051D1B528900D61E6C /* FBSDKLogo.m in Sources */, - F4F98C5624CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, - C57044DA24E26678009637AD /* FBSDKUserDataStore.m in Sources */, 814AC8061D1B528900D61E6C /* FBSDKDeviceButton.m in Sources */, 814AC8071D1B528900D61E6C /* FBSDKGraphRequestConnection.m in Sources */, F9A06DCA2510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, - F468B32524C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 814AC8081D1B528900D61E6C /* FBSDKErrorRecoveryConfiguration.m in Sources */, 814AC8091D1B528900D61E6C /* FBSDKApplicationDelegate.m in Sources */, 814AC80B1D1B528900D61E6C /* FBSDKDeviceDialogView.m in Sources */, @@ -3888,14 +4002,12 @@ 81B71D051D19C87400933E93 /* FBSDKContainerViewController.m in Sources */, 81B71D061D19C87400933E93 /* FBSDKAccessTokenCache.m in Sources */, 81B71D071D19C87400933E93 /* FBSDKCrypto.m in Sources */, - F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 81B71D081D19C87400933E93 /* FBSDKAppEventsState.m in Sources */, 52963A87215992F400C7B252 /* FBSDKWebViewAppLinkResolver.m in Sources */, 81B71D091D19C87400933E93 /* FBSDKCloseIcon.m in Sources */, F4BF22AA241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 5D41131B229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m in Sources */, 81B71D0A1D19C87400933E93 /* FBSDKBase64.m in Sources */, - F468B34B24C25AB600979F8D /* FBSDKURLSession.m in Sources */, 81B71D0B1D19C87400933E93 /* FBSDKBridgeAPIProtocolWebV2.m in Sources */, 81B71D0C1D19C87400933E93 /* FBSDKGraphRequestBody.m in Sources */, F943110524F8D615002441F1 /* FBSDKSKAdNetworkRule.m in Sources */, @@ -3929,11 +4041,9 @@ 81B71D1D1D19C87400933E93 /* FBSDKBridgeAPIRequest.m in Sources */, 81B71D1E1D19C87400933E93 /* FBSDKAppEventsDeviceInfo.m in Sources */, F42004962416C30300AD7006 /* FBSDKMonitor.m in Sources */, - F468B31B24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 81B71D1F1D19C87400933E93 /* FBSDKError.m in Sources */, 81B71D231D19C87400933E93 /* FBSDKAudioResourceLoader.m in Sources */, 81B71D241D19C87400933E93 /* FBSDKLogo.m in Sources */, - F468B35324C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, F4210E35241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 81B71D251D19C87400933E93 /* FBSDKPaymentObserver.m in Sources */, 81B71D261D19C87400933E93 /* FBSDKBridgeAPIResponse.m in Sources */, @@ -3948,7 +4058,6 @@ C5696F60209BBC35009C931F /* FBSDKEventBinding.m in Sources */, 0384CEBB208E60660013D404 /* FBSDKAccessTokenExpirer.m in Sources */, 81B71D2F1D19C87400933E93 /* FBSDKColor.m in Sources */, - F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 81B71D301D19C87400933E93 /* FBSDKAppLinkResolver.m in Sources */, F420D18F2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 81B71D311D19C87400933E93 /* FBSDKIcon.m in Sources */, @@ -3958,12 +4067,10 @@ 81B71D321D19C87400933E93 /* FBSDKConstants.m in Sources */, 81B71D331D19C87400933E93 /* FBSDKAppEventsUtility.m in Sources */, 5DB7B08F2303632E0012E8CB /* FBSDKInstrumentManager.m in Sources */, - F468B30B24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, C5696F48209BBC35009C931F /* FBSDKCodelessPathComponent.m in Sources */, F46FA64024533F690060C902 /* Settings.swift in Sources */, 81B71D341D19C87400933E93 /* FBSDKSettings.m in Sources */, 52963A85215992F400C7B252 /* FBSDKAppLink.m in Sources */, - C57044D824E26678009637AD /* FBSDKUserDataStore.m in Sources */, F943113224FB25A7002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */, BFC02459237B6B9C00A596EE /* FBSDKFeatureExtractor.m in Sources */, 52963A77215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */, @@ -3980,7 +4087,6 @@ F4D8D8E32422887600C28384 /* FBSDKMonitorNetworker.m in Sources */, 5D6DF1642398E28000AC2D6C /* FBSDKEventDeactivationManager.m in Sources */, 5D4360E123219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, - F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, F9FD9A7E21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, 81B71D3D1D19C87400933E93 /* FBSDKAppEvents.m in Sources */, FDAF4A912395D27D00711C4C /* FBSDKModelUtility.m in Sources */, @@ -3992,7 +4098,6 @@ 81B71D401D19C87400933E93 /* FBSDKWebDialogView.m in Sources */, 81B71D411D19C87400933E93 /* FBSDKErrorConfiguration.m in Sources */, C4FC99F2202CD56D0038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, - F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 52D4F0BC1D91A18D0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 81B71D431D19C87400933E93 /* FBSDKServerConfiguration.m in Sources */, @@ -4018,10 +4123,8 @@ 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */, C4FC99DA202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, 9D32A8461A699459000A936D /* FBSDKAccessTokenCache.m in Sources */, - F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 894C0B0A1A702194009137EF /* FBSDKCrypto.m in Sources */, 9D0BC1671A8E892C00BE8BA4 /* FBSDKAppEventsState.m in Sources */, - F468B31A24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 89D652851A855A6000BB651C /* FBSDKCloseIcon.m in Sources */, F4BF22A9241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 52963A86215992F400C7B252 /* FBSDKWebViewAppLinkResolver.m in Sources */, @@ -4050,7 +4153,6 @@ 52963A82215992F400C7B252 /* FBSDKURL.m in Sources */, 893F448C1A642F11001DB0B6 /* FBSDKInternalUtility.m in Sources */, ADEA17741B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m in Sources */, - F468B32224C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, F46FA63D24533F610060C902 /* Permission.swift in Sources */, 7E30917A1AA907E0004E91D5 /* FBSDKAppLinkUtility.m in Sources */, 89688B631AA64C5E00A98519 /* FBSDKViewImpressionTracker.m in Sources */, @@ -4064,7 +4166,6 @@ F9DE56BB24F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */, F4210E34241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 89D05AAA1AA1134000609300 /* FBSDKAudioResourceLoader.m in Sources */, - F468B30A24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 893F449A1A6444DF001DB0B6 /* FBSDKLogo.m in Sources */, 9D0BC1501A8D236200BE8BA4 /* FBSDKPaymentObserver.m in Sources */, 894C0AE01A6F1D1B009137EF /* FBSDKBridgeAPIResponse.m in Sources */, @@ -4081,10 +4182,8 @@ F420D18E2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 9DBA6A311A80265A00B4DE6A /* FBSDKColor.m in Sources */, E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */, - F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 7E5557371A8D833100344F86 /* FBSDKAppLinkResolver.m in Sources */, F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, - F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */, 891687D31AB33CA200F55364 /* FBSDKIcon.m in Sources */, 5D90CDDF2343D4BD00AF326A /* FBSDKCrashShield.m in Sources */, BFC02448237B6A9A00A596EE /* FBSDKFeatureExtractor.m in Sources */, @@ -4093,11 +4192,9 @@ 5DB7B08E2303632E0012E8CB /* FBSDKInstrumentManager.m in Sources */, F46FA63F24533F690060C902 /* Settings.swift in Sources */, C5696F47209BBC35009C931F /* FBSDKCodelessPathComponent.m in Sources */, - C57044D724E26678009637AD /* FBSDKUserDataStore.m in Sources */, F943112224FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */, 9DA8303D1A6999EC00770955 /* FBSDKSettings.m in Sources */, 52963A84215992F400C7B252 /* FBSDKAppLink.m in Sources */, - F468B34224C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 52963A76215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */, 891687EF1AB38C7C00F55364 /* FBSDKButton.m in Sources */, C5D25D3821795B790037B13D /* FBSDKCodelessIndexer.m in Sources */, @@ -4125,7 +4222,6 @@ 520223F81D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m in Sources */, 9DE1F3CE1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 89830F301A7805E100226ABB /* FBSDKServerConfiguration.m in Sources */, - F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */, FD8E438122FBF8F1008B6DD3 /* FBSDKErrorReport.m in Sources */, 899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */, @@ -4223,19 +4319,16 @@ 9DB0FA8D1BC1CEF4005EB8B1 /* FBSDKAppEventsUtility.m in Sources */, 9D6DEEC91BC23A30001A94ED /* FBSDKServerConfigurationManager.m in Sources */, 9D6DEEB31BC23850001A94ED /* FBSDKAccessTokenCache.m in Sources */, - F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E223219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 9DB0FA971BC22BC0005EB8B1 /* FBSDKUtility.m in Sources */, 9DE155411C161A66005FCF5C /* FBSDKBase64.m in Sources */, F420D1902433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, - F468B34424C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 9D6DEED21BC23ADD001A94ED /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 9DB0FAA71BC22D5B005EB8B1 /* FBSDKGraphRequestMetadata.m in Sources */, 9D6DEECF1BC23A6E001A94ED /* FBSDKServerConfiguration.m in Sources */, 81C969351C114723002FC037 /* FBSDKDynamicFrameworkLoader.m in Sources */, F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 9D6DEECB1BC23A43001A94ED /* FBSDKDialogConfiguration.m in Sources */, - F468B30C24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 9D6DEECD1BC23A53001A94ED /* FBSDKKeychainStoreViaBundleID.m in Sources */, FD147F662387215A000B216E /* FBSDKRestrictiveDataFilterManager.m in Sources */, 9DB0FA931BC22B49005EB8B1 /* FBSDKInternalUtility.m in Sources */, @@ -4244,7 +4337,6 @@ 9D10A6901CB38DF100F42AC1 /* FBSDKDeviceViewControllerBase.m in Sources */, F4A52B16242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */, 9D6DEEB11BC23834001A94ED /* FBSDKAppEventsState.m in Sources */, - F4FE998124D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 9D6DEEBD1BC238F5001A94ED /* FBSDKPaymentObserver.m in Sources */, F9FD9A7F21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, F4210E36241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, @@ -4263,14 +4355,12 @@ F42004972416C30300AD7006 /* FBSDKMonitor.m in Sources */, 9D6DEEAA1BC236B9001A94ED /* FBSDKAccessToken.m in Sources */, 9DB0FAA11BC22CF9005EB8B1 /* FBSDKGraphRequestBody.m in Sources */, - F468B34C24C25AB600979F8D /* FBSDKURLSession.m in Sources */, C5C7B75022D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, 9DB0FA9B1BC22BED005EB8B1 /* FBSDKErrorConfiguration.m in Sources */, F9A06DD52510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, C554DB192304D11900A32E8B /* FBSDKErrorReport.m in Sources */, 9D6538411BF44FB4008A08E9 /* FBSDKViewImpressionTracker.m in Sources */, 9DB0FA951BC22B79005EB8B1 /* FBSDKSettings.m in Sources */, - F468B31C24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 9D6DEEA91BC2368D001A94ED /* FBSDKAppEvents.m in Sources */, 9D6DEEE81BC2429B001A94ED /* FBSDKTestUsersManager.m in Sources */, C5696FA9209CCEB4009C931F /* FBSDKSwizzler.m in Sources */, @@ -4278,9 +4368,7 @@ 52D4F0D11D91A18F0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 9DDC112A1BEC413900A88306 /* FBSDKLogo.m in Sources */, 9D9E16AF1CB46C8E00C8B68F /* FBSDKDeviceButton.m in Sources */, - C57044D924E26678009637AD /* FBSDKUserDataStore.m in Sources */, 9DB0FA891BC1CDD0005EB8B1 /* FBSDKGraphRequestConnection.m in Sources */, - F468B32424C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, F9A06DC92510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, 9D6DEEBA1BC238A2001A94ED /* FBSDKErrorRecoveryConfiguration.m in Sources */, 9DC1DD781BC4629F000D5AD5 /* FBSDKApplicationDelegate.m in Sources */, @@ -4289,7 +4377,6 @@ 5DB7B0902303632F0012E8CB /* FBSDKInstrumentManager.m in Sources */, F40F6569241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */, 9D28F1991DB14DBB0057D709 /* FBSDKImageDownloader.m in Sources */, - F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 9DB0FAA51BC22D1C005EB8B1 /* FBSDKLogger.m in Sources */, 9D6DEEB01BC2379C001A94ED /* FBSDKTimeSpentData.m in Sources */, 9DB0FAA91BC22D6F005EB8B1 /* FBSDKGraphRequestPiggybackManager.m in Sources */, @@ -4389,10 +4476,30 @@ target = C5C4B3BE2276B67200CA3706 /* FBSDKCoreKit_Basics_TV */; targetProxy = C5FCE33C228E093100867DFD /* PBXContainerItemProxy */; }; - F410D0342370CBC2005B9318 /* PBXTargetDependency */ = { + F4583A6A252E5FBD0051E280 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C5C4B2E62276B51500CA3706 /* FBSDKCoreKit_Basics */; + targetProxy = F4583A69252E5FBD0051E280 /* PBXContainerItemProxy */; + }; + F4583AC8252E7D8B0051E280 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 81B71CFC1D19C87400933E93 /* FBSDKCoreKit-Dynamic */; - targetProxy = F410D0332370CBC2005B9318 /* PBXContainerItemProxy */; + targetProxy = F4583AC7252E7D8B0051E280 /* PBXContainerItemProxy */; + }; + F4583ACD252E85080051E280 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C5C4B2E62276B51500CA3706 /* FBSDKCoreKit_Basics */; + targetProxy = F4583ACC252E85080051E280 /* PBXContainerItemProxy */; + }; + F4C39BC52538EE7C00A04DA3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C5C4B3BE2276B67200CA3706 /* FBSDKCoreKit_Basics_TV */; + targetProxy = F4C39BC42538EE7C00A04DA3 /* PBXContainerItemProxy */; + }; + F4C39C1A2538FB6B00A04DA3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C5C4B4DC2276BA8D00CA3706 /* FBSDKCoreKit_Basics_TV-Dynamic */; + targetProxy = F4C39C192538FB6B00A04DA3 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -4538,84 +4645,84 @@ }; C5C4B3B42276B51500CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; + baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B3B52276B51500CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; + baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; buildSettings = { }; name = Release; }; C5C4B3CA2276B67200CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; + baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B3CB2276B67200CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; + baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; buildSettings = { }; name = Release; }; C5C4B4D22276BA1200CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */; + baseConfigurationReference = F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B4D32276BA1200CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */; + baseConfigurationReference = F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */; buildSettings = { }; name = Release; }; C5C4B4E82276BA8D00CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */; + baseConfigurationReference = F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B4E92276BA8D00CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */; + baseConfigurationReference = F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */; buildSettings = { }; name = Release; }; C5FCE322228E08CA00867DFD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; + baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; buildSettings = { }; name = Debug; }; C5FCE323228E08CA00867DFD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; + baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; buildSettings = { }; name = Release; }; C5FCE337228E08D400867DFD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; + baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; buildSettings = { }; name = Debug; }; C5FCE338228E08D400867DFD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; + baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; buildSettings = { }; name = Release; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index dd1195fca8..6ea5ad9295 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -24,9 +24,9 @@ #import #endif -#if defined FBSDKCOCOAPODS - #import -#elif defined BUCK +#if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE + #import "FBSDKCoreKit_Basics.h" +#else #import #endif @@ -131,7 +131,6 @@ #import "Device/FBSDKSmartDeviceDialogView.h" #endif - #import "../../../Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h" #import "../AppEvents/Internal/FBSDKAppEvents+Internal.h" #import "../AppEvents/Internal/FBSDKAppEventsConfiguration.h" #import "../AppEvents/Internal/FBSDKAppEventsConfigurationManager.h" diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj index 52b8cf25dd..c0fdaccffa 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj @@ -39,6 +39,7 @@ 9FC20034247D8D170016A053 /* FBSDKShareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FC2001D247D83400016A053 /* FBSDKShareKit.framework */; }; F4234613244A2D2D006C9836 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5123F49C110030A346 /* FBSDKCoreKit.framework */; }; F4234614244A2D2D006C9836 /* FBSDKCoreKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5123F49C110030A346 /* FBSDKCoreKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F4583ABD252E6E760051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5B23F49C110030A346 /* FBSDKCoreKit_Basics.framework */; }; F46A224524D9F14D005878A8 /* FBSDKGamingServicesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA1823F4902B0030A346 /* FBSDKGamingServicesKit.framework */; }; F46A225024D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F46A224B24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m */; }; F4DC057F2519499A0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */; }; @@ -334,6 +335,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F4583ABD252E6E760051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */, 9FC20034247D8D170016A053 /* FBSDKShareKit.framework in Frameworks */, F4F7CAA323F4A1470030A346 /* UIKit.framework in Frameworks */, F4234613244A2D2D006C9836 /* FBSDKCoreKit.framework in Frameworks */, @@ -504,10 +506,10 @@ F4F7CA5523F49C110030A346 /* FBSDKCoreKitTests.xctest */, F4F7CA5723F49C110030A346 /* FBSDKCoreKit.framework */, F4F7CA5923F49C110030A346 /* FBSDKCoreKit.framework */, - F4F7CA5B23F49C110030A346 /* FBSDKCoreKit.framework */, - F4F7CA5D23F49C110030A346 /* FBSDKCoreKit.framework */, - F4F7CA5F23F49C110030A346 /* FBSDKCoreKit.framework */, - F4F7CA6123F49C110030A346 /* FBSDKCoreKit.framework */, + F4F7CA5B23F49C110030A346 /* FBSDKCoreKit_Basics.framework */, + F4F7CA5D23F49C110030A346 /* FBSDKCoreKit_Basics.framework */, + F4F7CA5F23F49C110030A346 /* FBSDKCoreKit_Basics.framework */, + F4F7CA6123F49C110030A346 /* FBSDKCoreKit_Basics.framework */, ); name = Products; sourceTree = ""; @@ -741,31 +743,31 @@ remoteRef = F4F7CA5823F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA5B23F49C110030A346 /* FBSDKCoreKit.framework */ = { + F4F7CA5B23F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = F4F7CA5A23F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA5D23F49C110030A346 /* FBSDKCoreKit.framework */ = { + F4F7CA5D23F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = F4F7CA5C23F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA5F23F49C110030A346 /* FBSDKCoreKit.framework */ = { + F4F7CA5F23F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = F4F7CA5E23F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA6123F49C110030A346 /* FBSDKCoreKit.framework */ = { + F4F7CA6123F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = F4F7CA6023F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1113,7 +1115,6 @@ baseConfigurationReference = F4F7C9DF23F48F2C0030A346 /* FBSDKGamingServicesKit.xcconfig */; buildSettings = { CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; @@ -1122,7 +1123,6 @@ baseConfigurationReference = F4F7C9DF23F48F2C0030A346 /* FBSDKGamingServicesKit.xcconfig */; buildSettings = { CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index bc06cd2244..d9b83670e9 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -106,7 +106,6 @@ 818EB43C1D1A283100252851 /* FBSDKLoginManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D03E81F1A72D7E700207493 /* FBSDKLoginManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8199F1061D1A2B30007AA5AD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774A91A3B80FD00BE2807 /* CoreGraphics.framework */; }; 8199F1081D1A2B34007AA5AD /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774AB1A3B810100BE2807 /* UIKit.framework */; }; - 81A07EAB1D1A2B560041A29C /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B6811D0A5B9400962084 /* FBSDKCoreKit.framework */; }; 893774AA1A3B80FD00BE2807 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774A91A3B80FD00BE2807 /* CoreGraphics.framework */; }; 893774AC1A3B810100BE2807 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774AB1A3B810100BE2807 /* UIKit.framework */; }; 9D03E8211A72D7E700207493 /* FBSDKLoginManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D03E81F1A72D7E700207493 /* FBSDKLoginManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -148,6 +147,8 @@ C6CE2BC424EB73CF00CF2EB6 /* FBSDKReferralManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C6CE2BBE24EB72F200CF2EB6 /* FBSDKReferralManager.m */; }; C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */; }; C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */; }; + F4583AA0252E6C220051E280 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B6811D0A5B9400962084 /* FBSDKCoreKit.framework */; }; + F4583AA7252E6DC70051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E309CAC228F2581007B532E /* FBSDKCoreKit_Basics.framework */; }; F462DC0E23B958E000FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC0F23B958E100FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC1023B95BA600FFCECA /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */; }; @@ -405,8 +406,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 81A07EAB1D1A2B560041A29C /* FBSDKCoreKit.framework in Frameworks */, + F4583AA7252E6DC70051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */, 8199F1081D1A2B34007AA5AD /* UIKit.framework in Frameworks */, + F4583AA0252E6C220051E280 /* FBSDKCoreKit.framework in Frameworks */, 8199F1061D1A2B30007AA5AD /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -443,8 +445,8 @@ 8118B6831D0A5B9400962084 /* FBSDKCoreKitTests.xctest */, 8118B6851D0A5B9400962084 /* FBSDKCoreKit.framework */, 812E0D1B1D23840500291B71 /* FBSDKCoreKit.framework */, - 5E309CAC228F2581007B532E /* FBSDKCoreKit.framework */, - 5E309CAE228F2581007B532E /* FBSDKCoreKit.framework */, + 5E309CAC228F2581007B532E /* FBSDKCoreKit_Basics.framework */, + 5E309CAE228F2581007B532E /* FBSDKCoreKit_Basics.framework */, 5E309CB0228F2581007B532E /* FBSDKCoreKit.framework */, 5E309CB2228F2581007B532E /* FBSDKCoreKit.framework */, ); @@ -904,17 +906,17 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 5E309CAC228F2581007B532E /* FBSDKCoreKit.framework */ = { + 5E309CAC228F2581007B532E /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = 5E309CAB228F2581007B532E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E309CAE228F2581007B532E /* FBSDKCoreKit.framework */ = { + 5E309CAE228F2581007B532E /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = 5E309CAD228F2581007B532E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index 657b74ba25..4ad7210826 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -612,8 +612,8 @@ 8118B63F1D0A49B500962084 /* FBSDKCoreKitTests.xctest */, 8118B6411D0A49B500962084 /* FBSDKCoreKit.framework */, 819043EF1D261A7900B2E437 /* FBSDKCoreKit.framework */, - C57538C52292B6D5007C2EFF /* FBSDKCoreKit.framework */, - C57538C72292B6D5007C2EFF /* FBSDKCoreKit.framework */, + C57538C52292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */, + C57538C72292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */, C57538C92292B6D5007C2EFF /* FBSDKCoreKit.framework */, C57538CB2292B6D5007C2EFF /* FBSDKCoreKit.framework */, ); @@ -1262,17 +1262,17 @@ remoteRef = 819043EE1D261A7900B2E437 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - C57538C52292B6D5007C2EFF /* FBSDKCoreKit.framework */ = { + C57538C52292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = C57538C42292B6D5007C2EFF /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - C57538C72292B6D5007C2EFF /* FBSDKCoreKit.framework */ = { + C57538C72292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit.framework; + path = FBSDKCoreKit_Basics.framework; remoteRef = C57538C62292B6D5007C2EFF /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/scripts/xcode/build-universal-framework.sh b/scripts/xcode/build-universal-framework.sh index c3c774ef3c..d54249cb27 100755 --- a/scripts/xcode/build-universal-framework.sh +++ b/scripts/xcode/build-universal-framework.sh @@ -30,6 +30,7 @@ UNIVERSAL_BUILD_FOLDER=../build/ # make the output directory and delete the framework directory mkdir -p "${UNIVERSAL_BUILD_FOLDER}" rm -rf "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework" +rm -rf "${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}.framework" # get target by removing '-Universal' from $TARGET_NAME TARGET=${TARGET_NAME%-Universal} @@ -52,19 +53,19 @@ xcodebuild -target "${TARGET}" \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES # Step 2. Copy the framework structure to the universal folder -cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_BUILD_FOLDER}/" +cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}.framework" "${UNIVERSAL_BUILD_FOLDER}/" # Step 3. Copy the swiftmodule files created during the simulator build -rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" \ - "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" || true +rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}.framework/Modules/${PRODUCT_NAME}.swiftmodule/" \ + "${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}.framework/Modules/${PRODUCT_NAME}.swiftmodule" || true # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory -lipo -create -output "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" +lipo -create -output "${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" # Step 5. Copy strings bundle if exists -STRINGS_INPUT_FOLDER="${PROJECT_NAME}Strings.bundle" +STRINGS_INPUT_FOLDER="${PRODUCT_NAME}Strings.bundle" if [ -d "${STRINGS_INPUT_FOLDER}" ]; then - STRINGS_OUTPUT_FOLDER="${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}Strings.bundle" + STRINGS_OUTPUT_FOLDER="${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}Strings.bundle" rm -rf "${STRINGS_OUTPUT_FOLDER}" cp -R "${STRINGS_INPUT_FOLDER}" "${STRINGS_OUTPUT_FOLDER}" fi diff --git a/scripts/xcode/build-universal-tvos-framework.sh b/scripts/xcode/build-universal-tvos-framework.sh index 4f43bdff1d..8d43b66a50 100755 --- a/scripts/xcode/build-universal-tvos-framework.sh +++ b/scripts/xcode/build-universal-tvos-framework.sh @@ -30,6 +30,7 @@ UNIVERSAL_TV_BUILD_FOLDER=../build/tv/ # make the output directory and delete the framework directory mkdir -p "${UNIVERSAL_TV_BUILD_FOLDER}" rm -rf "${UNIVERSAL_TV_BUILD_FOLDER}/${PROJECT_NAME}.framework" +rm -rf "${UNIVERSAL_TV_BUILD_FOLDER}/${PRODUCT_NAME}.framework" # get target by removing '-Universal' from $TARGET_NAME TARGET=${TARGET_NAME%-Universal} @@ -54,9 +55,9 @@ xcodebuild -target "${TARGET}" \ clean build # Step 2. Copy the framework structure to the universal folder -cp -R "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PROJECT_NAME}.framework" "${UNIVERSAL_TV_BUILD_FOLDER}/" +cp -R "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PRODUCT_NAME}.framework" "${UNIVERSAL_TV_BUILD_FOLDER}/" # Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory -lipo -create -output "${UNIVERSAL_TV_BUILD_FOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" \ - "${BUILD_DIR}/${CONFIGURATION}-appletvsimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" \ - "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PROJECT_NAME}.framework/${PROJECT_NAME}" +lipo -create -output "${UNIVERSAL_TV_BUILD_FOLDER}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" \ + "${BUILD_DIR}/${CONFIGURATION}-appletvsimulator/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" \ + "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" From e55513f2cd6990a6469001dfea0c29758b958c30 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 16 Oct 2020 08:42:33 -0700 Subject: [PATCH 031/227] Make Basics an actual dependency 3/n (#1527) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1527 ## Context: In terms of BUCK, CocoaPods and Swift Package Manager, CoreKitBasics is its own module. Even in terms of xcodeproj it's its own target. This formalizes that dependency relationship. ## Why do this? This allows us to avoid a lot of the messiness where we have something like: ``` #if defined FBSDKCOCOAPODS #import #elif defined BUCK #import #else #import "FBSDKCoreKit_Basics.h" #endif ``` Now we can just do: ``` #import ``` and it will "just work" ## This diff Updates imports to work with Swift Package Manager. Looks like at this point it's unnecessary to change the Swift name in `FBSDKAppEventUserDataType` (see earlier versions of the diff for context). This might become necessary later when the Package is updated to support Swift but that's an unrelated change. Reviewed By: dreamolight Differential Revision: D24179748 fbshipit-source-id: 1b91798d4fc62a3530deb4f0dcf53dcb9870ba75 --- Package.swift | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Package.swift b/Package.swift index a1e75d07b3..d336dba03a 100644 --- a/Package.swift +++ b/Package.swift @@ -28,6 +28,10 @@ let package = Package( .tvOS(.v10) ], products: [ + .library( + name: "FBSDKCoreKit_Basics", + targets: ["FBSDKCoreKit_Basics"] + ), .library( name: "FacebookCore", targets: ["FacebookCore"] @@ -48,7 +52,8 @@ let package = Package( dependencies: [], targets: [ .target( - name: "FBSDKCoreKit_Basics" + name: "FBSDKCoreKit_Basics", + path: "Sources/FBSDKCoreKit_Basics" ), .target( name: "FBSDKCoreKit", @@ -81,7 +86,8 @@ let package = Package( .headerSearchPath("Internal/Network"), .headerSearchPath("Internal/ServerConfiguration"), .headerSearchPath("Internal/TokenCaching"), - .headerSearchPath("Internal/UI") + .headerSearchPath("Internal/UI"), + .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) ], linkerSettings: [ .linkedFramework("Accelerate") @@ -90,7 +96,10 @@ let package = Package( .target( name: "FacebookCore", dependencies: ["FBSDKCoreKit"], - path: "FBSDKCoreKit/FBSDKCoreKit/Swift" + path: "FBSDKCoreKit/FBSDKCoreKit/Swift", + cSettings: [ + .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) + ] ), .target( name: "FBSDKLoginKit", From 2f5d81551328152037735165abfbdcaa52749433 Mon Sep 17 00:00:00 2001 From: Shuxin Zhang Date: Fri, 16 Oct 2020 10:06:43 -0700 Subject: [PATCH 032/227] Added unit test for profile package + Make profile fetch capable of taking in arbitrary graph request Summary: This diff adds a method loadProfileWithToken which takes in a customized graph request, and also exposed the loadProfileWithToken private handler in internal header. This would make unit testing much easier as we could easily stub graph request. Reviewed By: robtimp Differential Revision: D24131996 fbshipit-source-id: 8df9a88ff48de334c7f0c0c94992d2c94f7eeb76 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 94 ++++++++++--------- .../Internal/FBSDKProfile+Internal.h | 7 ++ .../FBSDKCoreKitTests/FBSDKProfileTests.m | 67 +++++++++++++ 3 files changed, 124 insertions(+), 44 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index 405938ea81..4187b5afc1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -22,8 +22,6 @@ #import "FBSDKProfile+Internal.h" - #import "FBSDKCoreKit+Internal.h" - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSNotificationName const FBSDKProfileDidChangeNotification = @"com.facebook.sdk.FBSDKProfile.FBSDKProfileDidChangeNotification";; @@ -231,48 +229,6 @@ - (void)encodeWithCoder:(NSCoder *)encoder #pragma mark - Private -+ (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion -{ - static FBSDKGraphRequestConnection *executingRequestConnection = nil; - - BOOL isStale = [[NSDate date] timeIntervalSinceDate:g_currentProfile.refreshDate] > FBSDKPROFILE_STALE_IN_SECONDS; - if (token - && (isStale || ![g_currentProfile.userID isEqualToString:token.userID])) { - FBSDKProfile *expectedCurrentProfile = g_currentProfile; - - NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; - [executingRequestConnection cancel]; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath - parameters:nil - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; - executingRequestConnection = [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - if (expectedCurrentProfile != g_currentProfile) { - // current profile has already changed since request was started. Let's not overwrite. - if (completion != NULL) { - completion(nil, nil); - } - return; - } - FBSDKProfile *profile = nil; - if (!error) { - profile = [[FBSDKProfile alloc] initWithUserID:result[@"id"] - firstName:result[@"first_name"] - middleName:result[@"middle_name"] - lastName:result[@"last_name"] - name:result[@"name"] - linkURL:[NSURL URLWithString:result[@"link"]] - refreshDate:[NSDate date]]; - } - [[self class] setCurrentProfile:profile]; - if (completion != NULL) { - completion(profile, error); - } - }]; - } else if (completion != NULL) { - completion(g_currentProfile, nil); - } -} - + (void)observeChangeAccessTokenChange:(NSNotification *)notification { FBSDKAccessToken *token = notification.userInfo[FBSDKAccessTokenChangeNewKey]; @@ -311,6 +267,56 @@ + (FBSDKProfile *)fetchCachedProfile return nil; } ++ (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion +{ + NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; + + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath + parameters:nil + flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; + [[self class] loadProfileWithToken:token completion:completion graphRequest:request]; +} + ++ (void)loadProfileWithToken:(FBSDKAccessToken *)token + completion:(FBSDKProfileBlock)completion + graphRequest:(FBSDKGraphRequest *)request +{ + static FBSDKGraphRequestConnection *executingRequestConnection = nil; + + BOOL isStale = [[NSDate date] timeIntervalSinceDate:g_currentProfile.refreshDate] > FBSDKPROFILE_STALE_IN_SECONDS; + if (token + && (isStale || ![g_currentProfile.userID isEqualToString:token.userID])) { + FBSDKProfile *expectedCurrentProfile = g_currentProfile; + + [executingRequestConnection cancel]; + executingRequestConnection = [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + if (expectedCurrentProfile != g_currentProfile) { + // current profile has already changed since request was started. Let's not overwrite. + if (completion != NULL) { + completion(nil, nil); + } + return; + } + FBSDKProfile *profile = nil; + if (!error) { + profile = [[FBSDKProfile alloc] initWithUserID:result[@"id"] + firstName:result[@"first_name"] + middleName:result[@"middle_name"] + lastName:result[@"last_name"] + name:result[@"name"] + linkURL:[NSURL URLWithString:result[@"link"]] + refreshDate:[NSDate date]]; + } + [[self class] setCurrentProfile:profile]; + if (completion != NULL) { + completion(profile, error); + } + }]; + } else if (completion != NULL) { + completion(g_currentProfile, nil); + } +} + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h index 2322d67765..c0a7d38da1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h @@ -20,6 +20,7 @@ #if !TARGET_OS_TV + #import "FBSDKCoreKit+Internal.h" #import "FBSDKProfile.h" NS_ASSUME_NONNULL_BEGIN @@ -29,6 +30,12 @@ NS_ASSUME_NONNULL_BEGIN + (void)cacheProfile:(nullable FBSDKProfile *)profile; + (nullable FBSDKProfile *)fetchCachedProfile; ++ (void)loadProfileWithToken:(FBSDKAccessToken *)token + completion:(FBSDKProfileBlock)completion + graphRequest:(FBSDKGraphRequest *)request; + ++ (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(_Nullable FBSDKProfileBlock)completion; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index 5b4a73a7e8..19db6dd081 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -339,4 +339,71 @@ - (void)testCreatingSquareImageURLWithNegativeSize ); } +- (void)testCorrectGraphPathForFBProfileLoad +{ + id profileMock = OCMClassMock([FBSDKProfile class]); + NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; + __block BOOL graphRequestMethodInvoked = false; + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY graphRequest:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { + __unsafe_unretained FBSDKGraphRequest *req = [FBSDKGraphRequest alloc]; + [invocation getArgument:&req atIndex:4]; + graphRequestMethodInvoked = true; + XCTAssertTrue([[req graphPath] isEqualToString:graphPath]); + }); + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY]).andForwardToRealObject(); + [FBSDKProfile loadProfileWithToken:nil completion:nil]; + XCTAssertTrue(graphRequestMethodInvoked); +} + +- (void)testActualProfileLoaded +{ + id result = @{ @"id" : SampleUserProfile.valid.userID, + @"first_name" : SampleUserProfile.valid.firstName, + @"middle_name" : SampleUserProfile.valid.middleName, + @"last_name" : SampleUserProfile.valid.lastName, + @"name" : SampleUserProfile.valid.name}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { + XCTAssertTrue([profile.firstName isEqualToString:SampleUserProfile.valid.firstName]); + XCTAssertTrue([profile.middleName isEqualToString:SampleUserProfile.valid.middleName]); + XCTAssertTrue([profile.lastName isEqualToString:SampleUserProfile.valid.lastName]); + XCTAssertTrue([profile.name isEqualToString:SampleUserProfile.valid.name]); + XCTAssertTrue([profile.userID isEqualToString:SampleUserProfile.valid.userID]); + } graphRequest:self.graphRequestMock]; +} + +- (void)testProfileNilWithNilAccessToken +{ + id result = @{ @"id" : SampleUserProfile.valid.userID, + @"first_name" : SampleUserProfile.valid.firstName, + @"middle_name" : SampleUserProfile.valid.middleName, + @"last_name" : SampleUserProfile.valid.lastName, + @"name" : SampleUserProfile.valid.name}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:nil completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { + XCTAssertNil(profile); + } graphRequest:self.graphRequestMock]; +} + +- (void)testProfileNotRefreshedIfNotStale +{ + [FBSDKProfile setCurrentProfile:SampleUserProfile.valid]; + id result = @{ @"id" : SampleUserProfile.valid.userID, + @"first_name" : @"firstname", + @"middle_name" : @"middlename", + @"last_name" : @"lastname", + @"name" : @"name"}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:nil completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { + XCTAssertTrue([profile.firstName isEqualToString:SampleUserProfile.valid.firstName]); + XCTAssertTrue([profile.middleName isEqualToString:SampleUserProfile.valid.middleName]); + XCTAssertTrue([profile.lastName isEqualToString:SampleUserProfile.valid.lastName]); + XCTAssertTrue([profile.name isEqualToString:SampleUserProfile.valid.name]); + XCTAssertTrue([profile.userID isEqualToString:SampleUserProfile.valid.userID]); + } graphRequest:self.graphRequestMock]; +} + @end From cf1f45cd92adda089162c12baada79e6f86aee18 Mon Sep 17 00:00:00 2001 From: Shuxin Zhang Date: Fri, 16 Oct 2020 10:06:43 -0700 Subject: [PATCH 033/227] refactored profile handler's result parsing block Summary: Decoupled the logic in profile.m to separate out the result parsing and profile generation logic, so that it is easier to test and change later. Reviewed By: joesus Differential Revision: D24149369 fbshipit-source-id: 4a271edf66763b810189b824f8962c9a72fe8592 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 32 +++++++--- .../Internal/FBSDKProfile+Internal.h | 5 +- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 62 +++++++++++++++++++ 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index 4187b5afc1..b01dbc0322 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -280,6 +280,30 @@ + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileB + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion graphRequest:(FBSDKGraphRequest *)request +{ + FBSDKParseProfileBlock parseBlock = ^void (id result, FBSDKProfile **profileRef) { + if (profileRef == NULL + || result == nil + || result[@"id"] == nil + || ((NSString *) result[@"id"]).length == 0) { + return; + } + FBSDKProfile *profile = [[FBSDKProfile alloc] initWithUserID:result[@"id"] + firstName:result[@"first_name"] + middleName:result[@"middle_name"] + lastName:result[@"last_name"] + name:result[@"name"] + linkURL:[NSURL URLWithString:result[@"link"]] + refreshDate:[NSDate date]]; + *profileRef = [profile copy]; + }; + [[self class] loadProfileWithToken:token completion:completion graphRequest:request parseBlock:parseBlock]; +} + ++ (void)loadProfileWithToken:(FBSDKAccessToken *)token + completion:(FBSDKProfileBlock)completion + graphRequest:(FBSDKGraphRequest *)request + parseBlock:(FBSDKParseProfileBlock)parseBlock; { static FBSDKGraphRequestConnection *executingRequestConnection = nil; @@ -299,13 +323,7 @@ + (void)loadProfileWithToken:(FBSDKAccessToken *)token } FBSDKProfile *profile = nil; if (!error) { - profile = [[FBSDKProfile alloc] initWithUserID:result[@"id"] - firstName:result[@"first_name"] - middleName:result[@"middle_name"] - lastName:result[@"last_name"] - name:result[@"name"] - linkURL:[NSURL URLWithString:result[@"link"]] - refreshDate:[NSDate date]]; + parseBlock(result, &profile); } [[self class] setCurrentProfile:profile]; if (completion != NULL) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h index c0a7d38da1..09fee8f01f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h @@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN +typedef void (^FBSDKParseProfileBlock)(id result, FBSDKProfile *_Nonnull *_Nullable profileRef); + @interface FBSDKProfile (Internal) + (void)cacheProfile:(nullable FBSDKProfile *)profile; @@ -32,7 +34,8 @@ NS_ASSUME_NONNULL_BEGIN + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion - graphRequest:(FBSDKGraphRequest *)request; + graphRequest:(FBSDKGraphRequest *)request + parseBlock:(FBSDKParseProfileBlock)parseBlock; + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(_Nullable FBSDKProfileBlock)completion; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index 19db6dd081..e8d021cc09 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -47,6 +47,9 @@ + (void)resetDataProcessingOptionsCache; @interface FBSDKProfile (Testing) + (void)resetCurrentProfileCache; ++ (void)loadProfileWithToken:(FBSDKAccessToken *)token + completion:(FBSDKProfileBlock)completion + graphRequest:(FBSDKGraphRequest *)request; @end @interface FBSDKProfileTests : FBSDKTestCase @@ -406,4 +409,63 @@ - (void)testProfileNotRefreshedIfNotStale } graphRequest:self.graphRequestMock]; } +- (void)testProfileParseBlockInvokedOnSuccessfulGraphRequest +{ + id result = @{}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + __block BOOL parseBlockInvoked = false; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock parseBlock:^void (id result, FBSDKProfile **profileRef) { + parseBlockInvoked = true; + }]; + XCTAssertTrue(parseBlockInvoked); +} + +- (void)testProfileParseBlockShouldHaveNonNullPointer +{ + id result = @{}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock parseBlock:^void (id result, FBSDKProfile **profileRef) { + XCTAssertTrue(profileRef != NULL); + }]; +} + +- (void)testProfileParseBlockReturnsNilIfResultIsEmpty +{ + id result = @{}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock]; + XCTAssertNil(FBSDKProfile.currentProfile); +} + +- (void)testProfileParseBlockReturnsNilIfResultHasNoId +{ + id result = @{ @"first_name" : @"firstname", + @"middle_name" : @"middlename", + @"last_name" : @"lastname", + @"name" : @"name"}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock]; + XCTAssertNil(FBSDKProfile.currentProfile); +} + +- (void)testProfileParseBlockReturnsNilIfResultHasEmptyId +{ + id result = @{ + @"id" : @"", + @"first_name" : @"firstname", + @"middle_name" : @"middlename", + @"last_name" : @"lastname", + @"name" : @"name" + }; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock]; + XCTAssertNil(FBSDKProfile.currentProfile); +} + @end From 61b601e7c98551f3e39a2949fbf1ed4a22b2ca51 Mon Sep 17 00:00:00 2001 From: Shuxin Zhang Date: Fri, 16 Oct 2020 10:06:43 -0700 Subject: [PATCH 034/227] Unified profile picture view url getter with profile sdk url getter Summary: Added an internal private method, getImageUrl for getting the profile picture url in ProfilePictureView.h Reviewed By: robtimp Differential Revision: D24185414 fbshipit-source-id: b93851039085f44268f918492af33d5f411615a3 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 75 ++++++++++--------- .../FBSDKCoreKit/FBSDKProfilePictureView.m | 20 +++-- .../Internal/FBSDKProfile+Internal.h | 4 + 3 files changed, 57 insertions(+), 42 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index b01dbc0322..13e058fd8b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -92,40 +92,7 @@ + (void)setCurrentProfile:(FBSDKProfile *)profile - (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size { - NSString *const accessTokenKey = @"access_token"; - NSString *const pictureModeKey = @"type"; - NSString *const widthKey = @"width"; - NSString *const heightKey = @"height"; - - NSString *type; - switch (mode) { - case FBSDKProfilePictureModeNormal: type = @"normal"; break; - case FBSDKProfilePictureModeSquare: type = @"square"; break; - case FBSDKProfilePictureModeSmall: type = @"small"; break; - case FBSDKProfilePictureModeAlbum: type = @"album"; break; - case FBSDKProfilePictureModeLarge: type = @"large"; break; - default: type = @"normal"; - } - - NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary]; - [FBSDKTypeUtility dictionary:queryParameters setObject:type forKey:pictureModeKey]; - [FBSDKTypeUtility dictionary:queryParameters setObject:@(roundf(size.width)) forKey:widthKey]; - [FBSDKTypeUtility dictionary:queryParameters setObject:@(roundf(size.height)) forKey:heightKey]; - - if (FBSDKAccessToken.currentAccessToken) { - [FBSDKTypeUtility dictionary:queryParameters setObject:FBSDKAccessToken.currentAccessToken.tokenString forKey:accessTokenKey]; - } else if (FBSDKSettings.clientToken) { - [FBSDKTypeUtility dictionary:queryParameters setObject:FBSDKSettings.clientToken forKey:accessTokenKey]; - } else { - NSLog(@"As of Graph API v8.0, profile images may not be retrieved without an access token. This can be the current access token from logging in with Facebook or it can be set via the plist or in code. Providing neither will cause this call to return a silhouette image."); - } - - NSString *path = [NSString stringWithFormat:@"%@/picture", _userID]; - - return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" - path:path - queryParameters:queryParameters - error:NULL]; + return [FBSDKProfile imageURLForProfileID:_userID PictureMode:mode size:size]; } + (void)enableUpdatesOnAccessTokenChange:(BOOL)enable @@ -267,6 +234,46 @@ + (FBSDKProfile *)fetchCachedProfile return nil; } ++ (NSURL *)imageURLForProfileID:(NSString *)profileId + PictureMode:(FBSDKProfilePictureMode)mode + size:(CGSize)size +{ + NSString *const accessTokenKey = @"access_token"; + NSString *const pictureModeKey = @"type"; + NSString *const widthKey = @"width"; + NSString *const heightKey = @"height"; + + NSString *type; + switch (mode) { + case FBSDKProfilePictureModeNormal: type = @"normal"; break; + case FBSDKProfilePictureModeSquare: type = @"square"; break; + case FBSDKProfilePictureModeSmall: type = @"small"; break; + case FBSDKProfilePictureModeAlbum: type = @"album"; break; + case FBSDKProfilePictureModeLarge: type = @"large"; break; + default: type = @"normal"; + } + + NSMutableDictionary *queryParameters = [NSMutableDictionary dictionary]; + [FBSDKTypeUtility dictionary:queryParameters setObject:type forKey:pictureModeKey]; + [FBSDKTypeUtility dictionary:queryParameters setObject:@(roundf(size.width)) forKey:widthKey]; + [FBSDKTypeUtility dictionary:queryParameters setObject:@(roundf(size.height)) forKey:heightKey]; + + if (FBSDKAccessToken.currentAccessToken) { + [FBSDKTypeUtility dictionary:queryParameters setObject:FBSDKAccessToken.currentAccessToken.tokenString forKey:accessTokenKey]; + } else if (FBSDKSettings.clientToken) { + [FBSDKTypeUtility dictionary:queryParameters setObject:FBSDKSettings.clientToken forKey:accessTokenKey]; + } else { + NSLog(@"As of Graph API v8.0, profile images may not be retrieved without an access token. This can be the current access token from logging in with Facebook or it can be set via the plist or in code. Providing neither will cause this call to return a silhouette image."); + } + + NSString *path = [NSString stringWithFormat:@"%@/picture", profileId]; + + return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" + path:path + queryParameters:queryParameters + error:NULL]; +} + + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion { NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m index f657ce3101..0f6b3ea80d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m @@ -26,6 +26,7 @@ #import "FBSDKInternalUtility.h" #import "FBSDKMaleSilhouetteIcon.h" #import "FBSDKMath.h" + #import "FBSDKProfile+Internal.h" #import "FBSDKUtility.h" @interface FBSDKProfilePictureViewState : NSObject @@ -302,6 +303,15 @@ - (CGSize)_imageSize:(BOOL)imageShouldFit scale:(CGFloat)scale return size; } +- (NSURL *)_getProfileImageUrl:(FBSDKProfilePictureViewState *)state +{ + // If there's an existing profile, use that profile's image url handler + if (FBSDKProfile.currentProfile != nil) { + return [FBSDKProfile.currentProfile imageURLForPictureMode:self.pictureMode size:state.size]; + } + return [FBSDKProfile imageURLForProfileID:state.profileID PictureMode:self.pictureMode size:state.size]; +} + - (void)_needsImageUpdate { _needsImageUpdate = NO; @@ -334,16 +344,10 @@ - (void)_needsImageUpdate return; } - NSString *path = [[NSString alloc] initWithFormat:@"/%@/picture", [FBSDKUtility URLEncode:state.profileID]]; - CGSize size = state.size; - NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:parameters setObject:@(size.width) forKey:@"width"]; - [FBSDKTypeUtility dictionary:parameters setObject:@(size.height) forKey:@"height"]; - [FBSDKTypeUtility dictionary:parameters setObject:accessToken.tokenString forKey:@"access_token"]; - NSURL *imageURL = [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" path:path queryParameters:parameters error:NULL]; - __weak FBSDKProfilePictureView *weakSelf = self; + NSURL *imageURL = [self _getProfileImageUrl:state]; + NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL]; NSURLSession *session = [NSURLSession sharedSession]; [[session diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h index 09fee8f01f..92f1dac3f8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h @@ -32,6 +32,10 @@ typedef void (^FBSDKParseProfileBlock)(id result, FBSDKProfile *_Nonnull *_Nulla + (void)cacheProfile:(nullable FBSDKProfile *)profile; + (nullable FBSDKProfile *)fetchCachedProfile; ++ (NSURL *)imageURLForProfileID:(NSString *)profileId + PictureMode:(FBSDKProfilePictureMode)mode + size:(CGSize)size; + + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion graphRequest:(FBSDKGraphRequest *)request From 4bc6d296669ffd534a28369c7c838120e357c9b0 Mon Sep 17 00:00:00 2001 From: Shuxin Zhang Date: Fri, 16 Oct 2020 10:06:43 -0700 Subject: [PATCH 035/227] Exposed the setup method of ProfilePictureView in internal handler Summary: Exposed the setup method of ProfilePictureView to an internal handler, so that we can flexibly configure its behavior. Reviewed By: jvlyn Differential Revision: D24282459 fbshipit-source-id: d6bcd47a3149bfc19d03dcc0b987c35969c09ea5 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 4 +++ .../FBSDKCoreKit/FBSDKProfilePictureView.m | 29 +++++++++------- .../FBSDKProfilePictureView+Internal.h | 34 +++++++++++++++++++ 3 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 41f0eec158..f5904c97de 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -682,6 +682,7 @@ 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 */; }; + B301910E253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */; }; B3C20ACD250B100F00DEC008 /* FBSDKAccessToken+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */; }; BF1C64E624039AD50052C580 /* FBSDKViewHierarchyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1C64E524039AD50052C580 /* FBSDKViewHierarchyTests.m */; }; BF247C822374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = BF247C802374E1B100A522C0 /* FBSDKSuggestedEventsIndexer.h */; }; @@ -1533,6 +1534,7 @@ 9DF2A3FE1A70572B00DFB2FD /* FBSDKGraphRequestMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestMetadata.m; sourceTree = ""; }; ADEA17711B7ECA1A0070EDC0 /* FBSDKMonotonicTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMonotonicTime.h; sourceTree = ""; }; ADEA17721B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonotonicTime.m; sourceTree = ""; }; + B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKProfilePictureView+Internal.h"; sourceTree = ""; }; B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKAccessToken+Internal.h"; sourceTree = ""; }; BF1C64E524039AD50052C580 /* FBSDKViewHierarchyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKViewHierarchyTests.m; sourceTree = ""; }; BF247C802374E1B100A522C0 /* FBSDKSuggestedEventsIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKSuggestedEventsIndexer.h; sourceTree = ""; }; @@ -2096,6 +2098,7 @@ 9D32A8381A69941A000A936D /* TokenCaching */, 89FB8C3E1A842393003CAE60 /* UI */, 89FB8C431A842644003CAE60 /* WebDialog */, + B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */, ); path = Internal; sourceTree = ""; @@ -3120,6 +3123,7 @@ 7E5557381A8D833100344F86 /* FBSDKAppLinkResolver.h in Headers */, 9D32A8401A69941A000A936D /* FBSDKAccessTokenCaching.h in Headers */, F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, + B301910E253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h in Headers */, 894C0ADF1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h in Headers */, 890414741A647D8800617215 /* FBSDKCoreKit+Internal.h in Headers */, 7EB63DA01A9BE730003A7AED /* FBSDKMeasurementEventListener.h in Headers */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m index 0f6b3ea80d..f47ec77225 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m @@ -21,6 +21,7 @@ #if !TARGET_OS_TV #import "FBSDKProfilePictureView.h" + #import "FBSDKProfilePictureView+Internal.h" #import "FBSDKAccessToken.h" #import "FBSDKInternalUtility.h" @@ -119,7 +120,7 @@ @implementation FBSDKProfilePictureView - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - [self _configureProfilePictureView]; + [self configureProfilePictureView]; } return self; } @@ -127,7 +128,7 @@ - (instancetype)initWithFrame:(CGRect)frame - (instancetype)initWithCoder:(NSCoder *)decoder { if ((self = [super initWithCoder:decoder])) { - [self _configureProfilePictureView]; + [self configureProfilePictureView]; } return self; } @@ -224,18 +225,9 @@ - (void)setNeedsImageUpdate }); } - #pragma mark - Helper Methods + #pragma mark - Internal Methods -- (void)_accessTokenDidChangeNotification:(NSNotification *)notification -{ - if (![_profileID isEqualToString:@"me"] || !notification.userInfo[FBSDKAccessTokenDidChangeUserIDKey]) { - return; - } - _lastState = nil; - [self setNeedsImageUpdate]; -} - -- (void)_configureProfilePictureView +- (void)configureProfilePictureView { _imageView = [[UIImageView alloc] initWithFrame:self.bounds]; _imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); @@ -253,6 +245,17 @@ - (void)_configureProfilePictureView [self setNeedsImageUpdate]; } + #pragma mark - Helper Methods + +- (void)_accessTokenDidChangeNotification:(NSNotification *)notification +{ + if (![_profileID isEqualToString:@"me"] || !notification.userInfo[FBSDKAccessTokenDidChangeUserIDKey]) { + return; + } + _lastState = nil; + [self setNeedsImageUpdate]; +} + - (BOOL)_imageShouldFit { switch (self.contentMode) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h new file mode 100644 index 0000000000..388773a43b --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h @@ -0,0 +1,34 @@ +// 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 "FBSDKProfilePictureView.h" +#import "TargetConditionals.h" + +#if !TARGET_OS_TV + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKProfilePictureView (Internal) + +- (void)configureProfilePictureView; + +@end + +NS_ASSUME_NONNULL_END + +#endif From cf1c46d9e9342caed0cdcda6f166237f18c6c9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Cruz?= Date: Fri, 16 Oct 2020 13:18:35 -0700 Subject: [PATCH 036/227] Unit Test Hardening - FBSDKIntegrityTests Summary: Auditing - FBSDKIntegrityTests.m The `FBSDKModelManager` class was being mocked but it wasn't cleaned up. I moved the mock to the `FBSDKTestCase` class. The goal of this file is to track the mocks all in one file. The mock is now being cleaned up. Reviewed By: joesus Differential Revision: D24349018 fbshipit-source-id: c31e79129cfc66ef4bfd75794a37516a93e7da3d --- .../AppEvents/Integrity/FBSDKIntegrityTests.m | 12 ++++-------- .../Internal/Helpers/FBSDKTestCase.h | 3 +++ .../Internal/Helpers/FBSDKTestCase.m | 10 ++++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m index 3d60917f19..17123dadd8 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKIntegrityTests.m @@ -21,12 +21,9 @@ #import "FBSDKIntegrityManager.h" #import "FBSDKModelManager.h" +#import "FBSDKTestCase.h" -@interface FBSDKIntegrityTests : XCTestCase -{ - id _mockModelManager; -} - +@interface FBSDKIntegrityTests : FBSDKTestCase @end @implementation FBSDKIntegrityTests @@ -35,7 +32,6 @@ - (void)setUp { [super setUp]; [FBSDKIntegrityManager enable]; - _mockModelManager = OCMClassMock([FBSDKModelManager class]); } - (void)testProcessParameters1 @@ -46,7 +42,7 @@ - (void)testProcessParameters1 @"period_starts" : @"2020-02-03", // health }; - OCMStub([_mockModelManager processIntegrity:[OCMArg any]]).andReturn(YES); + OCMStub([self.modelManagerClassMock processIntegrity:[OCMArg any]]).andReturn(YES); NSDictionary *processed = [FBSDKIntegrityManager processParameters:parameters]; XCTAssertNil(processed[@"address"]); @@ -63,7 +59,7 @@ - (void)testProcessParameters2 @"_valueToSum" : @1, @"_session_id" : @"12345", }; - OCMStub([_mockModelManager processIntegrity:[OCMArg any]]).andReturn(NO); + OCMStub([self.modelManagerClassMock processIntegrity:[OCMArg any]]).andReturn(NO); NSDictionary *processed = [FBSDKIntegrityManager processParameters:parameters]; XCTAssertNotNil(processed[@"_valueToSum"]); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index bb4a0a789c..77dd9eac57 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -115,6 +115,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKSKAdNetworkReporter` class mock between tests @property (nullable, nonatomic, assign) id adNetworkReporterClassMock; +/// Used for sharing a `FBSDKModelManager` class mock between tests +@property (nullable, nonatomic, assign) id modelManagerClassMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 8fa2f62ede..08029ca213 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -31,6 +31,7 @@ #import "FBSDKCoreKitTestUtility.h" #import "FBSDKFeatureManager.h" #import "FBSDKKeychainStore.h" +#import "FBSDKModelManager.h" #import "FBSDKSKAdNetworkReporter.h" #import "FBSDKSettings.h" #import "FBSDKTimeSpentData.h" @@ -75,6 +76,7 @@ - (void)setUp [self setUpAdNetworkReporterMock]; [self setUpAppLinkResolverRequestBuilderMock]; [self setUpGraphRequestMock]; + [self setUpModelManagerClassMock]; } - (void)tearDown @@ -140,6 +142,9 @@ - (void)tearDown [_graphRequestMock stopMocking]; _graphRequestMock = nil; + + [_modelManagerClassMock stopMocking]; + _modelManagerClassMock = nil; } - (void)setUpSettingsMock @@ -243,6 +248,11 @@ - (void)setUpGraphRequestMock _graphRequestMock = OCMStrictClassMock(FBSDKGraphRequest.class); } +- (void)setUpModelManagerClassMock +{ + self.modelManagerClassMock = OCMClassMock(FBSDKModelManager.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID From c63db3eaf8229731e12e225f33f13aaedd5a4726 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 16 Oct 2020 16:02:14 -0700 Subject: [PATCH 037/227] Remove iOS 9.0 Gates Since 9.0 is default min version (#1528) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1528 $title Reviewed By: jingping2015 Differential Revision: D24196935 fbshipit-source-id: fddc09ceeb057842121f91541b355f46084cee5c --- .../AppLink/FBSDKWebViewAppLinkResolver.m | 15 ++-- .../FBSDKCoreKit/FBSDKApplicationDelegate.m | 10 ++- .../Internal/FBSDKInternalUtility.m | 2 +- .../FBSDKServerConfiguration.m | 8 +-- .../Codeless/FBSDKEventBindingTests.m | 68 +++++++++---------- .../FBSDKServerConfigurationTests.m | 36 ++-------- .../FBSDKShareKit/FBSDKGameRequestDialog.m | 7 +- 7 files changed, 51 insertions(+), 95 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m index d018943687..3faf0ef56d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppLink/FBSDKWebViewAppLinkResolver.m @@ -188,17 +188,10 @@ - (void)appLinkFromURL:(NSURL *)url handler:(FBSDKAppLinkBlock)handler }; webView.navigationDelegate = listener; webView.hidden = YES; - if (@available(iOS 9.0, *)) { - [webView loadData:responseData - MIMEType:response.MIMEType - characterEncodingName:response.textEncodingName - baseURL:response.URL]; - } else { - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - [request setValue:FBSDKWebViewAppLinkResolverMetaTagPrefix forHTTPHeaderField:FBSDKWebViewAppLinkResolverPreferHeader]; - [webView loadRequest:request]; - } - + [webView loadData:responseData + MIMEType:response.MIMEType + characterEncodingName:response.textEncodingName + baseURL:response.URL]; UIWindow *window = [UIApplication sharedApplication].windows.firstObject; [window addSubview:webView]; }]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m index 29d2afa94c..dfa9060df5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m @@ -181,12 +181,10 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { - if (@available(iOS 9.0, *)) { - return [self application:application - openURL:url - sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] - annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; - } + return [self application:application + openURL:url + sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] + annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; return NO; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 9f5173901f..6e9e41d662 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -624,7 +624,7 @@ + (void)checkRegisteredCanOpenURLScheme:(NSString *)urlScheme } if (![self isRegisteredCanOpenURLScheme:urlScheme]) { - NSString *reason = [NSString stringWithFormat:@"%@ is missing from your Info.plist under LSApplicationQueriesSchemes and is required for iOS 9.0", urlScheme]; + NSString *reason = [NSString stringWithFormat:@"%@ is missing from your Info.plist under LSApplicationQueriesSchemes and is required.", urlScheme]; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:reason]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m index 273fcf4751..1c6d224f0a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m @@ -149,14 +149,10 @@ + (FBSDKServerConfiguration *)defaultServerConfigurationForAppID:(NSString *)app // the server to respond. static FBSDKServerConfiguration *_defaultServerConfiguration = nil; if (![_defaultServerConfiguration.appID isEqualToString:appID]) { - // Bypass the native dialog flow for iOS 9+, as it produces a series of additional confirmation dialogs that lead to - // extra friction that is not desirable. - NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; - BOOL useNativeFlow = ![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]; - // Also enable SFSafariViewController by default. + // Enable SFSafariViewController by default. NSDictionary *dialogFlows = @{ FBSDKDialogConfigurationNameDefault : @{ - FBSDKDialogConfigurationFeatureUseNativeFlow : @(useNativeFlow), + FBSDKDialogConfigurationFeatureUseNativeFlow : @NO, FBSDKDialogConfigurationFeatureUseSafariViewController : @YES, }, FBSDKDialogConfigurationNameMessage : @{ diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m index fac505ad75..0738574a9d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m @@ -49,41 +49,39 @@ - (void)setUp { [super setUp]; - if (@available(iOS 9.0, *)) { - eventBindingManager = [[FBSDKEventBindingManager alloc] - initWithJSON:[FBSDKSampleEventBinding getSampleDictionary]]; - window = [[UIWindow alloc] init]; - UIViewController *vc = [[UIViewController alloc] init]; - UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; - - UITabBarController *tab = [[UITabBarController alloc] init]; - tab.viewControllers = @[nav]; - window.rootViewController = tab; - - UIStackView *firstStackView = [[UIStackView alloc] init]; - [vc.view addSubview:firstStackView]; - UIStackView *secondStackView = [[UIStackView alloc] init]; - [firstStackView addSubview:secondStackView]; - - btnBuy = [UIButton buttonWithType:UIButtonTypeCustom]; - [btnBuy setTitle:@"Buy" forState:UIControlStateNormal]; - [firstStackView addSubview:btnBuy]; - - UILabel *lblPrice = [[UILabel alloc] init]; - lblPrice.text = @"$2.0"; - [firstStackView addSubview:lblPrice]; - - btnConfirm = [UIButton buttonWithType:UIButtonTypeCustom]; - [btnConfirm setTitle:@"Confirm" forState:UIControlStateNormal]; - [firstStackView addSubview:btnConfirm]; - - lblPrice = [[UILabel alloc] init]; - lblPrice.text = @"$3.0"; - [secondStackView addSubview:lblPrice]; - - stepper = [[UIStepper alloc] init]; - [secondStackView addSubview:stepper]; - } + eventBindingManager = [[FBSDKEventBindingManager alloc] + initWithJSON:[FBSDKSampleEventBinding getSampleDictionary]]; + window = [[UIWindow alloc] init]; + UIViewController *vc = [[UIViewController alloc] init]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; + + UITabBarController *tab = [[UITabBarController alloc] init]; + tab.viewControllers = @[nav]; + window.rootViewController = tab; + + UIStackView *firstStackView = [[UIStackView alloc] init]; + [vc.view addSubview:firstStackView]; + UIStackView *secondStackView = [[UIStackView alloc] init]; + [firstStackView addSubview:secondStackView]; + + btnBuy = [UIButton buttonWithType:UIButtonTypeCustom]; + [btnBuy setTitle:@"Buy" forState:UIControlStateNormal]; + [firstStackView addSubview:btnBuy]; + + UILabel *lblPrice = [[UILabel alloc] init]; + lblPrice.text = @"$2.0"; + [firstStackView addSubview:lblPrice]; + + btnConfirm = [UIButton buttonWithType:UIButtonTypeCustom]; + [btnConfirm setTitle:@"Confirm" forState:UIControlStateNormal]; + [firstStackView addSubview:btnConfirm]; + + lblPrice = [[UILabel alloc] init]; + lblPrice.text = @"$3.0"; + [secondStackView addSubview:lblPrice]; + + stepper = [[UIStepper alloc] init]; + [secondStackView addSubview:stepper]; } - (void)tearDown diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m index 6e83823990..efec344995 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m @@ -503,13 +503,8 @@ - (void)testCreatingWithDialogConfigurations ); } -- (void)testCreatingWithoutDialogFlowsBelowIosVersion9 +- (void)testCreatingWithoutDialogFlows { - NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; - - id internalUtilityMock = OCMClassMock([FBSDKInternalUtility class]); - OCMStub([internalUtilityMock isOSRunTimeVersionAtLeast:iOS9Version]).andReturn(YES); - // Need to recreate with a new appID to invalidate cache of default configuration config = [FBSDKServerConfiguration defaultServerConfigurationForAppID:self.name]; @@ -523,30 +518,11 @@ - (void)testCreatingWithoutDialogFlowsBelowIosVersion9 }, }; - XCTAssertEqualObjects(config.dialogFlows, expectedDefaultDialogFlows); -} - -- (void)testCreatingWithoutDialogFlowsAboveIosVersion9 -{ - NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; - - id internalUtilityMock = OCMClassMock([FBSDKInternalUtility class]); - OCMStub([internalUtilityMock isOSRunTimeVersionAtLeast:iOS9Version]).andReturn(NO); - - // Need to recreate with a new appID to invalidate cache of default configuration - config = [FBSDKServerConfiguration defaultServerConfigurationForAppID:self.name]; - - NSDictionary *expectedDefaultDialogFlows = @{ - FBSDKDialogConfigurationNameDefault : @{ - FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, - FBSDKDialogConfigurationFeatureUseSafariViewController : @YES, - }, - FBSDKDialogConfigurationNameMessage : @{ - FBSDKDialogConfigurationFeatureUseNativeFlow : @YES, - }, - }; - - XCTAssertEqualObjects(config.dialogFlows, expectedDefaultDialogFlows); + XCTAssertEqualObjects( + config.dialogFlows, + expectedDefaultDialogFlows, + "Should use the expected default dialog flow" + ); } - (void)testCreatingWithDialogFlows diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m index 2569503f56..efb00bb6fe 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m @@ -138,12 +138,7 @@ - (BOOL)show } } - if (@available(iOS 9, *)) { - [self _launchDialogViaBridgeAPIWithParameters:parameters]; - } else { - _webDialog.parameters = parameters; - [_webDialog show]; - } + [self _launchDialogViaBridgeAPIWithParameters:parameters]; [FBSDKInternalUtility registerTransientObject:self]; return YES; From 089a7644826a582429c8e10f7b1562c8ff546da8 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005325678 Date: Mon, 19 Oct 2020 03:11:53 -0700 Subject: [PATCH 038/227] Daily `arc lint --take UNCRUSTIFY` Reviewed By: zertosh Differential Revision: D24389458 fbshipit-source-id: 9f912dd46f9c24bf515b82b239de1e68c02fffa3 --- FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 08029ca213..c9b3634d6c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -142,7 +142,7 @@ - (void)tearDown [_graphRequestMock stopMocking]; _graphRequestMock = nil; - + [_modelManagerClassMock stopMocking]; _modelManagerClassMock = nil; } From 2f51191f584d263cefc4c88fbd3061833ba220f6 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 20 Oct 2020 11:42:08 -0700 Subject: [PATCH 039/227] Fix NS_SWIFT_NAME issues 2/n (#1535) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1535 Adds a Swift name for FBSDKGateKeeperManager so that there's no compiler warning about invalid subtype `GateKeeperKey` Differential Revision: D24399076 fbshipit-source-id: c62d7753869a4a11453d6e5ab95ad470288c41ba --- .../Internal/ServerConfiguration/FBSDKGateKeeperManager.h | 1 + 1 file changed, 1 insertion(+) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.h index fa8a5b6593..8d5e582ee4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKGateKeeperManager.h @@ -27,6 +27,7 @@ typedef NSString *const FBSDKGateKeeperKey NS_TYPED_EXTENSIBLE_ENUM NS_SWIFT_NAM typedef void (^FBSDKGKManagerBlock)(NSError * _Nullable error) NS_SWIFT_NAME(GKManagerBlock); +NS_SWIFT_NAME(GateKeeperManager) @interface FBSDKGateKeeperManager : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; From 3f931200936f355575550cd0c1d064b24254b9fb Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 20 Oct 2020 11:44:11 -0700 Subject: [PATCH 040/227] Fix NS_SWIFT_NAME issues 1/n (#1537) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1537 Fixes issue with BridgeAPIProtocol since it's not actually possible to have a nested type in a Swift protocol. This causes a warning in xcode. Differential Revision: D24397014 fbshipit-source-id: f7d7088c620396bc56a7f0875ebcc6273f9db1f5 --- .../Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h index 00f2bc589a..d9a08d1f5e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h @@ -20,12 +20,11 @@ #if !TARGET_OS_TV -#import + #import -typedef NS_ENUM(NSUInteger, FBSDKBridgeAPIProtocolType) -{ +typedef NS_ENUM(NSUInteger, FBSDKBridgeAPIProtocolType) { FBSDKBridgeAPIProtocolTypeNative, FBSDKBridgeAPIProtocolTypeWeb, -} NS_SWIFT_NAME(BridgeAPIProtocol.Type); +}; #endif From 203b5ca02ba3b9759555a50d02b0ec9838c38927 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 20 Oct 2020 11:45:07 -0700 Subject: [PATCH 041/227] Update Reference Doc Generation Script Summary: For some reason Jazzy freaks out if there's an existing build in any one of the 'kit' directories. This makes sure existing build artifacts are deleted before generating the documentation. Differential Revision: D24402710 fbshipit-source-id: 10a860d4ad6bdd8cd66a114154d047ae703740fa --- scripts/run.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/run.sh b/scripts/run.sh index cf3d424929..d8901b6bbc 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -522,6 +522,8 @@ release_sdk() { release_docs() { for kit in "${SDK_KITS[@]}"; do + rm -rf "$kit/build" || true + ruby "$SDK_SCRIPTS_DIR"/genDocs.rb "$kit" # Zip the result so it can be uploaded easily From aadd2a88dd010bad5e5d63e8f6d7c6ae0bc8a6d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Cruz?= Date: Tue, 20 Oct 2020 11:50:00 -0700 Subject: [PATCH 042/227] Unit Test Hardening - FBSDKEventDeactivationTests Summary: Auditing - `FBSDKEventDeactivationTests.m` Two changes: 1. The `FBSDKServerConfigurationManager` mock class wasn't being cleaned up. By inheriting from `FBSDKTestCase`, the `FBSDKServerConfigurationManager` mock is already available and is already cleaned up during tear down. 2. The `FBSDKServerConfiguration` mock wasn't necessary. This is now replaced by a "fake" server configuration with the appropriate properties for this test. Reviewed By: joesus Differential Revision: D24373077 fbshipit-source-id: e4890f0faa6ce393b0215bf5b61c759cce8e6b1b --- .../EventDeactivation/FBSDKEventDeactivationTests.m | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m index 273c3efc44..1461080d1c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m @@ -21,24 +21,25 @@ #import "FBSDKEventDeactivationManager.h" #import "FBSDKRestrictiveDataFilterManager.h" -#import "FBSDKServerConfigurationManager.h" +#import "FBSDKServerConfigurationFixtures.h" +#import "FBSDKTestCase.h" -@interface FBSDKEventDeactivationTests : XCTestCase +@interface FBSDKEventDeactivationTests : FBSDKTestCase @end @implementation FBSDKEventDeactivationTests - (void)setUp { + [super setUp]; + NSDictionary *events = @{ @"fb_mobile_catalog_update" : @{ @"restrictive_param" : @{@"first_name" : @"6"}}, @"manual_initiated_checkout" : @{ @"deprecated_param" : @[@"deprecated_3"]}, }; - id mockServerConfiguration = OCMClassMock([FBSDKServerConfiguration class]); - OCMStub([mockServerConfiguration restrictiveParams]).andReturn(events); - id mockServerConfigurationManager = OCMClassMock([FBSDKServerConfigurationManager class]); - OCMStub([mockServerConfigurationManager cachedServerConfiguration]).andReturn(mockServerConfiguration); + FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationFixtures configWithDictionary:@{@"restrictiveParams" : events}]; + [self stubCachedServerConfigurationWithServerConfiguration:serverConfiguration]; [FBSDKEventDeactivationManager enable]; } From d599ef0997e6ed7d1e8efbf438aa4a9a3d59c46e Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 20 Oct 2020 12:52:41 -0700 Subject: [PATCH 043/227] Fix Analyzer / Compiler Warnings Summary: $title Reviewed By: jvlyn Differential Revision: D24426175 fbshipit-source-id: 196d5c3a0d8cdff06bbf8b164b07e70896594e4f --- .../ViewHierarchy/FBSDKViewHierarchy.m | 2 +- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 22 ++++++++++++------- .../AppEvents/AAM/FBSDKMetadataIndexerTests.m | 6 ++--- .../Codeless/FBSDKEventBindingTests.m | 8 +++---- .../ViewHierarchy/FBSDKViewHierarchyTests.m | 10 ++++----- .../include/FBSDKBasicUtility.h | 2 +- 6 files changed, 28 insertions(+), 22 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m index 4fe87ed5e7..e9f6718e3a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m @@ -52,7 +52,7 @@ void fb_dispatch_on_default_thread(dispatch_block_t block) } } -id getVariableFromInstance(NSObject *instance, NSString *variableName); +_Nullable id getVariableFromInstance(NSObject *instance, NSString *variableName); @implementation FBSDKViewHierarchy diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index e8d021cc09..f417a4f58d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -348,13 +348,13 @@ - (void)testCorrectGraphPathForFBProfileLoad NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; __block BOOL graphRequestMethodInvoked = false; OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY graphRequest:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { - __unsafe_unretained FBSDKGraphRequest *req = [FBSDKGraphRequest alloc]; + __unsafe_unretained FBSDKGraphRequest *req; [invocation getArgument:&req atIndex:4]; graphRequestMethodInvoked = true; XCTAssertTrue([[req graphPath] isEqualToString:graphPath]); }); OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY]).andForwardToRealObject(); - [FBSDKProfile loadProfileWithToken:nil completion:nil]; + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil]; XCTAssertTrue(graphRequestMethodInvoked); } @@ -416,9 +416,12 @@ - (void)testProfileParseBlockInvokedOnSuccessfulGraphRequest __block BOOL parseBlockInvoked = false; - [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock parseBlock:^void (id result, FBSDKProfile **profileRef) { - parseBlockInvoked = true; - }]; + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken + completion:^void (FBSDKProfile *profile, NSError *error) {} + graphRequest:self.graphRequestMock + parseBlock:^void (id parseResult, FBSDKProfile **profileRef) { + parseBlockInvoked = true; + }]; XCTAssertTrue(parseBlockInvoked); } @@ -427,9 +430,12 @@ - (void)testProfileParseBlockShouldHaveNonNullPointer id result = @{}; [self stubGraphRequestWithResult:result error:nil connection:nil]; - [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock parseBlock:^void (id result, FBSDKProfile **profileRef) { - XCTAssertTrue(profileRef != NULL); - }]; + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken + completion:^void (FBSDKProfile *profile, NSError *error) {} + graphRequest:self.graphRequestMock + parseBlock:^void (id parseResult, FBSDKProfile **profileRef) { + XCTAssertTrue(profileRef != NULL); + }]; } - (void)testProfileParseBlockReturnsNilIfResultIsEmpty diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m index 045f6d57e8..7bb3aadbad 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/AAM/FBSDKMetadataIndexerTests.m @@ -95,18 +95,18 @@ - (void)setUp }]; _emailField = [[UITextField alloc] init]; - _emailField.placeholder = @"Enter your email"; + _emailField.placeholder = NSLocalizedString(@"Enter your email", nil); _emailField.keyboardType = UIKeyboardTypeEmailAddress; _emailView = [[UITextView alloc] init]; _emailView.keyboardType = UIKeyboardTypeEmailAddress; _phoneField = [[UITextField alloc] init]; - _phoneField.placeholder = @"Enter your phone"; + _phoneField.placeholder = NSLocalizedString(@"Enter your phone", nil); _phoneField.keyboardType = UIKeyboardTypePhonePad; _pwdField = [[UITextField alloc] init]; - _pwdField.placeholder = @"Enter your password"; + _pwdField.placeholder = NSLocalizedString(@"Enter your password", nil); _pwdField.secureTextEntry = YES; _pwdView = [[UITextView alloc] init]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m index 0738574a9d..95f7948fef 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m @@ -65,19 +65,19 @@ - (void)setUp [firstStackView addSubview:secondStackView]; btnBuy = [UIButton buttonWithType:UIButtonTypeCustom]; - [btnBuy setTitle:@"Buy" forState:UIControlStateNormal]; + [btnBuy setTitle:NSLocalizedString(@"Buy", nil) forState:UIControlStateNormal]; [firstStackView addSubview:btnBuy]; UILabel *lblPrice = [[UILabel alloc] init]; - lblPrice.text = @"$2.0"; + lblPrice.text = NSLocalizedString(@"$2.0", nil); [firstStackView addSubview:lblPrice]; btnConfirm = [UIButton buttonWithType:UIButtonTypeCustom]; - [btnConfirm setTitle:@"Confirm" forState:UIControlStateNormal]; + [btnConfirm setTitle:NSLocalizedString(@"Confirm", nil) forState:UIControlStateNormal]; [firstStackView addSubview:btnConfirm]; lblPrice = [[UILabel alloc] init]; - lblPrice.text = @"$3.0"; + lblPrice.text = NSLocalizedString(@"$3.0", nil); [secondStackView addSubview:lblPrice]; stepper = [[UIStepper alloc] init]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m index cd95373c5d..858380f01f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m @@ -57,20 +57,20 @@ - (void)setUp scrollview = [[UIScrollView alloc] init]; label = [[UILabel alloc] init]; - label.text = @"I am a label"; + label.text = NSLocalizedString(@"I am a label", nil); [scrollview addSubview:label]; textField = [[UITextField alloc] init]; - textField.text = @"I am a text field"; - textField.placeholder = @"text field placeholder"; + textField.text = NSLocalizedString(@"I am a text field", nil); + textField.placeholder = NSLocalizedString(@"text field placeholder", nil); [scrollview addSubview:textField]; textView = [[UITextView alloc] init]; - textView.text = @"I am a text view"; + textView.text = NSLocalizedString(@"I am a text view", nil); [scrollview addSubview:textView]; btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 5, 20)]; - [btn setTitle:@"I am a button" forState:UIControlStateNormal]; + [btn setTitle:NSLocalizedString(@"I am a button", nil) forState:UIControlStateNormal]; [scrollview addSubview:btn]; } diff --git a/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h index 718c3229d3..d18f44e037 100644 --- a/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h @@ -71,7 +71,7 @@ setJSONStringForObject:(id)object @param invalidObjectHandler Handles objects that are invalid, returning a replacement value or nil to ignore. @return Query string representation of the parameters. */ -+ (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary ++ (nullable NSString *)queryStringWithDictionary:(NSDictionary *)dictionary error:(NSError *__autoreleasing *)errorRef invalidObjectHandler:(nullable FBSDKInvalidObjectHandler)invalidObjectHandler; From 760acc9d07baa0ef8c358cd8fba979e99d9a8c64 Mon Sep 17 00:00:00 2001 From: Marina Zvyagina Date: Thu, 22 Oct 2020 11:38:56 -0700 Subject: [PATCH 044/227] Fixed nil returned warnings (#1539) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1539 Reviewed By: jingping2015 Differential Revision: D24422629 Pulled By: joesus fbshipit-source-id: f97707c336fd3601e468cc8c061c6b59ed5c3ece --- .../AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m | 4 ++-- .../AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m | 6 +++--- Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m index e9f6718e3a..b44d13c726 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m @@ -343,7 +343,7 @@ + (nullable NSIndexPath *)getIndexPath:(NSObject *)obj id getVariableFromInstance(NSObject *instance, NSString *variableName) { if (instance == nil || variableName.length == 0) { - return nil; + return [NSNull null]; } Ivar ivar = class_getInstanceVariable([instance class], variableName.UTF8String); @@ -354,7 +354,7 @@ id getVariableFromInstance(NSObject *instance, NSString *variableName) } } - return nil; + return [NSNull null]; } + (NSString *)getText:(nullable NSObject *)obj diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m index 858380f01f..c77fc635fa 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/ViewHierarchy/FBSDKViewHierarchyTests.m @@ -121,11 +121,11 @@ - (void)testGetHint - (void)testGetInstanceVariable { // empty args should cause no-op. - XCTAssertNil(getVariableFromInstance(nil, @"anything prop")); - XCTAssertNil(getVariableFromInstance([NSObject new], nil)); + XCTAssertEqualObjects(getVariableFromInstance(nil, @"anything prop"), NSNull.null); + XCTAssertEqualObjects(getVariableFromInstance([NSObject new], nil), NSNull.null); // If there is no ivar, should return nil. - XCTAssertNil(getVariableFromInstance([NSObject new], @"some_made_up_property_123456")); + XCTAssertEqualObjects(getVariableFromInstance([NSObject new], @"some_made_up_property_123456"), NSNull.null); // this should work. XCTAssertEqualObjects(getVariableFromInstance([TestObj new], @"_a"), @"BLAH"); diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m b/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m index fe61144e78..4d58701a17 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m @@ -128,9 +128,9 @@ + (id)objectForJSONString:(NSString *)string error:(NSError *__autoreleasing *)e return [FBSDKTypeUtility JSONObjectWithData:data options:NSJSONReadingAllowFragments error:errorRef]; } -+ (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary - error:(NSError *__autoreleasing *)errorRef - invalidObjectHandler:(FBSDKInvalidObjectHandler)invalidObjectHandler ++ (nullable NSString *)queryStringWithDictionary:(NSDictionary *)dictionary + error:(NSError *__autoreleasing *)errorRef + invalidObjectHandler:(FBSDKInvalidObjectHandler)invalidObjectHandler { NSMutableString *queryString = [[NSMutableString alloc] init]; __block BOOL hasParameters = NO; From 48a3d58e8d5386e9d83593f06a62feaf6adc55b9 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 22 Oct 2020 11:42:10 -0700 Subject: [PATCH 045/227] GraphRequestPiggybackManager Tests 1/n Summary: $title Differential Revision: D24462021 fbshipit-source-id: b158b272a06744c5ad04f5e9b987f0d029efce85 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 20 +++ .../FBSDKGraphRequestPiggybackManager.m | 23 ++- .../Internal/Helpers/FBSDKTestCase.h | 3 + .../Internal/Helpers/FBSDKTestCase.m | 10 ++ .../Internal/Helpers/SampleGraphRequest.swift | 45 ++++++ .../SampleGraphRequestConnection.swift | 35 +++++ .../FBSDKGraphRequestPiggybackManagerTests.m | 141 ++++++++++++++++++ 7 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index f5904c97de..5e20af3b9c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -978,6 +978,9 @@ F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = F4DE31F524DB695100297C18 /* FBSDKTestCase.m */; }; F4E50155243648A100C99262 /* FBSDKServerConfigurationFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */; }; F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */; }; + F4EB317F2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EB317E2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m */; }; + F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */; }; + F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */; }; F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */; }; F4F98C5724CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5824CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; @@ -1688,6 +1691,9 @@ F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKServerConfigurationFixtures.h; sourceTree = ""; }; F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationFixtures.m; sourceTree = ""; }; F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationTests.m; sourceTree = ""; }; + F4EB317E2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestPiggybackManagerTests.m; sourceTree = ""; }; + F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleGraphRequestConnection.swift; sourceTree = ""; }; + F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleGraphRequest.swift; sourceTree = ""; }; F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationCenterSpy.h; sourceTree = ""; }; F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationCenterSpy.m; sourceTree = ""; }; F4F98BB324CB77F400F0D6EC /* FBSDKSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKSafeCast.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.h; sourceTree = ""; }; @@ -2146,6 +2152,7 @@ F4CD7CDA243E2CF7004C27F1 /* Helpers */, 5DB6129923593AA300150851 /* Instrument */, F420048C2416BD6D00AD7006 /* Monitoring */, + F4EB317D2540952B00736B67 /* Network */, F4E50151243648A100C99262 /* ServerConfiguration */, ); path = Internal; @@ -2805,6 +2812,8 @@ F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */, F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */, F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, + F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */, + F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */, ); path = Helpers; sourceTree = ""; @@ -2819,6 +2828,14 @@ path = ServerConfiguration; sourceTree = ""; }; + F4EB317D2540952B00736B67 /* Network */ = { + isa = PBXGroup; + children = ( + F4EB317E2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m */, + ); + path = Network; + sourceTree = ""; + }; F916580524F6BA9300BB759A /* SKAdNetwork */ = { isa = PBXGroup; children = ( @@ -4292,8 +4309,10 @@ F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */, F4A826B724EC6FAD00EB2CD4 /* FBSDKProfileTests.m in Sources */, 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */, + F4EB317F2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m in Sources */, F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m in Sources */, + F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, @@ -4306,6 +4325,7 @@ C51122A020A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m in Sources */, C51121CB20A27EF50041DC94 /* FBSDKEventBindingTests.m in Sources */, F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */, + F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */, F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m in Sources */, F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */, F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m index 2525d8d82a..7ade819841 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m @@ -30,8 +30,7 @@ + (void)addPiggybackRequests:(FBSDKGraphRequestConnection *)connection if ([FBSDKSettings appID].length > 0) { BOOL safeForPiggyback = YES; for (FBSDKGraphRequestMetadata *metadata in connection.requests) { - if (![metadata.request.version isEqualToString:[FBSDKSettings graphAPIVersion]] - || metadata.request.hasAttachments) { + if (![self _safeForPiggyback:metadata.request]) { safeForPiggyback = NO; break; } @@ -133,8 +132,8 @@ + (void)addRefreshPiggybackIfStale:(FBSDKGraphRequestConnection *)connection NSDate *now = [NSDate date]; NSDate *tokenRefreshDate = [FBSDKAccessToken currentAccessToken].refreshDate; if (tokenRefreshDate - && [now timeIntervalSinceDate:lastRefreshTry] > FBSDKTokenRefreshRetrySeconds - && [now timeIntervalSinceDate:tokenRefreshDate] > FBSDKTokenRefreshThresholdSeconds) { + && [now timeIntervalSinceDate:lastRefreshTry] > [self _tokenRefreshRetryInSeconds] + && [now timeIntervalSinceDate:tokenRefreshDate] > [self _tokenRefreshThresholdInSeconds]) { [self addRefreshPiggyback:connection permissionHandler:NULL]; lastRefreshTry = [NSDate date]; } @@ -155,4 +154,20 @@ + (void)addServerConfigurationPiggyback:(FBSDKGraphRequestConnection *)connectio }]; } ++ (BOOL)_safeForPiggyback:(FBSDKGraphRequest *)request +{ + return [request.version isEqualToString:[FBSDKSettings graphAPIVersion]] + && !request.hasAttachments; +} + ++ (int)_tokenRefreshThresholdInSeconds +{ + return FBSDKTokenRefreshThresholdSeconds; +} + ++ (int)_tokenRefreshRetryInSeconds +{ + return FBSDKTokenRefreshRetrySeconds; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 77dd9eac57..a166e44abe 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -118,6 +118,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKModelManager` class mock between tests @property (nullable, nonatomic, assign) id modelManagerClassMock; +/// Used for sharing a `FBSDKGraphRequestPiggybackManager` class mock between tests +@property (nullable, nonatomic, assign) id graphRequestPiggybackManagerMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index c9b3634d6c..a310713c5a 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -30,6 +30,7 @@ #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" #import "FBSDKFeatureManager.h" +#import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKKeychainStore.h" #import "FBSDKModelManager.h" #import "FBSDKSKAdNetworkReporter.h" @@ -77,6 +78,7 @@ - (void)setUp [self setUpAppLinkResolverRequestBuilderMock]; [self setUpGraphRequestMock]; [self setUpModelManagerClassMock]; + [self setUpGraphRequestPiggybackManagerMock]; } - (void)tearDown @@ -145,6 +147,9 @@ - (void)tearDown [_modelManagerClassMock stopMocking]; _modelManagerClassMock = nil; + + [_graphRequestPiggybackManagerMock stopMocking]; + _graphRequestPiggybackManagerMock = nil; } - (void)setUpSettingsMock @@ -253,6 +258,11 @@ - (void)setUpModelManagerClassMock self.modelManagerClassMock = OCMClassMock(FBSDKModelManager.class); } +- (void)setUpGraphRequestPiggybackManagerMock +{ + self.graphRequestPiggybackManagerMock = OCMClassMock(FBSDKGraphRequestPiggybackManager.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift new file mode 100644 index 0000000000..ba3360c149 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift @@ -0,0 +1,45 @@ +// 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 Foundation +@testable import FBSDKCoreKit + +@objc public class SampleGraphRequest : NSObject { + + @objc public static let valid = create() + @objc public static var withOutdatedVersionWithAttachment = create( + parameters: ["attachment": Data(count: 8)], + version: "3.0" + ) + @objc public static var withOutdatedVersion = create(version: "3.0") + @objc public static var withAttachment = create(parameters: ["attachment": Data(count: 8)]) + + @objc public static func create( + path: String = "/me", + parameters: [String: Any] = [:], + version: String = Settings.graphAPIVersion + ) -> GraphRequest { + return GraphRequest( + graphPath: path, + parameters: parameters, + tokenString: nil, + version: version, + httpMethod: HTTPMethod.get + ) + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift new file mode 100644 index 0000000000..bdebc5cd81 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift @@ -0,0 +1,35 @@ +// 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 Foundation +@testable import FBSDKCoreKit + +@objc public class SampleGraphRequestConnection : NSObject { + + @objc public static var empty: GraphRequestConnection { + GraphRequestConnection() + } + + @objc public static func with(requests: [GraphRequest]) -> GraphRequestConnection { + let connection = GraphRequestConnection() + requests.forEach { + connection.add($0) { _, _, _ in } + } + return connection + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m new file mode 100644 index 0000000000..087dcef153 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -0,0 +1,141 @@ +// 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 "FBSDKCoreKitTests-Swift.h" +#import "FBSDKGraphRequestPiggybackManager.h" +#import "FBSDKTestCase.h" + +@interface FBSDKGraphRequestPiggybackManager (Testing) + ++ (int)_tokenRefreshThresholdInSeconds; ++ (int)_tokenRefreshRetryInSeconds; ++ (BOOL)_safeForPiggyback:(FBSDKGraphRequest *)request; + +@end + +@interface FBSDKGraphRequestPiggybackManagerTests : FBSDKTestCase + +@end + +@implementation FBSDKGraphRequestPiggybackManagerTests + +typedef FBSDKGraphRequestPiggybackManager Manager; + +- (void)testRefreshThresholdInSeconds +{ + int oneDayInSeconds = 24 * 60 * 60; + XCTAssertEqual( + [Manager _tokenRefreshThresholdInSeconds], + oneDayInSeconds, + "There should be a well-known value for the token refresh threshold" + ); +} + +- (void)testRefreshRetryInSeconds +{ + int oneHourInSeconds = 60 * 60; + XCTAssertEqual( + [Manager _tokenRefreshRetryInSeconds], + oneHourInSeconds, + "There should be a well-known value for the token refresh retry threshold" + ); +} + +- (void)testAddingRequestsWithoutAppID +{ + [self stubAppID:@""]; + + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:OCMArg.any])); + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addServerConfigurationPiggyback:OCMArg.any])); + + [Manager addPiggybackRequests:SampleGraphRequestConnection.empty]; +} + +- (void)testSafeForAddingWithMatchingGraphVersionWithAttachment +{ + XCTAssertFalse( + [Manager _safeForPiggyback:SampleGraphRequest.withAttachment], + "A request with an attachment is not considered safe for piggybacking" + ); +} + +- (void)testSafeForAddingWithMatchingGraphVersionWithoutAttachment +{ + XCTAssertTrue( + [Manager _safeForPiggyback:SampleGraphRequest.valid], + "A request without an attachment is considered safe for piggybacking" + ); +} + +- (void)testSafeForAddingWithoutMatchingGraphVersionWithAttachment +{ + XCTAssertFalse( + [Manager _safeForPiggyback:SampleGraphRequest.withOutdatedVersionWithAttachment], + "A request with an attachment and outdated version is not considered safe for piggybacking" + ); +} + +- (void)testSafeForAddingWithoutMatchingGraphVersionWithoutAttachment +{ + XCTAssertFalse( + [Manager _safeForPiggyback:SampleGraphRequest.withOutdatedVersion], + "A request with an outdated version is not considered safe for piggybacking" + ); +} + +- (void)testAddingRequestsForConnectionWithSafeRequests +{ + [self stubAppID:@"abc123"]; + FBSDKGraphRequestConnection *connection = [SampleGraphRequestConnection withRequests:@[SampleGraphRequest.valid]]; + + [Manager addPiggybackRequests:connection]; + + OCMVerify(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:connection])); + OCMVerify(ClassMethod([self.graphRequestPiggybackManagerMock addServerConfigurationPiggyback:connection])); +} + +- (void)testAddingRequestsForConnectionWithUnsafeRequests +{ + [self stubAppID:@"abc123"]; + FBSDKGraphRequestConnection *connection = [SampleGraphRequestConnection withRequests:@[SampleGraphRequest.withAttachment]]; + + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:connection])); + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addServerConfigurationPiggyback:connection])); + + [Manager addPiggybackRequests:connection]; +} + +- (void)testAddingRequestsForConnectionWithSafeAndUnsafeRequests +{ + [self stubAppID:@"abc123"]; + FBSDKGraphRequestConnection *connection = [SampleGraphRequestConnection withRequests:@[ + SampleGraphRequest.valid, + SampleGraphRequest.withAttachment + ]]; + + // No requests are piggybacked if any are invalid + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:connection])); + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addServerConfigurationPiggyback:connection])); + + [Manager addPiggybackRequests:connection]; +} + +@end From dcf76f61cf338de2fb38de5b8dc119c5819009a3 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 22 Oct 2020 14:44:28 -0700 Subject: [PATCH 046/227] Add fields parameters where obviously missing (#1545) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1545 This adds an empty fields parameter to call sites that are clearly missing one. This should cut down on issues like this one - https://github.com/facebook/facebook-ios-sdk/issues/1403 Reviewed By: jingping2015 Differential Revision: D24422317 fbshipit-source-id: 28533806fcb202f82e1300a34f7926c1f8b70910 --- .../FBSDKSuggestedEventsIndexer.m | 6 ++- .../FBSDKCoreKit/FBSDKTestUsersManager.m | 4 +- .../FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m | 8 +++- .../FBSDKGraphRequestTests.m | 44 ++++++++++++------- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m index d4e427aa3b..4609fdda62 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/SuggestedEvents/FBSDKSuggestedEventsIndexer.m @@ -273,8 +273,10 @@ + (void)logSuggestedEvent:(NSString *)event withText:(NSString *)text withDenseF FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/suggested_events", [FBSDKSettings appID]] - parameters:@{@"event_name" : event, - @"metadata" : metadata, } + parameters:@{ + @"event_name" : event, + @"metadata" : metadata, + } HTTPMethod:FBSDKHTTPMethodPOST]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {}]; return; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m index 955ba74dcb..85f4550c7a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m @@ -199,7 +199,7 @@ - (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken - (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKErrorBlock)handler { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:userId - parameters:@{} + parameters:@{@"fields" : @""} tokenString:self.appAccessToken version:nil HTTPMethod:@"DELETE"]; @@ -284,7 +284,7 @@ - (void)fetchExistingTestAccountsWithAfterCursor:(NSString *)after handler:(FBSD self->_accounts[userId][kAccountsDictionaryTokenKey] = token; expectedTestAccounts++; [permissionConnection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@?fields=permissions", userId] - parameters:@{} + parameters:@{@"fields" : @""} tokenString:self.appAccessToken version:nil HTTPMethod:FBSDKHTTPMethodGET] diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m index b3b06dd521..7aa0d386da 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m @@ -44,13 +44,17 @@ @implementation FBSDKGraphRequest - (instancetype)initWithGraphPath:(NSString *)graphPath { - return [self initWithGraphPath:graphPath parameters:@{}]; + return [self initWithGraphPath:graphPath parameters:@{@"fields" : @""}]; } - (instancetype)initWithGraphPath:(NSString *)graphPath HTTPMethod:(FBSDKHTTPMethod)method { - return [self initWithGraphPath:graphPath parameters:@{} HTTPMethod:method]; + if (method == FBSDKHTTPMethodGET) { + return [self initWithGraphPath:graphPath parameters:@{@"fields" : @""} HTTPMethod:method]; + } else { + return [self initWithGraphPath:graphPath parameters:@{} HTTPMethod:method]; + } } - (instancetype)initWithGraphPath:(NSString *)graphPath diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m index bde573eba0..35490f4125 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestTests.m @@ -36,7 +36,7 @@ return @{@"fields" : @""}; } -static NSDictionary *const _mockEmptyParamter(void) +static NSDictionary *const _mockEmptyParameters(void) { return @{}; } @@ -57,13 +57,21 @@ - (void)setUp #pragma mark - Tests +- (void)testDefaultGETParameters +{ + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath]; + + [_mockConnection addRequest:request + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; + [self verifyRequest:request expectedGraphPath:_mockGraphPath expectedParameters:_mockParameters() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodGET]; +} + - (void)testGraphRequestGETWithEmptyParameters { - FBSDKGraphRequest *request1 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath]; - FBSDKGraphRequest *request2 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter()]; - FBSDKGraphRequest *request3 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() flags:FBSDKGraphRequestFlagNone]; - FBSDKGraphRequest *request4 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodGET]; - FBSDKGraphRequest *request5 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodGET]; + FBSDKGraphRequest *request1 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParameters()]; + FBSDKGraphRequest *request2 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParameters() flags:FBSDKGraphRequestFlagNone]; + FBSDKGraphRequest *request3 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParameters() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodGET]; + FBSDKGraphRequest *request4 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParameters() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodGET]; [_mockConnection addRequest:request1 completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; @@ -73,11 +81,9 @@ - (void)testGraphRequestGETWithEmptyParameters completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request4 completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; - [_mockConnection addRequest:request5 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; for (FBSDKGraphRequestMetadata *metadata in _mockConnection.requests) { - [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParamter() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodGET]; + [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParameters() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodGET]; } } @@ -102,21 +108,27 @@ - (void)testGraphRequestGETWithNonEmptyParameters } } +- (void)testDefaultPOSTParameters +{ + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath HTTPMethod:FBSDKHTTPMethodPOST]; + + [_mockConnection addRequest:request + completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; + [self verifyRequest:request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParameters() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodPOST]; +} + - (void)testGraphRequestPOSTWithEmptyParameters { - FBSDKGraphRequest *request1 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath HTTPMethod:FBSDKHTTPMethodPOST]; - FBSDKGraphRequest *request2 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() HTTPMethod:FBSDKHTTPMethodPOST]; - FBSDKGraphRequest *request3 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParamter() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodPOST]; + FBSDKGraphRequest *request1 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParameters() HTTPMethod:FBSDKHTTPMethodPOST]; + FBSDKGraphRequest *request2 = [[FBSDKGraphRequest alloc] initWithGraphPath:_mockGraphPath parameters:_mockEmptyParameters() tokenString:nil version:_mockDefaultVersion HTTPMethod:FBSDKHTTPMethodPOST]; [_mockConnection addRequest:request1 completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; [_mockConnection addRequest:request2 completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; - [_mockConnection addRequest:request3 - completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) {}]; for (FBSDKGraphRequestMetadata *metadata in _mockConnection.requests) { - [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParamter() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodPOST]; + [self verifyRequest:metadata.request expectedGraphPath:_mockGraphPath expectedParameters:_mockEmptyParameters() expectedTokenString:nil expectedVersion:_mockDefaultVersion expectedMethod:FBSDKHTTPMethodPOST]; } } @@ -140,7 +152,7 @@ - (void)testSerializeURL NSString *baseURL = [FBSDKInternalUtility facebookURLWithHostPrefix:_mockPrefix path:_mockGraphPath - queryParameters:_mockEmptyParamter() + queryParameters:_mockEmptyParameters() defaultVersion:_mockDefaultVersion error:NULL].absoluteString; NSString *url = [FBSDKGraphRequest serializeURL:baseURL From 9501a778fedd5cdff5ea19b577b6d290d85c21a8 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 22 Oct 2020 15:31:43 -0700 Subject: [PATCH 047/227] Remove TriStateBool 1/2 (#1534) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1534 We should not have a type that is easily represented by a Swift optional. Especially since a BOOL is basically always tri-state in ObjC. Followup work can remove it entirely from `LikeActionController` Reviewed By: tianqibt Differential Revision: D24396921 fbshipit-source-id: ba033536f1e506b35e0dea1cdeada88eec2a4bdd --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 12 ----- .../Internal/FBSDKCoreKit+Internal.h | 2 - .../FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h | 36 -------------- .../FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m | 49 ------------------- .../Internal/FBSDKLikeActionController.m | 34 +++++++++++++ 5 files changed, 34 insertions(+), 99 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h delete mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 5e20af3b9c..c31fb3bfdd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -308,7 +308,6 @@ 81B71D0E1D19C87400933E93 /* FBSDKTestUsersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D7E7E601ADF038800F53E38 /* FBSDKTestUsersManager.m */; }; 81B71D0F1D19C87400933E93 /* FBSDKMeasurementEventListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB63D9D1A9BE730003A7AED /* FBSDKMeasurementEventListener.m */; }; 81B71D101D19C87400933E93 /* FBSDKProfilePictureView.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3CF71A8BF73A00EA8658 /* FBSDKProfilePictureView.m */; }; - 81B71D111D19C87400933E93 /* FBSDKTriStateBOOL.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D05A941AA0E89B00609300 /* FBSDKTriStateBOOL.m */; }; 81B71D121D19C87400933E93 /* FBSDKLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D6999FD1A76E166003AE384 /* FBSDKLogger.m */; }; 81B71D131D19C87400933E93 /* FBSDKApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D34A11E1A5F038300C37317 /* FBSDKApplicationDelegate.m */; }; 81B71D141D19C87400933E93 /* FBSDKDynamicFrameworkLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 81C969311C114723002FC037 /* FBSDKDynamicFrameworkLoader.m */; }; @@ -383,7 +382,6 @@ 81B71D651D19C87400933E93 /* FBSDKBridgeAPIRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0ACF1A6F15F7009137EF /* FBSDKBridgeAPIRequest.h */; }; 81B71D671D19C87400933E93 /* FBSDKWebDialogView.h in Headers */ = {isa = PBXBuildFile; fileRef = 89FB8C481A842A8A003CAE60 /* FBSDKWebDialogView.h */; }; 81B71D681D19C87400933E93 /* FBSDKServerConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8917C4AB1B7A46C800B0B96B /* FBSDKServerConfiguration+Internal.h */; }; - 81B71D691D19C87400933E93 /* FBSDKTriStateBOOL.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D05A931AA0E89B00609300 /* FBSDKTriStateBOOL.h */; }; 81B71D6A1D19C87400933E93 /* FBSDKCloseIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D652821A855A6000BB651C /* FBSDKCloseIcon.h */; }; 81B71D6B1D19C87400933E93 /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DF18BB71A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.h */; }; 81B71D6D1D19C87400933E93 /* FBSDKProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DA81AF41AA4EF3300B9FE0B /* FBSDKProfile.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -490,8 +488,6 @@ 89C8B1991A8D7A15009B07F5 /* FBSDKUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 89C8B1971A8D7A15009B07F5 /* FBSDKUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 89C8B19A1A8D7A15009B07F5 /* FBSDKUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */; }; 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.m */; }; - 89D05A951AA0E89B00609300 /* FBSDKTriStateBOOL.h in Headers */ = {isa = PBXBuildFile; fileRef = 89D05A931AA0E89B00609300 /* FBSDKTriStateBOOL.h */; }; - 89D05A961AA0E89B00609300 /* FBSDKTriStateBOOL.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D05A941AA0E89B00609300 /* FBSDKTriStateBOOL.m */; }; 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 */; }; @@ -1428,8 +1424,6 @@ 89C8B1971A8D7A15009B07F5 /* FBSDKUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKUtility.h; sourceTree = ""; }; 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUtility.m; sourceTree = ""; }; 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUtilityTests.m; sourceTree = ""; }; - 89D05A931AA0E89B00609300 /* FBSDKTriStateBOOL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKTriStateBOOL.h; sourceTree = ""; }; - 89D05A941AA0E89B00609300 /* FBSDKTriStateBOOL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTriStateBOOL.m; sourceTree = ""; }; 89D05AA71AA1134000609300 /* FBSDKAudioResourceLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAudioResourceLoader.h; sourceTree = ""; }; 89D05AA81AA1134000609300 /* FBSDKAudioResourceLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAudioResourceLoader.m; sourceTree = ""; }; 89D4AE851A7FFEFC00DB8C72 /* FBSDKBridgeAPIRequest+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKBridgeAPIRequest+Private.h"; sourceTree = ""; }; @@ -2093,8 +2087,6 @@ ADEA17721B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m */, 9DE6C46D1AAF6E2800EC4C99 /* FBSDKProfile+Internal.h */, 9DA830421A699A2200770955 /* FBSDKSettings+Internal.h */, - 89D05A931AA0E89B00609300 /* FBSDKTriStateBOOL.h */, - 89D05A941AA0E89B00609300 /* FBSDKTriStateBOOL.m */, C5696FA1209CCEB3009C931F /* FBSDKSwizzler.h */, C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */, 52963A9D215993C100C7B252 /* FBSDKURL_Internal.h */, @@ -3053,7 +3045,6 @@ 81B71D651D19C87400933E93 /* FBSDKBridgeAPIRequest.h in Headers */, 81B71D671D19C87400933E93 /* FBSDKWebDialogView.h in Headers */, 81B71D681D19C87400933E93 /* FBSDKServerConfiguration+Internal.h in Headers */, - 81B71D691D19C87400933E93 /* FBSDKTriStateBOOL.h in Headers */, 81B71D6A1D19C87400933E93 /* FBSDKCloseIcon.h in Headers */, 5DBC72D22373793400A9D859 /* FBSDKModelManager.h in Headers */, 81B71D6B1D19C87400933E93 /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, @@ -3190,7 +3181,6 @@ 8917C4AD1B7A46C800B0B96B /* FBSDKServerConfiguration+Internal.h in Headers */, E4416C0123F61902009CCBFA /* FBSDKModelParser.h in Headers */, F40F6561241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h in Headers */, - 89D05A951AA0E89B00609300 /* FBSDKTriStateBOOL.h in Headers */, 5D41131E229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.h in Headers */, 89D652841A855A6000BB651C /* FBSDKCloseIcon.h in Headers */, F4D8D8DC2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */, @@ -4036,7 +4026,6 @@ 81B71D0E1D19C87400933E93 /* FBSDKTestUsersManager.m in Sources */, 81B71D0F1D19C87400933E93 /* FBSDKMeasurementEventListener.m in Sources */, 81B71D101D19C87400933E93 /* FBSDKProfilePictureView.m in Sources */, - 81B71D111D19C87400933E93 /* FBSDKTriStateBOOL.m in Sources */, F9A06DD42510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, 5DBC72D92373795600A9D859 /* FBSDKModelManager.mm in Sources */, 81B71D121D19C87400933E93 /* FBSDKLogger.m in Sources */, @@ -4160,7 +4149,6 @@ 899C3CF91A8BF73A00EA8658 /* FBSDKProfilePictureView.m in Sources */, F9A06DD32510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, 5DBC72D82373795600A9D859 /* FBSDKModelManager.mm in Sources */, - 89D05A961AA0E89B00609300 /* FBSDKTriStateBOOL.m in Sources */, 9D6999FF1A76E166003AE384 /* FBSDKLogger.m in Sources */, 9D34A1201A5F038300C37317 /* FBSDKApplicationDelegate.m in Sources */, C5188E372231C4B500F4D8BC /* FBSDKBridgeAPI.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 6ea5ad9295..c0ac57830e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -48,7 +48,6 @@ #import "FBSDKMonotonicTime.h" #import "FBSDKSKAdNetworkReporter.h" #import "FBSDKSuggestedEventsIndexer.h" - #import "FBSDKTriStateBOOL.h" #import "FBSDKUIUtility.h" #import "FBSDKViewHierarchy.h" #import "FBSDKViewHierarchyMacros.h" @@ -116,7 +115,6 @@ #import "FBSDKAudioResourceLoader.h" #import "FBSDKContainerViewController.h" #import "FBSDKMonotonicTime.h" - #import "FBSDKTriStateBOOL.h" #import "UI/FBSDKCloseIcon.h" #import "UI/FBSDKColor.h" #import "UI/FBSDKMaleSilhouetteIcon.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h deleted file mode 100644 index d5c1dbe12c..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h +++ /dev/null @@ -1,36 +0,0 @@ -// 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 "TargetConditionals.h" - -#if !TARGET_OS_TV - -#import - -typedef NS_ENUM(NSInteger, FBSDKTriStateBOOL) -{ - FBSDKTriStateBOOLValueUnknown = -1, - FBSDKTriStateBOOLValueNO = 0, - FBSDKTriStateBOOLValueYES = 1, -} NS_SWIFT_NAME(TriStateBool.Value); - -FOUNDATION_EXPORT FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value); -FOUNDATION_EXPORT FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value); -FOUNDATION_EXPORT BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue); - -#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m deleted file mode 100644 index 14d02f7c4e..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m +++ /dev/null @@ -1,49 +0,0 @@ -// 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 "TargetConditionals.h" - -#if !TARGET_OS_TV - - #import "FBSDKTriStateBOOL.h" - -FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value) -{ - return value ? FBSDKTriStateBOOLValueYES : FBSDKTriStateBOOLValueNO; -} - -FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value) -{ - return ([value isKindOfClass:[NSNumber class]] - ? FBSDKTriStateBOOLFromBOOL(value.boolValue) - : FBSDKTriStateBOOLValueUnknown); -} - -BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue) -{ - switch (value) { - case FBSDKTriStateBOOLValueYES: - return YES; - case FBSDKTriStateBOOLValueNO: - return NO; - case FBSDKTriStateBOOLValueUnknown: - return defaultValue; - } -} - -#endif diff --git a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m index dd95f9d43c..2e560b0b4c 100644 --- a/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m +++ b/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m @@ -38,6 +38,40 @@ #import "FBSDKLikeActionControllerCache.h" #import "FBSDKLikeDialog.h" +typedef NS_ENUM(NSInteger, FBSDKTriStateBOOL) { + FBSDKTriStateBOOLValueUnknown = -1, + FBSDKTriStateBOOLValueNO = 0, + FBSDKTriStateBOOLValueYES = 1, +}; + +FOUNDATION_EXPORT FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value); +FOUNDATION_EXPORT FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value); +FOUNDATION_EXPORT BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue); + +FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value) +{ + return value ? FBSDKTriStateBOOLValueYES : FBSDKTriStateBOOLValueNO; +} + +FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value) +{ + return ([value isKindOfClass:[NSNumber class]] + ? FBSDKTriStateBOOLFromBOOL(value.boolValue) + : FBSDKTriStateBOOLValueUnknown); +} + +BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue) +{ + switch (value) { + case FBSDKTriStateBOOLValueYES: + return YES; + case FBSDKTriStateBOOLValueNO: + return NO; + case FBSDKTriStateBOOLValueUnknown: + return defaultValue; + } +} + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 NSNotificationName const FBSDKLikeActionControllerDidDisableNotification = @"FBSDKLikeActionControllerDidDisableNotification"; From 82a8e7dbc1f5ee69599629bc10a70cc06d42f8c4 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 23 Oct 2020 10:36:11 -0700 Subject: [PATCH 048/227] Remove UIKit version checks (#1536) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1536 The `FBSDKUIKitVersion` enum was only being used to check if the version was at least 8. Our minimum supported version is now 9 so there is no reason to keep this check. Basically afaict this was all to deal with orientation changes prior to iOS 8 so it can all go. Reviewed By: jingping2015 Differential Revision: D24397387 fbshipit-source-id: 8bdd4daef82d02d5f21141c346445e1c7e91c7f4 --- .../Internal/FBSDKInternalUtility.h | 36 ----------------- .../Internal/FBSDKInternalUtility.m | 31 --------------- .../Internal/WebDialog/FBSDKWebDialog.m | 39 +------------------ 3 files changed, 2 insertions(+), 104 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h index 9365454e0c..465a589ca6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h @@ -28,15 +28,6 @@ NS_ASSUME_NONNULL_BEGIN #define FBSDK_CANOPENURL_MSQRD_PLAYER @"msqrdplayer" #define FBSDK_CANOPENURL_SHARE_EXTENSION @"fbshareextension" -typedef NS_ENUM(int32_t, FBSDKUIKitVersion) -{ - FBSDKUIKitVersion_6_0 = 0x0944, - FBSDKUIKitVersion_6_1 = 0x094C, - FBSDKUIKitVersion_7_0 = 0x0B57, - FBSDKUIKitVersion_7_1 = 0x0B77, - FBSDKUIKitVersion_8_0 = 0x0CF6, -} NS_SWIFT_NAME(FBUIKit.Version); - /** Describes the callback for appLinkFromURLInBackground. @param object the FBSDKAppLink representing the deferred App Link @@ -80,19 +71,6 @@ NS_SWIFT_NAME(InternalUtility) */ @property (class, nonatomic, assign, readonly) NSOperatingSystemVersion operatingSystemVersion; -/** - Tests whether the orientation should be manually adjusted for views outside of the root view controller. - - With the legacy layout the developer must worry about device orientation when working with views outside of - the window's root view controller and apply the correct rotation transform and/or swap a view's width and height - values. If the application was linked with UIKit on iOS 7 or earlier or the application is running on iOS 7 or earlier - then we need to use the legacy layout code. Otherwise if the application was linked with UIKit on iOS 8 or later and - the application is running on iOS 8 or later, UIKit handles all of the rotation complexity and the origin is always in - the top-left and no rotation transform is necessary. - @return YES if if the orientation must be manually adjusted, otherwise NO. - */ -@property (class, nonatomic, assign, readonly) BOOL shouldManuallyAdjustOrientation; - /* Checks if the app is Unity. */ @@ -174,20 +152,6 @@ NS_SWIFT_NAME(InternalUtility) */ + (BOOL)isSafariBundleIdentifier:(NSString *)bundleIdentifier; -/** - Tests whether the UIKit version that the current app was linked to is at least the specified version. - @param version The version to test against. - @return YES if the linked UIKit version is greater than or equal to the specified version, otherwise NO. - */ -+ (BOOL)isUIKitLinkTimeVersionAtLeast:(FBSDKUIKitVersion)version; - -/** - Tests whether the UIKit version in the runtime is at least the specified version. - @param version The version to test against. - @return YES if the runtime UIKit version is greater than or equal to the specified version, otherwise NO. - */ -+ (BOOL)isUIKitRunTimeVersionAtLeast:(FBSDKUIKitVersion)version; - /** Checks equality between 2 objects. diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 6e9e41d662..148bbb195f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -212,28 +212,6 @@ + (BOOL)isSafariBundleIdentifier:(NSString *)bundleIdentifier || [bundleIdentifier isEqualToString:@"com.apple.SafariViewService"]); } -+ (BOOL)isUIKitLinkTimeVersionAtLeast:(FBSDKUIKitVersion)version -{ - static int32_t linkTimeMajorVersion; - static dispatch_once_t getVersionOnce; - dispatch_once(&getVersionOnce, ^{ - int32_t linkTimeVersion = NSVersionOfLinkTimeLibrary("UIKit"); - linkTimeMajorVersion = [self getMajorVersionFromFullLibraryVersion:linkTimeVersion]; - }); - return (version <= linkTimeMajorVersion); -} - -+ (BOOL)isUIKitRunTimeVersionAtLeast:(FBSDKUIKitVersion)version -{ - static int32_t runTimeMajorVersion; - static dispatch_once_t getVersionOnce; - dispatch_once(&getVersionOnce, ^{ - int32_t runTimeVersion = NSVersionOfRunTimeLibrary("UIKit"); - runTimeMajorVersion = [self getMajorVersionFromFullLibraryVersion:runTimeVersion]; - }); - return (version <= runTimeMajorVersion); -} - + (int32_t)getMajorVersionFromFullLibraryVersion:(int32_t)version { // Negative values returned by NSVersionOfRunTimeLibrary/NSVersionOfLinkTimeLibrary @@ -282,21 +260,12 @@ + (NSOperatingSystemVersion)operatingSystemVersion case 1: operatingSystemVersion.majorVersion = [[FBSDKTypeUtility array:components objectAtIndex:0] integerValue]; break; - case 0: - operatingSystemVersion.majorVersion = ([self isUIKitLinkTimeVersionAtLeast:FBSDKUIKitVersion_7_0] ? 7 : 6); - break; } } }); return operatingSystemVersion; } -+ (BOOL)shouldManuallyAdjustOrientation -{ - return (![self isUIKitLinkTimeVersionAtLeast:FBSDKUIKitVersion_8_0] - || ![self isUIKitRunTimeVersionAtLeast:FBSDKUIKitVersion_8_0]); -} - + (NSURL *)URLWithScheme:(NSString *)scheme host:(NSString *)host path:(NSString *)path diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m index 967b108cd4..7bec076f97 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m @@ -262,27 +262,6 @@ - (BOOL)_showWebView return YES; } -- (CGAffineTransform)_transformForOrientation -{ - // iOS 8 simply adjusts the application frame to adapt to the current orientation and deprecated the concept of - // interface orientations - if ([FBSDKInternalUtility shouldManuallyAdjustOrientation]) { - switch (FBSDKInternalUtility.statusBarOrientation) { - case UIInterfaceOrientationLandscapeLeft: - return CGAffineTransformMakeRotation(M_PI * 1.5); - case UIInterfaceOrientationLandscapeRight: - return CGAffineTransformMakeRotation(M_PI / 2); - case UIInterfaceOrientationPortraitUpsideDown: - return CGAffineTransformMakeRotation(-M_PI); - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationUnknown: - // don't adjust the orientation - break; - } - } - return CGAffineTransformIdentity; -} - - (CGRect)_applicationFrameForOrientation { CGRect applicationFrame = _dialogView.window.screen.bounds; @@ -305,19 +284,7 @@ - (CGRect)_applicationFrameForOrientation applicationFrame.size.width -= insets.left + insets.right; applicationFrame.size.height -= insets.top + insets.bottom; - if ([FBSDKInternalUtility shouldManuallyAdjustOrientation]) { - switch (FBSDKInternalUtility.statusBarOrientation) { - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - return CGRectMake(0, 0, CGRectGetHeight(applicationFrame), CGRectGetWidth(applicationFrame)); - case UIInterfaceOrientationPortraitUpsideDown: - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationUnknown: - return applicationFrame; - } - } else { - return applicationFrame; - } + return applicationFrame; } - (void)_updateViewsWithScale:(CGFloat)scale @@ -325,15 +292,13 @@ - (void)_updateViewsWithScale:(CGFloat)scale animationDuration:(CFTimeInterval)animationDuration completion:(FBSDKBoolBlock)completion { - CGAffineTransform transform; + CGAffineTransform transform = _dialogView.transform; CGRect applicationFrame = [self _applicationFrameForOrientation]; if (scale == 1.0) { - transform = _dialogView.transform; _dialogView.transform = CGAffineTransformIdentity; _dialogView.frame = applicationFrame; _dialogView.transform = transform; } - transform = CGAffineTransformScale([self _transformForOrientation], scale, scale); void (^updateBlock)(void) = ^{ self->_dialogView.transform = transform; self->_dialogView.center = CGPointMake( From 3fe195191512831ea0f9d3a7ced3170459608dce Mon Sep 17 00:00:00 2001 From: firewood Date: Mon, 26 Oct 2020 11:41:31 -0700 Subject: [PATCH 049/227] Fix a multi-thread issue in the initialization. (#1285) Summary: - [x] sign [contributor license agreement](https://developers.facebook.com/opensource/cla) - [x] I've ensured that all existing tests pass and added tests (when/where necessary) - [x] I've updated the documentation (when/where necessary) and [Changelog](CHANGELOG.md) (when/where necessary) - [x] I've added the proper label to this pull request (e.g. `bug` for bug fixes) ## Pull Request Details There are few crashes in our app during the initialization. When the app initializes both of Facebook SDK and Facebook Audience Network SDK in the close timing, the app will crash due to the multiple access to the variable (_observers). Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1285 Test Plan: I've created a simplified example to describe the issue. The app will crash without `synchronized`. https://gist.github.com/firewood/54ce08372aec55e43dfc245ae285ad4a Reviewed By: dreamolight Differential Revision: D24541739 Pulled By: joesus fbshipit-source-id: 640d7bde592a9d5d34b47c17d0c793f0bf77b174 --- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index 7dcf6a8649..38bbbbd9b5 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -85,8 +85,7 @@ + (void)initialize + (void)sendCrashLogs { - NSArray> *observers = [_observers copy]; - for (id observer in observers) { + for (id observer in _observers) { if (observer && [observer respondsToSelector:@selector(didReceiveCrashLogs:)]) { NSArray *> *filteredCrashLogs = [self filterCrashLogs:observer.prefixes processedCrashLogs:_processedCrashLogs]; [observer didReceiveCrashLogs:filteredCrashLogs]; @@ -138,22 +137,26 @@ + (void)addObserver:(id)observer installSignalsHandler(); _processedCrashLogs = [self getProcessedCrashLogs]; }); - if (![_observers containsObject:observer]) { - [_observers addObject:observer]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) { - [self generateMethodMapping:observer]; - }); - [self sendCrashLogs]; + @synchronized(_observers) { + if (![_observers containsObject:observer]) { + [_observers addObject:observer]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) { + [self generateMethodMapping:observer]; + }); + [self sendCrashLogs]; + } } } + (void)removeObserver:(id)observer { - if ([_observers containsObject:observer]) { - [_observers removeObject:observer]; - if (_observers.count == 0) { - [FBSDKCrashHandler uninstallExceptionsHandler]; - uninstallSignalsHandler(); + @synchronized(_observers) { + if ([_observers containsObject:observer]) { + [_observers removeObject:observer]; + if (_observers.count == 0) { + [FBSDKCrashHandler uninstallExceptionsHandler]; + uninstallSignalsHandler(); + } } } } From 263fce7b95af6787a75af44fb1313a1bc107703d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 26 Oct 2020 12:13:32 -0700 Subject: [PATCH 050/227] Back out "Make Basics an actual dependency 3/n" Summary: Original commit changeset: 1b91798d4fc6 Reviewed By: dreamolight Differential Revision: D24542237 fbshipit-source-id: f0a16130f47e6365b26c53bf7d2abf51250fde9d --- Package.swift | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Package.swift b/Package.swift index d336dba03a..a1e75d07b3 100644 --- a/Package.swift +++ b/Package.swift @@ -28,10 +28,6 @@ let package = Package( .tvOS(.v10) ], products: [ - .library( - name: "FBSDKCoreKit_Basics", - targets: ["FBSDKCoreKit_Basics"] - ), .library( name: "FacebookCore", targets: ["FacebookCore"] @@ -52,8 +48,7 @@ let package = Package( dependencies: [], targets: [ .target( - name: "FBSDKCoreKit_Basics", - path: "Sources/FBSDKCoreKit_Basics" + name: "FBSDKCoreKit_Basics" ), .target( name: "FBSDKCoreKit", @@ -86,8 +81,7 @@ let package = Package( .headerSearchPath("Internal/Network"), .headerSearchPath("Internal/ServerConfiguration"), .headerSearchPath("Internal/TokenCaching"), - .headerSearchPath("Internal/UI"), - .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) + .headerSearchPath("Internal/UI") ], linkerSettings: [ .linkedFramework("Accelerate") @@ -96,10 +90,7 @@ let package = Package( .target( name: "FacebookCore", dependencies: ["FBSDKCoreKit"], - path: "FBSDKCoreKit/FBSDKCoreKit/Swift", - cSettings: [ - .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) - ] + path: "FBSDKCoreKit/FBSDKCoreKit/Swift" ), .target( name: "FBSDKLoginKit", From fd86ddce8aebf8fe16044d234d10c283bf39a0ee Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 26 Oct 2020 12:13:32 -0700 Subject: [PATCH 051/227] Back out "Make Basics an actual dependency 2/n" Summary: Original commit changeset: 32a9332a2d03 Reviewed By: dreamolight Differential Revision: D24542238 fbshipit-source-id: bb55b9eeb9fba7e73080fb2cdfa33d16594acb0c --- .../FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig | 28 -- .../FBSDKCoreKit_Basics-tvOS.xcconfig | 28 -- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 347 ++++++------------ .../Internal/FBSDKCoreKit+Internal.h | 7 +- .../project.pbxproj | 28 +- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 18 +- .../FBSDKShareKit.xcodeproj/project.pbxproj | 12 +- scripts/xcode/build-universal-framework.sh | 13 +- .../xcode/build-universal-tvos-framework.sh | 9 +- 9 files changed, 162 insertions(+), 328 deletions(-) delete mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig delete mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig deleted file mode 100644 index 58adbacc24..0000000000 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig +++ /dev/null @@ -1,28 +0,0 @@ -// 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. - -#include "Shared/Platform/tvOS.xcconfig" -#include "Shared/Target/DynamicFramework.xcconfig" -#include "Shared/Version.xcconfig" - -PRODUCT_NAME = FBSDKCoreKit_Basics -PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics - -CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) - -INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig deleted file mode 100644 index 97f7c38772..0000000000 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-tvOS.xcconfig +++ /dev/null @@ -1,28 +0,0 @@ -// 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. - -#include "Shared/Platform/tvOS.xcconfig" -#include "Shared/Target/StaticFramework.xcconfig" -#include "Shared/Version.xcconfig" - -PRODUCT_NAME = FBSDKCoreKit_Basics -PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics - -CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) - -INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index c31fb3bfdd..b65c34bde8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -744,8 +744,18 @@ C5696FA8209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; C5696FA9209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; C5696FAA209CCEB4009C931F /* FBSDKSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */; }; - C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D724E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044D824E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044D924E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; + C57044DA24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; C57044DB24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; C57044DC24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; C57044DD24E26678009637AD /* FBSDKUserDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = C57044CE24E26678009637AD /* FBSDKUserDataStore.m */; }; @@ -816,33 +826,6 @@ F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */; }; F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.m */; }; - F4583A7B252E62050051E280 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4583A7A252E62050051E280 /* UIKit.framework */; }; - F4583A7C252E620C0051E280 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F4583A78252E61DB0051E280 /* libz.tbd */; }; - F4583A83252E641F0051E280 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - F4583A87252E64E00051E280 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A88252E64E00051E280 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A89252E64E00051E280 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A8A252E64E00051E280 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A8B252E64E00051E280 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A8C252E64E00051E280 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A8D252E64E00051E280 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A8E252E64E00051E280 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A8F252E64E00051E280 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A90252E64E00051E280 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A91252E64E00051E280 /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A92252E65110051E280 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A93252E65110051E280 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A94252E65110051E280 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A95252E65110051E280 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A96252E65110051E280 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A97252E65110051E280 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A98252E65110051E280 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A99252E65110051E280 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A9A252E65120051E280 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A9B252E65120051E280 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583A9C252E65120051E280 /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4583AC3252E7D350051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */; }; - F4583AC9252E7F850051E280 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 81B71DA31D19C87400933E93 /* FBSDKCoreKit.framework */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -868,26 +851,50 @@ F468B2A124C2457000979F8D /* FBSDKRestrictiveData.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */; }; F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; F468B2A724C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; + F468B30A24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30B24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30C24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B30D24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B30E24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B30F24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B31024C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; F468B31124C25AB600979F8D /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */; }; + F468B31A24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31B24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31C24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B31D24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B31E24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B31F24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B32024C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; F468B32124C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E224C25AB500979F8D /* FBSDKURLSessionTask.m */; }; + F468B32224C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32424C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B32524C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32624C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32724C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32824C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; F468B32924C25AB600979F8D /* FBSDKCrashHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E324C25AB500979F8D /* FBSDKCrashHandler.m */; }; + F468B34224C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34424C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34524C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34624C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34724C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34824C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; F468B34924C25AB600979F8D /* FBSDKBasicUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */; }; + F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34B24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34C24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B34D24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B34E24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B34F24C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B35024C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; F468B35124C25AB600979F8D /* FBSDKURLSession.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E824C25AB600979F8D /* FBSDKURLSession.m */; }; + F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35324C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; + F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35624C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35724C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35824C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; @@ -938,30 +945,6 @@ F4BF22AA241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; - F4C39A4F2538E79A00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39A5C2538E79B00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5024E36E5200D4C010 /* FBSDKCoreKit_Basics.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39BC32538EE7C00A04DA3 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - F4C39BD32538EEEB00A04DA3 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F4C39BD22538EEE100A04DA3 /* libz.tbd */; }; - F4C39BF52538EF0000A04DA3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4C39BF42538EF0000A04DA3 /* UIKit.framework */; }; - F4C39C0D2538EFA000A04DA3 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */; }; - F4C39C3B2538FC4600A04DA3 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C5C2538FC4700A04DA3 /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4D24E36E5200D4C010 /* FBSDKBasicUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C7E2538FC6E00A04DA3 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C7F2538FC6E00A04DA3 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C802538FC6E00A04DA3 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C812538FC6E00A04DA3 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C822538FC6E00A04DA3 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C832538FC6E00A04DA3 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C842538FC6E00A04DA3 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C852538FC6E00A04DA3 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C912538FC7000A04DA3 /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B5124E36E5200D4C010 /* FBSDKCrashObserving.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C922538FC7000A04DA3 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C932538FC7000A04DA3 /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C942538FC7000A04DA3 /* FBSDKSafeCast.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C952538FC7000A04DA3 /* FBSDKURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4F24E36E5200D4C010 /* FBSDKURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C962538FC7000A04DA3 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4E24E36E5200D4C010 /* FBSDKJSONValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C972538FC7000A04DA3 /* FBSDKCrashHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4B24E36E5200D4C010 /* FBSDKCrashHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4C39C982538FC7000A04DA3 /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A11B4C24E36E5200D4C010 /* FBSDKLibAnalyzer.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4D8D8DC2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DD2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; @@ -978,14 +961,24 @@ F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */; }; F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */; }; F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */; }; + F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4F98C5624CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5724CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5824CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5924CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5A24CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; + F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998124D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998224D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998324D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998424D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998524D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998624D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; + F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; + F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */; }; @@ -1205,68 +1198,15 @@ remoteGlobalIDString = C5C4B3BE2276B67200CA3706; remoteInfo = FBSDKCoreKit_Basics_TV; }; - F4583A69252E5FBD0051E280 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; - proxyType = 1; - remoteGlobalIDString = C5C4B2E62276B51500CA3706; - remoteInfo = FBSDKCoreKit_Basics; - }; - F4583AC7252E7D8B0051E280 /* PBXContainerItemProxy */ = { + F410D0332370CBC2005B9318 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; proxyType = 1; remoteGlobalIDString = 81B71CFC1D19C87400933E93; remoteInfo = "FBSDKCoreKit-Dynamic"; }; - F4583ACC252E85080051E280 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; - proxyType = 1; - remoteGlobalIDString = C5C4B2E62276B51500CA3706; - remoteInfo = FBSDKCoreKit_Basics; - }; - F4C39BC42538EE7C00A04DA3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; - proxyType = 1; - remoteGlobalIDString = C5C4B3BE2276B67200CA3706; - remoteInfo = FBSDKCoreKit_Basics_TV; - }; - F4C39C192538FB6B00A04DA3 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D26973E1A5DF40700143BFC /* Project object */; - proxyType = 1; - remoteGlobalIDString = C5C4B4DC2276BA8D00CA3706; - remoteInfo = "FBSDKCoreKit_Basics_TV-Dynamic"; - }; /* End PBXContainerItemProxy section */ -/* Begin PBXCopyFilesBuildPhase section */ - F4583A86252E641F0051E280 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - F4583A83252E641F0051E280 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - F4C39BC62538EE7C00A04DA3 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - F4C39BC32538EE7C00A04DA3 /* FBSDKCoreKit_Basics.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ 033429B020894D4700C94913 /* FBSDKAccessTokenExpirer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessTokenExpirer.h; sourceTree = ""; }; 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessTokenExpirer.m; sourceTree = ""; }; @@ -1567,10 +1507,10 @@ C5696FA2209CCEB4009C931F /* FBSDKSwizzler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSwizzler.m; sourceTree = ""; }; C57044CD24E26678009637AD /* FBSDKUserDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKUserDataStore.h; sourceTree = ""; }; C57044CE24E26678009637AD /* FBSDKUserDataStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUserDataStore.m; sourceTree = ""; }; - C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit_Basics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKFeatureManager.h; sourceTree = ""; }; C5C7B74922D84F64004A5A0C /* FBSDKFeatureManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKFeatureManager.m; sourceTree = ""; }; C5D25D3421795B790037B13D /* FBSDKCodelessIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCodelessIndexer.h; sourceTree = ""; }; @@ -1601,10 +1541,6 @@ F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationManagerTests.m; sourceTree = ""; }; F43960CE2425513100C1868F /* FakeMonitorStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeMonitorStore.h; sourceTree = ""; }; F43960CF2425513100C1868F /* FakeMonitorStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeMonitorStore.m; sourceTree = ""; }; - F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKCoreKit_Basics-Dynamic.xcconfig"; sourceTree = ""; }; - F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FBSDKCoreKit_Basics.xcconfig; sourceTree = ""; }; - F4583A78252E61DB0051E280 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; - F4583A7A252E62050051E280 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.7.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKBasicUtility.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKBasicUtility.h; sourceTree = ""; }; F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCoreKit_Basics.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCoreKit_Basics.h; sourceTree = ""; }; F468B22024C2399800979F8D /* FBSDKCrashObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCrashObserving.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCrashObserving.h; sourceTree = ""; }; @@ -1671,10 +1607,6 @@ F4BF2292241954B400BFB494 /* FBSDKMonitorStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStoreTests.m; sourceTree = ""; }; F4BF22A1241954D800BFB494 /* FBSDKMonitorStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorStore.h; sourceTree = ""; }; F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStore.m; sourceTree = ""; }; - F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig"; sourceTree = ""; }; - F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "FBSDKCoreKit_Basics-tvOS.xcconfig"; sourceTree = ""; }; - F4C39BD22538EEE100A04DA3 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; }; - F4C39BF42538EF0000A04DA3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorNetworker.h; sourceTree = ""; }; F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworker.m; sourceTree = ""; }; F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworkerTests.m; sourceTree = ""; }; @@ -1743,7 +1675,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4C39C0D2538EFA000A04DA3 /* FBSDKCoreKit_Basics.framework in Frameworks */, F9FFE01F2252D66E007B2346 /* libz.tbd in Frameworks */, F9A18071252150610062E634 /* AdSupport.framework in Frameworks */, 4AF47D131F424A8700A57A67 /* CoreImage.framework in Frameworks */, @@ -1756,7 +1687,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4583AC3252E7D350051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */, F9A80C9E237D02860019D7E0 /* Accelerate.framework in Frameworks */, F9A180732521506C0062E634 /* AdSupport.framework in Frameworks */, C52C02ED2315039400F30E2A /* WebKit.framework in Frameworks */, @@ -1781,7 +1711,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4583AC9252E7F850051E280 /* FBSDKCoreKit.framework in Frameworks */, FDB2B4F32398D73D00AE087E /* Accelerate.framework in Frameworks */, 7E55576C1A8EAC7D00344F86 /* libOHHTTPStubs.a in Frameworks */, 9DAD87761A8AA75700FFA324 /* libOCMock.a in Frameworks */, @@ -1817,8 +1746,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4583A7C252E620C0051E280 /* libz.tbd in Frameworks */, - F4583A7B252E62050051E280 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1826,8 +1753,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4C39BD32538EEEB00A04DA3 /* libz.tbd in Frameworks */, - F4C39BF52538EF0000A04DA3 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2002,14 +1927,10 @@ 81A4A6011D19BE0400D5BF66 /* Configurations */ = { isa = PBXGroup; children = ( - F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */, - F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */, + 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */, + 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */, 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */, 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */, - F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */, - 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */, - F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */, - 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */, 814AC8CB1D1B5CAC00D61E6C /* FBSDKCoreKitTests.xcconfig */, 81A4A6041D19BE0400D5BF66 /* Shared */, ); @@ -2104,10 +2025,6 @@ 893F44A31A644536001DB0B6 /* Frameworks */ = { isa = PBXGroup; children = ( - F4C39BF42538EF0000A04DA3 /* UIKit.framework */, - F4C39BD22538EEE100A04DA3 /* libz.tbd */, - F4583A7A252E62050051E280 /* UIKit.framework */, - F4583A78252E61DB0051E280 /* libz.tbd */, F9A18062252150610062E634 /* AdSupport.framework */, F9A180722521506C0062E634 /* AdSupport.framework */, F9A80C9D237D02860019D7E0 /* Accelerate.framework */, @@ -2349,10 +2266,10 @@ 9DB0FA731BC1CA71005EB8B1 /* FBSDKCoreKit.framework */, 81B71DA31D19C87400933E93 /* FBSDKCoreKit.framework */, 814AC8571D1B528900D61E6C /* FBSDKCoreKit.framework */, - C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */, - C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */, - C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit_Basics.framework */, - C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */, + C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */, + C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */, + C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */, + C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */, ); name = Products; sourceTree = ""; @@ -2953,6 +2870,7 @@ 814AC8411D1B528900D61E6C /* FBSDKDynamicFrameworkLoader.h in Headers */, 814AC8421D1B528900D61E6C /* FBSDKServerConfiguration.h in Headers */, 814AC8431D1B528900D61E6C /* FBSDKGraphRequestPiggybackManager.h in Headers */, + C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */, 814AC8441D1B528900D61E6C /* FBSDKAppEventsUtility.h in Headers */, 5D90CDE92343D4D200AF326A /* FBSDKCrashShield.h in Headers */, 814AC8471D1B528900D61E6C /* FBSDKCopying.h in Headers */, @@ -3098,6 +3016,7 @@ 81B71D901D19C87400933E93 /* FBSDKSettings.h in Headers */, 81B71D911D19C87400933E93 /* FBSDKServerConfiguration.h in Headers */, F468B23524C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, + C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */, BFC02456237B6B9300A596EE /* FBSDKModelRuntime.hpp in Headers */, 81B71D921D19C87400933E93 /* FBSDKAppEventsStateManager.h in Headers */, 81B71D931D19C87400933E93 /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -3244,6 +3163,7 @@ F468B23424C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, FD9E154D23777AC900A005EC /* FBSDKModelRuntime.hpp in Headers */, 9D0BC1571A8D23E200BE8BA4 /* FBSDKAppEvents.h in Headers */, + C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */, 9DC658951A6EE5C500B85AAF /* FBSDKGraphRequest.h in Headers */, C5188DF9222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */, 894C0AF61A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */, @@ -3338,6 +3258,7 @@ 81C969331C114723002FC037 /* FBSDKDynamicFrameworkLoader.h in Headers */, 9D6DEED01BC23A71001A94ED /* FBSDKServerConfiguration.h in Headers */, 9DB0FAA81BC22D6A005EB8B1 /* FBSDKGraphRequestPiggybackManager.h in Headers */, + C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */, 9DB0FA8C1BC1CEEC005EB8B1 /* FBSDKAppEventsUtility.h in Headers */, 5D90CDE82343D4D200AF326A /* FBSDKCrashShield.h in Headers */, 9DB0FA821BC1CB93005EB8B1 /* FBSDKCopying.h in Headers */, @@ -3368,17 +3289,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4583A8F252E64E00051E280 /* FBSDKCoreKit_Basics.h in Headers */, - F4583A87252E64E00051E280 /* FBSDKTypeUtility.h in Headers */, - F4583A88252E64E00051E280 /* FBSDKURLSessionTask.h in Headers */, - F4583A89252E64E00051E280 /* FBSDKSafeCast.h in Headers */, - F4583A8A252E64E00051E280 /* FBSDKCrashHandler.h in Headers */, - F4583A8B252E64E00051E280 /* FBSDKLibAnalyzer.h in Headers */, - F4583A8C252E64E00051E280 /* FBSDKBasicUtility.h in Headers */, - F4583A8D252E64E00051E280 /* FBSDKJSONValue.h in Headers */, - F4583A8E252E64E00051E280 /* FBSDKURLSession.h in Headers */, - F4583A90252E64E00051E280 /* FBSDKCrashObserving.h in Headers */, - F4583A91252E64E00051E280 /* FBSDKUserDataStore.h in Headers */, + F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3387,17 +3299,7 @@ buildActionMask = 2147483647; files = ( F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, - F4C39C842538FC6E00A04DA3 /* FBSDKCrashHandler.h in Headers */, - F4C39C812538FC6E00A04DA3 /* FBSDKSafeCast.h in Headers */, - F4C39C3B2538FC4600A04DA3 /* FBSDKBasicUtility.h in Headers */, - F4C39C832538FC6E00A04DA3 /* FBSDKJSONValue.h in Headers */, C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */, - F4C39C822538FC6E00A04DA3 /* FBSDKURLSession.h in Headers */, - F4C39C7F2538FC6E00A04DA3 /* FBSDKURLSessionTask.h in Headers */, - F4C39A4F2538E79A00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */, - F4C39C7E2538FC6E00A04DA3 /* FBSDKCrashObserving.h in Headers */, - F4C39C802538FC6E00A04DA3 /* FBSDKTypeUtility.h in Headers */, - F4C39C852538FC6E00A04DA3 /* FBSDKLibAnalyzer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3405,17 +3307,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4583A9A252E65120051E280 /* FBSDKCoreKit_Basics.h in Headers */, - F4583A92252E65110051E280 /* FBSDKTypeUtility.h in Headers */, - F4583A93252E65110051E280 /* FBSDKURLSessionTask.h in Headers */, - F4583A94252E65110051E280 /* FBSDKSafeCast.h in Headers */, - F4583A95252E65110051E280 /* FBSDKCrashHandler.h in Headers */, - F4583A96252E65110051E280 /* FBSDKLibAnalyzer.h in Headers */, - F4583A97252E65110051E280 /* FBSDKBasicUtility.h in Headers */, - F4583A98252E65110051E280 /* FBSDKJSONValue.h in Headers */, - F4583A99252E65110051E280 /* FBSDKURLSession.h in Headers */, - F4583A9B252E65120051E280 /* FBSDKCrashObserving.h in Headers */, - F4583A9C252E65120051E280 /* FBSDKUserDataStore.h in Headers */, + F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3424,17 +3317,7 @@ buildActionMask = 2147483647; files = ( F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, - F4C39C972538FC7000A04DA3 /* FBSDKCrashHandler.h in Headers */, - F4C39C942538FC7000A04DA3 /* FBSDKSafeCast.h in Headers */, - F4C39C5C2538FC4700A04DA3 /* FBSDKBasicUtility.h in Headers */, - F4C39C962538FC7000A04DA3 /* FBSDKJSONValue.h in Headers */, C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */, - F4C39C952538FC7000A04DA3 /* FBSDKURLSession.h in Headers */, - F4C39C922538FC7000A04DA3 /* FBSDKURLSessionTask.h in Headers */, - F4C39A5C2538E79B00A04DA3 /* FBSDKCoreKit_Basics.h in Headers */, - F4C39C912538FC7000A04DA3 /* FBSDKCrashObserving.h in Headers */, - F4C39C932538FC7000A04DA3 /* FBSDKTypeUtility.h in Headers */, - F4C39C982538FC7000A04DA3 /* FBSDKLibAnalyzer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3449,12 +3332,10 @@ 814AC8141D1B528900D61E6C /* Frameworks */, 814AC8161D1B528900D61E6C /* Headers */, 814AC8531D1B528900D61E6C /* Resources */, - F4C39BC62538EE7C00A04DA3 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( - F4C39BC52538EE7C00A04DA3 /* PBXTargetDependency */, ); name = "FBSDKCoreKit_TV-Dynamic"; productName = "FBSDKCoreKit (TV)"; @@ -3469,12 +3350,10 @@ 81B71D451D19C87400933E93 /* Frameworks */, 81B71D471D19C87400933E93 /* Headers */, 81B71D9F1D19C87400933E93 /* Resources */, - F4583A86252E641F0051E280 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( - F4583ACD252E85080051E280 /* PBXTargetDependency */, ); name = "FBSDKCoreKit-Dynamic"; productName = FBSDKCoreKit; @@ -3494,7 +3373,6 @@ buildRules = ( ); dependencies = ( - F4583A6A252E5FBD0051E280 /* PBXTargetDependency */, ); name = FBSDKCoreKit; productName = FBSDKCoreKit; @@ -3512,7 +3390,7 @@ buildRules = ( ); dependencies = ( - F4583AC8252E7D8B0051E280 /* PBXTargetDependency */, + F410D0342370CBC2005B9318 /* PBXTargetDependency */, 9DAD79FB1B7B27DE00DFEF8F /* PBXTargetDependency */, ); name = FBSDKCoreKitTests; @@ -3532,7 +3410,6 @@ buildRules = ( ); dependencies = ( - F4C39C1A2538FB6B00A04DA3 /* PBXTargetDependency */, ); name = FBSDKCoreKit_TV; productName = "FBSDKCoreKit (TV)"; @@ -3554,7 +3431,7 @@ ); name = FBSDKCoreKit_Basics; productName = FBSDKCoreKit; - productReference = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit_Basics.framework */; + productReference = C5C4B3B62276B51500CA3706 /* FBSDKCoreKit.framework */; productType = "com.apple.product-type.framework"; }; C5C4B3BE2276B67200CA3706 /* FBSDKCoreKit_Basics_TV */ = { @@ -3572,7 +3449,7 @@ ); name = FBSDKCoreKit_Basics_TV; productName = FBSDKCoreKit; - productReference = C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit_Basics.framework */; + productReference = C5C4B3CC2276B67200CA3706 /* FBSDKCoreKit.framework */; productType = "com.apple.product-type.framework"; }; C5C4B4012276BA1200CA3706 /* FBSDKCoreKit_Basics-Dynamic */ = { @@ -3590,7 +3467,7 @@ ); name = "FBSDKCoreKit_Basics-Dynamic"; productName = FBSDKCoreKit; - productReference = C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit_Basics.framework */; + productReference = C5C4B4D42276BA1200CA3706 /* FBSDKCoreKit.framework */; productType = "com.apple.product-type.framework"; }; C5C4B4DC2276BA8D00CA3706 /* FBSDKCoreKit_Basics_TV-Dynamic */ = { @@ -3608,7 +3485,7 @@ ); name = "FBSDKCoreKit_Basics_TV-Dynamic"; productName = FBSDKCoreKit; - productReference = C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit_Basics.framework */; + productReference = C5C4B4EA2276BA8D00CA3706 /* FBSDKCoreKit.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -3934,16 +3811,19 @@ 814AC7E41D1B528900D61E6C /* FBSDKAppEventsUtility.m in Sources */, 814AC7E51D1B528900D61E6C /* FBSDKServerConfigurationManager.m in Sources */, 814AC7E61D1B528900D61E6C /* FBSDKAccessTokenCache.m in Sources */, + F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E323219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 814AC7E71D1B528900D61E6C /* FBSDKUtility.m in Sources */, 814AC7E81D1B528900D61E6C /* FBSDKBase64.m in Sources */, F420D1912433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, + F468B34524C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 814AC7E91D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 814AC7EA1D1B528900D61E6C /* FBSDKGraphRequestMetadata.m in Sources */, 814AC7EB1D1B528900D61E6C /* FBSDKServerConfiguration.m in Sources */, 814AC7EC1D1B528900D61E6C /* FBSDKDynamicFrameworkLoader.m in Sources */, F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 814AC7ED1D1B528900D61E6C /* FBSDKDialogConfiguration.m in Sources */, + F468B30D24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 814AC7EE1D1B528900D61E6C /* FBSDKKeychainStoreViaBundleID.m in Sources */, FD147F672387215A000B216E /* FBSDKRestrictiveDataFilterManager.m in Sources */, 814AC7EF1D1B528900D61E6C /* FBSDKInternalUtility.m in Sources */, @@ -3952,6 +3832,7 @@ 814AC7F11D1B528900D61E6C /* FBSDKDeviceViewControllerBase.m in Sources */, F4A52B17242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */, 814AC7F21D1B528900D61E6C /* FBSDKAppEventsState.m in Sources */, + F4FE998224D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 814AC7F31D1B528900D61E6C /* FBSDKPaymentObserver.m in Sources */, F9FD9A8021659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, @@ -3970,21 +3851,26 @@ F42004982416C30300AD7006 /* FBSDKMonitor.m in Sources */, 814AC7FC1D1B528900D61E6C /* FBSDKAccessToken.m in Sources */, 814AC7FD1D1B528900D61E6C /* FBSDKGraphRequestBody.m in Sources */, + F468B34D24C25AB600979F8D /* FBSDKURLSession.m in Sources */, C5C7B75122D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, 814AC7FE1D1B528900D61E6C /* FBSDKErrorConfiguration.m in Sources */, F9A06DD62510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, C554DB1A2304D11A00A32E8B /* FBSDKErrorReport.m in Sources */, 814AC7FF1D1B528900D61E6C /* FBSDKViewImpressionTracker.m in Sources */, 814AC8001D1B528900D61E6C /* FBSDKSettings.m in Sources */, + F468B31D24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 814AC8021D1B528900D61E6C /* FBSDKAppEvents.m in Sources */, 814AC8031D1B528900D61E6C /* FBSDKTestUsersManager.m in Sources */, C5696FAA209CCEB4009C931F /* FBSDKSwizzler.m in Sources */, 814AC8041D1B528900D61E6C /* FBSDKGraphRequest.m in Sources */, 52D4F0D21D91A18F0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 814AC8051D1B528900D61E6C /* FBSDKLogo.m in Sources */, + F4F98C5624CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, + C57044DA24E26678009637AD /* FBSDKUserDataStore.m in Sources */, 814AC8061D1B528900D61E6C /* FBSDKDeviceButton.m in Sources */, 814AC8071D1B528900D61E6C /* FBSDKGraphRequestConnection.m in Sources */, F9A06DCA2510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, + F468B32524C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 814AC8081D1B528900D61E6C /* FBSDKErrorRecoveryConfiguration.m in Sources */, 814AC8091D1B528900D61E6C /* FBSDKApplicationDelegate.m in Sources */, 814AC80B1D1B528900D61E6C /* FBSDKDeviceDialogView.m in Sources */, @@ -4013,12 +3899,14 @@ 81B71D051D19C87400933E93 /* FBSDKContainerViewController.m in Sources */, 81B71D061D19C87400933E93 /* FBSDKAccessTokenCache.m in Sources */, 81B71D071D19C87400933E93 /* FBSDKCrypto.m in Sources */, + F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 81B71D081D19C87400933E93 /* FBSDKAppEventsState.m in Sources */, 52963A87215992F400C7B252 /* FBSDKWebViewAppLinkResolver.m in Sources */, 81B71D091D19C87400933E93 /* FBSDKCloseIcon.m in Sources */, F4BF22AA241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 5D41131B229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m in Sources */, 81B71D0A1D19C87400933E93 /* FBSDKBase64.m in Sources */, + F468B34B24C25AB600979F8D /* FBSDKURLSession.m in Sources */, 81B71D0B1D19C87400933E93 /* FBSDKBridgeAPIProtocolWebV2.m in Sources */, 81B71D0C1D19C87400933E93 /* FBSDKGraphRequestBody.m in Sources */, F943110524F8D615002441F1 /* FBSDKSKAdNetworkRule.m in Sources */, @@ -4051,9 +3939,11 @@ 81B71D1D1D19C87400933E93 /* FBSDKBridgeAPIRequest.m in Sources */, 81B71D1E1D19C87400933E93 /* FBSDKAppEventsDeviceInfo.m in Sources */, F42004962416C30300AD7006 /* FBSDKMonitor.m in Sources */, + F468B31B24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 81B71D1F1D19C87400933E93 /* FBSDKError.m in Sources */, 81B71D231D19C87400933E93 /* FBSDKAudioResourceLoader.m in Sources */, 81B71D241D19C87400933E93 /* FBSDKLogo.m in Sources */, + F468B35324C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, F4210E35241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 81B71D251D19C87400933E93 /* FBSDKPaymentObserver.m in Sources */, 81B71D261D19C87400933E93 /* FBSDKBridgeAPIResponse.m in Sources */, @@ -4068,6 +3958,7 @@ C5696F60209BBC35009C931F /* FBSDKEventBinding.m in Sources */, 0384CEBB208E60660013D404 /* FBSDKAccessTokenExpirer.m in Sources */, 81B71D2F1D19C87400933E93 /* FBSDKColor.m in Sources */, + F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 81B71D301D19C87400933E93 /* FBSDKAppLinkResolver.m in Sources */, F420D18F2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 81B71D311D19C87400933E93 /* FBSDKIcon.m in Sources */, @@ -4077,10 +3968,12 @@ 81B71D321D19C87400933E93 /* FBSDKConstants.m in Sources */, 81B71D331D19C87400933E93 /* FBSDKAppEventsUtility.m in Sources */, 5DB7B08F2303632E0012E8CB /* FBSDKInstrumentManager.m in Sources */, + F468B30B24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, C5696F48209BBC35009C931F /* FBSDKCodelessPathComponent.m in Sources */, F46FA64024533F690060C902 /* Settings.swift in Sources */, 81B71D341D19C87400933E93 /* FBSDKSettings.m in Sources */, 52963A85215992F400C7B252 /* FBSDKAppLink.m in Sources */, + C57044D824E26678009637AD /* FBSDKUserDataStore.m in Sources */, F943113224FB25A7002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */, BFC02459237B6B9C00A596EE /* FBSDKFeatureExtractor.m in Sources */, 52963A77215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */, @@ -4097,6 +3990,7 @@ F4D8D8E32422887600C28384 /* FBSDKMonitorNetworker.m in Sources */, 5D6DF1642398E28000AC2D6C /* FBSDKEventDeactivationManager.m in Sources */, 5D4360E123219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, + F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, F9FD9A7E21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, 81B71D3D1D19C87400933E93 /* FBSDKAppEvents.m in Sources */, FDAF4A912395D27D00711C4C /* FBSDKModelUtility.m in Sources */, @@ -4108,6 +4002,7 @@ 81B71D401D19C87400933E93 /* FBSDKWebDialogView.m in Sources */, 81B71D411D19C87400933E93 /* FBSDKErrorConfiguration.m in Sources */, C4FC99F2202CD56D0038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, + F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 52D4F0BC1D91A18D0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 81B71D431D19C87400933E93 /* FBSDKServerConfiguration.m in Sources */, @@ -4133,8 +4028,10 @@ 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */, C4FC99DA202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, 9D32A8461A699459000A936D /* FBSDKAccessTokenCache.m in Sources */, + F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 894C0B0A1A702194009137EF /* FBSDKCrypto.m in Sources */, 9D0BC1671A8E892C00BE8BA4 /* FBSDKAppEventsState.m in Sources */, + F468B31A24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 89D652851A855A6000BB651C /* FBSDKCloseIcon.m in Sources */, F4BF22A9241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 52963A86215992F400C7B252 /* FBSDKWebViewAppLinkResolver.m in Sources */, @@ -4162,6 +4059,7 @@ 52963A82215992F400C7B252 /* FBSDKURL.m in Sources */, 893F448C1A642F11001DB0B6 /* FBSDKInternalUtility.m in Sources */, ADEA17741B7ECA1A0070EDC0 /* FBSDKMonotonicTime.m in Sources */, + F468B32224C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, F46FA63D24533F610060C902 /* Permission.swift in Sources */, 7E30917A1AA907E0004E91D5 /* FBSDKAppLinkUtility.m in Sources */, 89688B631AA64C5E00A98519 /* FBSDKViewImpressionTracker.m in Sources */, @@ -4175,6 +4073,7 @@ F9DE56BB24F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */, F4210E34241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, 89D05AAA1AA1134000609300 /* FBSDKAudioResourceLoader.m in Sources */, + F468B30A24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 893F449A1A6444DF001DB0B6 /* FBSDKLogo.m in Sources */, 9D0BC1501A8D236200BE8BA4 /* FBSDKPaymentObserver.m in Sources */, 894C0AE01A6F1D1B009137EF /* FBSDKBridgeAPIResponse.m in Sources */, @@ -4191,8 +4090,10 @@ F420D18E2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 9DBA6A311A80265A00B4DE6A /* FBSDKColor.m in Sources */, E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */, + F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 7E5557371A8D833100344F86 /* FBSDKAppLinkResolver.m in Sources */, F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, + F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */, 891687D31AB33CA200F55364 /* FBSDKIcon.m in Sources */, 5D90CDDF2343D4BD00AF326A /* FBSDKCrashShield.m in Sources */, BFC02448237B6A9A00A596EE /* FBSDKFeatureExtractor.m in Sources */, @@ -4201,9 +4102,11 @@ 5DB7B08E2303632E0012E8CB /* FBSDKInstrumentManager.m in Sources */, F46FA63F24533F690060C902 /* Settings.swift in Sources */, C5696F47209BBC35009C931F /* FBSDKCodelessPathComponent.m in Sources */, + C57044D724E26678009637AD /* FBSDKUserDataStore.m in Sources */, F943112224FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */, 9DA8303D1A6999EC00770955 /* FBSDKSettings.m in Sources */, 52963A84215992F400C7B252 /* FBSDKAppLink.m in Sources */, + F468B34224C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 52963A76215992F400C7B252 /* FBSDKAppLinkReturnToRefererView.m in Sources */, 891687EF1AB38C7C00F55364 /* FBSDKButton.m in Sources */, C5D25D3821795B790037B13D /* FBSDKCodelessIndexer.m in Sources */, @@ -4231,6 +4134,7 @@ 520223F81D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m in Sources */, 9DE1F3CE1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 89830F301A7805E100226ABB /* FBSDKServerConfiguration.m in Sources */, + F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */, FD8E438122FBF8F1008B6DD3 /* FBSDKErrorReport.m in Sources */, 899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */, @@ -4331,16 +4235,19 @@ 9DB0FA8D1BC1CEF4005EB8B1 /* FBSDKAppEventsUtility.m in Sources */, 9D6DEEC91BC23A30001A94ED /* FBSDKServerConfigurationManager.m in Sources */, 9D6DEEB31BC23850001A94ED /* FBSDKAccessTokenCache.m in Sources */, + F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E223219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 9DB0FA971BC22BC0005EB8B1 /* FBSDKUtility.m in Sources */, 9DE155411C161A66005FCF5C /* FBSDKBase64.m in Sources */, F420D1902433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, + F468B34424C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, 9D6DEED21BC23ADD001A94ED /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 9DB0FAA71BC22D5B005EB8B1 /* FBSDKGraphRequestMetadata.m in Sources */, 9D6DEECF1BC23A6E001A94ED /* FBSDKServerConfiguration.m in Sources */, 81C969351C114723002FC037 /* FBSDKDynamicFrameworkLoader.m in Sources */, F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */, 9D6DEECB1BC23A43001A94ED /* FBSDKDialogConfiguration.m in Sources */, + F468B30C24C25AB600979F8D /* FBSDKTypeUtility.m in Sources */, 9D6DEECD1BC23A53001A94ED /* FBSDKKeychainStoreViaBundleID.m in Sources */, FD147F662387215A000B216E /* FBSDKRestrictiveDataFilterManager.m in Sources */, 9DB0FA931BC22B49005EB8B1 /* FBSDKInternalUtility.m in Sources */, @@ -4349,6 +4256,7 @@ 9D10A6901CB38DF100F42AC1 /* FBSDKDeviceViewControllerBase.m in Sources */, F4A52B16242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */, 9D6DEEB11BC23834001A94ED /* FBSDKAppEventsState.m in Sources */, + F4FE998124D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 9D6DEEBD1BC238F5001A94ED /* FBSDKPaymentObserver.m in Sources */, F9FD9A7F21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, F4210E36241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */, @@ -4367,12 +4275,14 @@ F42004972416C30300AD7006 /* FBSDKMonitor.m in Sources */, 9D6DEEAA1BC236B9001A94ED /* FBSDKAccessToken.m in Sources */, 9DB0FAA11BC22CF9005EB8B1 /* FBSDKGraphRequestBody.m in Sources */, + F468B34C24C25AB600979F8D /* FBSDKURLSession.m in Sources */, C5C7B75022D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, 9DB0FA9B1BC22BED005EB8B1 /* FBSDKErrorConfiguration.m in Sources */, F9A06DD52510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.m in Sources */, C554DB192304D11900A32E8B /* FBSDKErrorReport.m in Sources */, 9D6538411BF44FB4008A08E9 /* FBSDKViewImpressionTracker.m in Sources */, 9DB0FA951BC22B79005EB8B1 /* FBSDKSettings.m in Sources */, + F468B31C24C25AB600979F8D /* FBSDKURLSessionTask.m in Sources */, 9D6DEEA91BC2368D001A94ED /* FBSDKAppEvents.m in Sources */, 9D6DEEE81BC2429B001A94ED /* FBSDKTestUsersManager.m in Sources */, C5696FA9209CCEB4009C931F /* FBSDKSwizzler.m in Sources */, @@ -4380,7 +4290,9 @@ 52D4F0D11D91A18F0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 9DDC112A1BEC413900A88306 /* FBSDKLogo.m in Sources */, 9D9E16AF1CB46C8E00C8B68F /* FBSDKDeviceButton.m in Sources */, + C57044D924E26678009637AD /* FBSDKUserDataStore.m in Sources */, 9DB0FA891BC1CDD0005EB8B1 /* FBSDKGraphRequestConnection.m in Sources */, + F468B32424C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, F9A06DC92510FAF0007E6386 /* FBSDKAppEventsConfiguration.m in Sources */, 9D6DEEBA1BC238A2001A94ED /* FBSDKErrorRecoveryConfiguration.m in Sources */, 9DC1DD781BC4629F000D5AD5 /* FBSDKApplicationDelegate.m in Sources */, @@ -4389,6 +4301,7 @@ 5DB7B0902303632F0012E8CB /* FBSDKInstrumentManager.m in Sources */, F40F6569241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */, 9D28F1991DB14DBB0057D709 /* FBSDKImageDownloader.m in Sources */, + F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 9DB0FAA51BC22D1C005EB8B1 /* FBSDKLogger.m in Sources */, 9D6DEEB01BC2379C001A94ED /* FBSDKTimeSpentData.m in Sources */, 9DB0FAA91BC22D6F005EB8B1 /* FBSDKGraphRequestPiggybackManager.m in Sources */, @@ -4488,30 +4401,10 @@ target = C5C4B3BE2276B67200CA3706 /* FBSDKCoreKit_Basics_TV */; targetProxy = C5FCE33C228E093100867DFD /* PBXContainerItemProxy */; }; - F4583A6A252E5FBD0051E280 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C5C4B2E62276B51500CA3706 /* FBSDKCoreKit_Basics */; - targetProxy = F4583A69252E5FBD0051E280 /* PBXContainerItemProxy */; - }; - F4583AC8252E7D8B0051E280 /* PBXTargetDependency */ = { + F410D0342370CBC2005B9318 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 81B71CFC1D19C87400933E93 /* FBSDKCoreKit-Dynamic */; - targetProxy = F4583AC7252E7D8B0051E280 /* PBXContainerItemProxy */; - }; - F4583ACD252E85080051E280 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C5C4B2E62276B51500CA3706 /* FBSDKCoreKit_Basics */; - targetProxy = F4583ACC252E85080051E280 /* PBXContainerItemProxy */; - }; - F4C39BC52538EE7C00A04DA3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C5C4B3BE2276B67200CA3706 /* FBSDKCoreKit_Basics_TV */; - targetProxy = F4C39BC42538EE7C00A04DA3 /* PBXContainerItemProxy */; - }; - F4C39C1A2538FB6B00A04DA3 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C5C4B4DC2276BA8D00CA3706 /* FBSDKCoreKit_Basics_TV-Dynamic */; - targetProxy = F4C39C192538FB6B00A04DA3 /* PBXContainerItemProxy */; + targetProxy = F410D0332370CBC2005B9318 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -4657,84 +4550,84 @@ }; C5C4B3B42276B51500CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; + baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B3B52276B51500CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; + baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { }; name = Release; }; C5C4B3CA2276B67200CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; + baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B3CB2276B67200CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; + baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { }; name = Release; }; C5C4B4D22276BA1200CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */; + baseConfigurationReference = 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B4D32276BA1200CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4583A59252E5F220051E280 /* FBSDKCoreKit_Basics-Dynamic.xcconfig */; + baseConfigurationReference = 81A4A6021D19BE0400D5BF66 /* FBSDKCoreKit-Dynamic.xcconfig */; buildSettings = { }; name = Release; }; C5C4B4E82276BA8D00CA3706 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */; + baseConfigurationReference = 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */; buildSettings = { }; name = Debug; }; C5C4B4E92276BA8D00CA3706 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4C39AF82538EA2C00A04DA3 /* FBSDKCoreKit_Basics-tvOS-Dynamic.xcconfig */; + baseConfigurationReference = 814AC8751D1B52DC00D61E6C /* FBSDKCoreKit-tvOS-Dynamic.xcconfig */; buildSettings = { }; name = Release; }; C5FCE322228E08CA00867DFD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; + baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { }; name = Debug; }; C5FCE323228E08CA00867DFD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4583A68252E5F220051E280 /* FBSDKCoreKit_Basics.xcconfig */; + baseConfigurationReference = 81A4A6031D19BE0400D5BF66 /* FBSDKCoreKit.xcconfig */; buildSettings = { }; name = Release; }; C5FCE337228E08D400867DFD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; + baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { }; name = Debug; }; C5FCE338228E08D400867DFD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F4C39AF92538EA3600A04DA3 /* FBSDKCoreKit_Basics-tvOS.xcconfig */; + baseConfigurationReference = 814AC8971D1B5A0600D61E6C /* FBSDKCoreKit-tvOS.xcconfig */; buildSettings = { }; name = Release; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index c0ac57830e..e036237088 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -24,9 +24,9 @@ #import #endif -#if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE - #import "FBSDKCoreKit_Basics.h" -#else +#if defined FBSDKCOCOAPODS + #import +#elif defined BUCK #import #endif @@ -129,6 +129,7 @@ #import "Device/FBSDKSmartDeviceDialogView.h" #endif + #import "../../../Sources/FBSDKCoreKit_Basics/include/FBSDKCoreKit_Basics.h" #import "../AppEvents/Internal/FBSDKAppEvents+Internal.h" #import "../AppEvents/Internal/FBSDKAppEventsConfiguration.h" #import "../AppEvents/Internal/FBSDKAppEventsConfigurationManager.h" diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj index c0fdaccffa..52b8cf25dd 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj @@ -39,7 +39,6 @@ 9FC20034247D8D170016A053 /* FBSDKShareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FC2001D247D83400016A053 /* FBSDKShareKit.framework */; }; F4234613244A2D2D006C9836 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5123F49C110030A346 /* FBSDKCoreKit.framework */; }; F4234614244A2D2D006C9836 /* FBSDKCoreKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5123F49C110030A346 /* FBSDKCoreKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - F4583ABD252E6E760051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA5B23F49C110030A346 /* FBSDKCoreKit_Basics.framework */; }; F46A224524D9F14D005878A8 /* FBSDKGamingServicesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4F7CA1823F4902B0030A346 /* FBSDKGamingServicesKit.framework */; }; F46A225024D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F46A224B24D9F184005878A8 /* FBSDKGamingServicesKitTestUtility.m */; }; F4DC057F2519499A0073B380 /* FBSDKCoreKitInternalImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4DC056E2519498C0073B380 /* FBSDKCoreKitInternalImport.h */; }; @@ -335,7 +334,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4583ABD252E6E760051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */, 9FC20034247D8D170016A053 /* FBSDKShareKit.framework in Frameworks */, F4F7CAA323F4A1470030A346 /* UIKit.framework in Frameworks */, F4234613244A2D2D006C9836 /* FBSDKCoreKit.framework in Frameworks */, @@ -506,10 +504,10 @@ F4F7CA5523F49C110030A346 /* FBSDKCoreKitTests.xctest */, F4F7CA5723F49C110030A346 /* FBSDKCoreKit.framework */, F4F7CA5923F49C110030A346 /* FBSDKCoreKit.framework */, - F4F7CA5B23F49C110030A346 /* FBSDKCoreKit_Basics.framework */, - F4F7CA5D23F49C110030A346 /* FBSDKCoreKit_Basics.framework */, - F4F7CA5F23F49C110030A346 /* FBSDKCoreKit_Basics.framework */, - F4F7CA6123F49C110030A346 /* FBSDKCoreKit_Basics.framework */, + F4F7CA5B23F49C110030A346 /* FBSDKCoreKit.framework */, + F4F7CA5D23F49C110030A346 /* FBSDKCoreKit.framework */, + F4F7CA5F23F49C110030A346 /* FBSDKCoreKit.framework */, + F4F7CA6123F49C110030A346 /* FBSDKCoreKit.framework */, ); name = Products; sourceTree = ""; @@ -743,31 +741,31 @@ remoteRef = F4F7CA5823F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA5B23F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { + F4F7CA5B23F49C110030A346 /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = F4F7CA5A23F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA5D23F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { + F4F7CA5D23F49C110030A346 /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = F4F7CA5C23F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA5F23F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { + F4F7CA5F23F49C110030A346 /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = F4F7CA5E23F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA6123F49C110030A346 /* FBSDKCoreKit_Basics.framework */ = { + F4F7CA6123F49C110030A346 /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = F4F7CA6023F49C110030A346 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1115,6 +1113,7 @@ baseConfigurationReference = F4F7C9DF23F48F2C0030A346 /* FBSDKGamingServicesKit.xcconfig */; buildSettings = { CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; @@ -1123,6 +1122,7 @@ baseConfigurationReference = F4F7C9DF23F48F2C0030A346 /* FBSDKGamingServicesKit.xcconfig */; buildSettings = { CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index d9b83670e9..bc06cd2244 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -106,6 +106,7 @@ 818EB43C1D1A283100252851 /* FBSDKLoginManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D03E81F1A72D7E700207493 /* FBSDKLoginManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8199F1061D1A2B30007AA5AD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774A91A3B80FD00BE2807 /* CoreGraphics.framework */; }; 8199F1081D1A2B34007AA5AD /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774AB1A3B810100BE2807 /* UIKit.framework */; }; + 81A07EAB1D1A2B560041A29C /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B6811D0A5B9400962084 /* FBSDKCoreKit.framework */; }; 893774AA1A3B80FD00BE2807 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774A91A3B80FD00BE2807 /* CoreGraphics.framework */; }; 893774AC1A3B810100BE2807 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774AB1A3B810100BE2807 /* UIKit.framework */; }; 9D03E8211A72D7E700207493 /* FBSDKLoginManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D03E81F1A72D7E700207493 /* FBSDKLoginManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -147,8 +148,6 @@ C6CE2BC424EB73CF00CF2EB6 /* FBSDKReferralManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C6CE2BBE24EB72F200CF2EB6 /* FBSDKReferralManager.m */; }; C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */; }; C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */; }; - F4583AA0252E6C220051E280 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B6811D0A5B9400962084 /* FBSDKCoreKit.framework */; }; - F4583AA7252E6DC70051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E309CAC228F2581007B532E /* FBSDKCoreKit_Basics.framework */; }; F462DC0E23B958E000FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC0F23B958E100FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC1023B95BA600FFCECA /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */; }; @@ -406,9 +405,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F4583AA7252E6DC70051E280 /* FBSDKCoreKit_Basics.framework in Frameworks */, + 81A07EAB1D1A2B560041A29C /* FBSDKCoreKit.framework in Frameworks */, 8199F1081D1A2B34007AA5AD /* UIKit.framework in Frameworks */, - F4583AA0252E6C220051E280 /* FBSDKCoreKit.framework in Frameworks */, 8199F1061D1A2B30007AA5AD /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -445,8 +443,8 @@ 8118B6831D0A5B9400962084 /* FBSDKCoreKitTests.xctest */, 8118B6851D0A5B9400962084 /* FBSDKCoreKit.framework */, 812E0D1B1D23840500291B71 /* FBSDKCoreKit.framework */, - 5E309CAC228F2581007B532E /* FBSDKCoreKit_Basics.framework */, - 5E309CAE228F2581007B532E /* FBSDKCoreKit_Basics.framework */, + 5E309CAC228F2581007B532E /* FBSDKCoreKit.framework */, + 5E309CAE228F2581007B532E /* FBSDKCoreKit.framework */, 5E309CB0228F2581007B532E /* FBSDKCoreKit.framework */, 5E309CB2228F2581007B532E /* FBSDKCoreKit.framework */, ); @@ -906,17 +904,17 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 5E309CAC228F2581007B532E /* FBSDKCoreKit_Basics.framework */ = { + 5E309CAC228F2581007B532E /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = 5E309CAB228F2581007B532E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E309CAE228F2581007B532E /* FBSDKCoreKit_Basics.framework */ = { + 5E309CAE228F2581007B532E /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = 5E309CAD228F2581007B532E /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index 4ad7210826..657b74ba25 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -612,8 +612,8 @@ 8118B63F1D0A49B500962084 /* FBSDKCoreKitTests.xctest */, 8118B6411D0A49B500962084 /* FBSDKCoreKit.framework */, 819043EF1D261A7900B2E437 /* FBSDKCoreKit.framework */, - C57538C52292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */, - C57538C72292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */, + C57538C52292B6D5007C2EFF /* FBSDKCoreKit.framework */, + C57538C72292B6D5007C2EFF /* FBSDKCoreKit.framework */, C57538C92292B6D5007C2EFF /* FBSDKCoreKit.framework */, C57538CB2292B6D5007C2EFF /* FBSDKCoreKit.framework */, ); @@ -1262,17 +1262,17 @@ remoteRef = 819043EE1D261A7900B2E437 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - C57538C52292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */ = { + C57538C52292B6D5007C2EFF /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = C57538C42292B6D5007C2EFF /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - C57538C72292B6D5007C2EFF /* FBSDKCoreKit_Basics.framework */ = { + C57538C72292B6D5007C2EFF /* FBSDKCoreKit.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = FBSDKCoreKit_Basics.framework; + path = FBSDKCoreKit.framework; remoteRef = C57538C62292B6D5007C2EFF /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/scripts/xcode/build-universal-framework.sh b/scripts/xcode/build-universal-framework.sh index d54249cb27..c3c774ef3c 100755 --- a/scripts/xcode/build-universal-framework.sh +++ b/scripts/xcode/build-universal-framework.sh @@ -30,7 +30,6 @@ UNIVERSAL_BUILD_FOLDER=../build/ # make the output directory and delete the framework directory mkdir -p "${UNIVERSAL_BUILD_FOLDER}" rm -rf "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework" -rm -rf "${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}.framework" # get target by removing '-Universal' from $TARGET_NAME TARGET=${TARGET_NAME%-Universal} @@ -53,19 +52,19 @@ xcodebuild -target "${TARGET}" \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES # Step 2. Copy the framework structure to the universal folder -cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}.framework" "${UNIVERSAL_BUILD_FOLDER}/" +cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_BUILD_FOLDER}/" # Step 3. Copy the swiftmodule files created during the simulator build -rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}.framework/Modules/${PRODUCT_NAME}.swiftmodule/" \ - "${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}.framework/Modules/${PRODUCT_NAME}.swiftmodule" || true +rsync -a "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/" \ + "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule" || true # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory -lipo -create -output "${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" +lipo -create -output "${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" # Step 5. Copy strings bundle if exists -STRINGS_INPUT_FOLDER="${PRODUCT_NAME}Strings.bundle" +STRINGS_INPUT_FOLDER="${PROJECT_NAME}Strings.bundle" if [ -d "${STRINGS_INPUT_FOLDER}" ]; then - STRINGS_OUTPUT_FOLDER="${UNIVERSAL_BUILD_FOLDER}/${PRODUCT_NAME}Strings.bundle" + STRINGS_OUTPUT_FOLDER="${UNIVERSAL_BUILD_FOLDER}/${PROJECT_NAME}Strings.bundle" rm -rf "${STRINGS_OUTPUT_FOLDER}" cp -R "${STRINGS_INPUT_FOLDER}" "${STRINGS_OUTPUT_FOLDER}" fi diff --git a/scripts/xcode/build-universal-tvos-framework.sh b/scripts/xcode/build-universal-tvos-framework.sh index 8d43b66a50..4f43bdff1d 100755 --- a/scripts/xcode/build-universal-tvos-framework.sh +++ b/scripts/xcode/build-universal-tvos-framework.sh @@ -30,7 +30,6 @@ UNIVERSAL_TV_BUILD_FOLDER=../build/tv/ # make the output directory and delete the framework directory mkdir -p "${UNIVERSAL_TV_BUILD_FOLDER}" rm -rf "${UNIVERSAL_TV_BUILD_FOLDER}/${PROJECT_NAME}.framework" -rm -rf "${UNIVERSAL_TV_BUILD_FOLDER}/${PRODUCT_NAME}.framework" # get target by removing '-Universal' from $TARGET_NAME TARGET=${TARGET_NAME%-Universal} @@ -55,9 +54,9 @@ xcodebuild -target "${TARGET}" \ clean build # Step 2. Copy the framework structure to the universal folder -cp -R "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PRODUCT_NAME}.framework" "${UNIVERSAL_TV_BUILD_FOLDER}/" +cp -R "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PROJECT_NAME}.framework" "${UNIVERSAL_TV_BUILD_FOLDER}/" # Step 3. Create universal binary file using lipo and place the combined executable in the copied framework directory -lipo -create -output "${UNIVERSAL_TV_BUILD_FOLDER}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" \ - "${BUILD_DIR}/${CONFIGURATION}-appletvsimulator/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" \ - "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" +lipo -create -output "${UNIVERSAL_TV_BUILD_FOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" \ + "${BUILD_DIR}/${CONFIGURATION}-appletvsimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" \ + "${BUILD_DIR}/${CONFIGURATION}-appletvos/${PROJECT_NAME}.framework/${PROJECT_NAME}" From 04dabfc88aa2b36b0cc27f550fcbda5d905cce32 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 26 Oct 2020 12:13:32 -0700 Subject: [PATCH 052/227] Back out "Make Basics an actual dependency 1/n" Summary: Original commit changeset: 75c04b3f0155 Reviewed By: dreamolight Differential Revision: D24542236 fbshipit-source-id: bcbee4887f9ad280d4cd6f619f5e3bd1ee02f8a0 --- .../FBSDKCoreKit_Basics-Dynamic.xcconfig | 30 ------------------- .../FBSDKCoreKit_Basics.xcconfig | 28 ----------------- 2 files changed, 58 deletions(-) delete mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig delete mode 100644 FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig deleted file mode 100644 index 41b967ed71..0000000000 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics-Dynamic.xcconfig +++ /dev/null @@ -1,30 +0,0 @@ -// 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. - -#include "Shared/Platform/iOS.xcconfig" -#include "Shared/Target/DynamicFramework.xcconfig" -#include "Shared/Version.xcconfig" - -PRODUCT_NAME = FBSDKCoreKit_Basics -PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics - -CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) - -INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist - -IPHONEOS_DEPLOYMENT_TARGET = 9.0 diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig deleted file mode 100644 index 5bea63d45a..0000000000 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKit_Basics.xcconfig +++ /dev/null @@ -1,28 +0,0 @@ -// 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. - -#include "Shared/Platform/iOS.xcconfig" -#include "Shared/Target/StaticFramework.xcconfig" -#include "Shared/Version.xcconfig" - -PRODUCT_NAME = FBSDKCoreKit_Basics -PRODUCT_BUNDLE_IDENTIFIER = com.facebook.sdk.FBSDKCoreKit.Basics - -CURRENT_PROJECT_VERSION = $(FBSDK_PROJECT_VERSION) - -INFOPLIST_FILE = $(SRCROOT)/FBSDKCoreKit/Info.plist From 1c11a60aff7a63e83311f231fc6352acd5106dc2 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Mon, 26 Oct 2020 13:52:01 -0700 Subject: [PATCH 053/227] Add FB and IG logos to login button Summary: Remove FOA branding from the login button and replace with the Facebook and Instagram logos, as shown here: https://fburl.com/9uzy2vdo Note that Ryan has already seen and approved this implementation of his design. Reviewed By: jvlyn Differential Revision: D24465954 fbshipit-source-id: f06360f4e81f38e0f8f2f0d92aa5bd801ee6ad23 --- .../Internal/AppEvents/FBSDKAppEventsUtilityTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index c0d528ce8d..181749ffd9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -178,7 +178,7 @@ - (void)testGetNumberValue XCTAssertTrue([str isEqualToString:@"1234.56"]); } -#if BUCK +#ifdef BUCK - (void)testGetNumberValueWithLocaleFR { OCMStub(ClassMethod([_mockNSLocale currentLocale])).andReturn([NSLocale localeWithLocaleIdentifier:@"fr"]); From 5ae6f41ac8a3464faf230869d914369949101db7 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Mon, 26 Oct 2020 14:55:34 -0700 Subject: [PATCH 054/227] Fix CoreKit_Basics imports Summary: Fix failing imports from FBSDK_CoreKitBasics Reviewed By: joesus Differential Revision: D24518845 fbshipit-source-id: 8208e9ef8b35681d7a09bde7c37d6ac50cf857f3 --- .../FBSDKSKAdNetworkConversionConfigurationTests.m | 6 +++++- .../FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m | 6 +++++- .../FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m index 4afd96586f..0dfbabcc8f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m @@ -24,7 +24,11 @@ #import "FBSDKSKAdNetworkConversionConfiguration.h" #import "FBSDKSKAdNetworkRule.h" #import "FBSDKTestCase.h" - #import "FBSDKTypeUtility.h" + #if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE + #import "FBSDKCoreKit_Basics.h" + #else + #import + #endif @interface FBSDKSKAdNetworkConversionConfiguration () diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m index d12613e655..6be1d3a5f6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m @@ -19,7 +19,11 @@ #import #import -#import "FBSDKJSONValue.h" +#if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE + #import "FBSDKCoreKit_Basics.h" +#else + #import +#endif @interface FBSDKJSONValueTests : XCTestCase @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m index dafcfd2098..1d8f22c1fd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m @@ -18,7 +18,11 @@ #import "UserDefaultsSpy.h" -#import "FBSDKTypeUtility.h" +#if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE + #import "FBSDKCoreKit_Basics.h" +#else + #import +#endif @implementation UserDefaultsSpy From 9975424cab2dd73fc4e982e174f662273d1bd52c Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 26 Oct 2020 18:07:01 -0700 Subject: [PATCH 055/227] Back out "Fix CoreKit_Basics imports" Summary: Original commit changeset: 8208e9ef8b35 Reviewed By: Mxiim Differential Revision: D24551147 fbshipit-source-id: c88a7d3d3f59adf736d0a297bc233efbb2424832 --- .../FBSDKSKAdNetworkConversionConfigurationTests.m | 6 +----- .../FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m | 6 +----- .../FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m | 6 +----- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m index 0dfbabcc8f..4afd96586f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkConversionConfigurationTests.m @@ -24,11 +24,7 @@ #import "FBSDKSKAdNetworkConversionConfiguration.h" #import "FBSDKSKAdNetworkRule.h" #import "FBSDKTestCase.h" - #if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE - #import "FBSDKCoreKit_Basics.h" - #else - #import - #endif + #import "FBSDKTypeUtility.h" @interface FBSDKSKAdNetworkConversionConfiguration () diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m index 6be1d3a5f6..d12613e655 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKJSONValueTests.m @@ -19,11 +19,7 @@ #import #import -#if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE - #import "FBSDKCoreKit_Basics.h" -#else - #import -#endif +#import "FBSDKJSONValue.h" @interface FBSDKJSONValueTests : XCTestCase @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m index 1d8f22c1fd..dafcfd2098 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/UserDefaultsSpy.m @@ -18,11 +18,7 @@ #import "UserDefaultsSpy.h" -#if defined FBSDKCOCOAPODS || FBSDK_SWIFT_PACKAGE - #import "FBSDKCoreKit_Basics.h" -#else - #import -#endif +#import "FBSDKTypeUtility.h" @implementation UserDefaultsSpy From aa4a4546584f10d17d427c1d7aa2baac224f7dba Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 26 Oct 2020 18:07:01 -0700 Subject: [PATCH 056/227] Bump Version 8.1.0 Summary: ran: `sh scripts/run.sh bump-version 8.1.0` Manually updated CHANGELOG.md. Reviewed By: YOUDAN, KylinChang Differential Revision: D24506932 fbshipit-source-id: 9ed6d6b58a35d8dee299462847628c6400325b45 --- CHANGELOG.md | 25 ++++++++++++++++++- Configurations/Version.xcconfig | 2 +- FBSDKCoreKit.podspec | 2 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 2 +- FBSDKGamingServicesKit.podspec | 2 +- FBSDKLoginKit.podspec | 2 +- FBSDKShareKit.podspec | 2 +- FBSDKTVOSKit.podspec | 2 +- FacebookSDK.podspec | 2 +- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 2 +- 10 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dfc5d55cd..a7a0a50d3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Important -[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.0.0...HEAD) +[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.1.0...HEAD) + +## 8.1.0 + +### Added +- Introduced `AppLinkResolverRequestBuilder` for use in cleaning up and adding tests around `AppLinkResolver` + +### Changed +- Removed version checks for iOS 9 since it’s the default version now. +- Refactored `AppLinkResolver` to use a request builder +- Refactored and added tests around `FBSDKProfile` and `FBSDKProfilePictureView` +- Updated `FBSDKSettings` to use `ADIdentifierManager` for tracking status +- Removes usages of deprecated `UI_USER_INTERFACE_IDIOM()` + +### Fixed +- Issues with Swift names causing warnings - #1522 +- Fixes bugs related to crash handling - #1444 +- Fixes Carthage distribution to include the correct binary slices when building on Xcode12 - #1484 +- Fixes duplicate symbol for `FBSDKVideoUploader` bug #1512 +- GET requests now default to having a 'fields' parameter to avoid warnings about missing fields #1403 +- Fixes Multithreading issue related to crash reporting - #1550 + +[2020-10-23](https://github.com/facebook/facebook-ios-sdk/releases/tag/v8.1.0) | +[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.0.0...v8.1.0) ## 8.0.0 diff --git a/Configurations/Version.xcconfig b/Configurations/Version.xcconfig index e0cb407740..70aaa27827 100644 --- a/Configurations/Version.xcconfig +++ b/Configurations/Version.xcconfig @@ -17,6 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // The versions for FBSDK and Messenger SDK. -FBSDK_PROJECT_VERSION=8.0.0 +FBSDK_PROJECT_VERSION=8.1.0 MNSDK_PROJECT_VERSION=TODO_SUPPORT_MNSDK diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index 8218bf08c7..941e1df5c8 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKCoreKit' - s.version = '8.0.0' + s.version = '8.1.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform core features' s.description = <<-DESC diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 2c25121fb5..70cb07f361 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -100,5 +100,5 @@ #endif -#define FBSDK_VERSION_STRING @"8.0.0" +#define FBSDK_VERSION_STRING @"8.1.0" #define FBSDK_TARGET_PLATFORM_VERSION @"v8.0" diff --git a/FBSDKGamingServicesKit.podspec b/FBSDKGamingServicesKit.podspec index 90aeb0849f..0eeb0217a7 100644 --- a/FBSDKGamingServicesKit.podspec +++ b/FBSDKGamingServicesKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKGamingServicesKit' - s.version = '8.0.0' + s.version = '8.1.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Gaming Services' s.description = <<-DESC diff --git a/FBSDKLoginKit.podspec b/FBSDKLoginKit.podspec index 2e5e4c444d..a6fbaa8922 100644 --- a/FBSDKLoginKit.podspec +++ b/FBSDKLoginKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKLoginKit' - s.version = '8.0.0' + s.version = '8.1.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 diff --git a/FBSDKShareKit.podspec b/FBSDKShareKit.podspec index d47eaec5a7..bd7c2fa453 100644 --- a/FBSDKShareKit.podspec +++ b/FBSDKShareKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKShareKit' - s.version = '8.0.0' + s.version = '8.1.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform Sharing Features' s.description = <<-DESC diff --git a/FBSDKTVOSKit.podspec b/FBSDKTVOSKit.podspec index 7b062dee0b..f73b45b298 100644 --- a/FBSDKTVOSKit.podspec +++ b/FBSDKTVOSKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKTVOSKit' - s.version = '8.0.0' + s.version = '8.1.0' s.summary = 'Official Facebook SDK for tvOS to access Facebook Platform with features like Login and Graph API.' s.description = <<-DESC diff --git a/FacebookSDK.podspec b/FacebookSDK.podspec index d6c2545c35..ac26de8166 100644 --- a/FacebookSDK.podspec +++ b/FacebookSDK.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FacebookSDK' - s.version = '8.0.0' + s.version = '8.1.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform' s.description = <<-DESC diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index 38bbbbd9b5..e3b895ab5e 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -29,7 +29,7 @@ #define FBSDK_MAX_CRASH_LOGS 5 #define FBSDK_CRASH_PATH_NAME @"instrument" #ifndef FBSDK_VERSION_STRING - #define FBSDK_VERSION_STRING @"8.0.0" + #define FBSDK_VERSION_STRING @"8.1.0" #endif static const int fatalSignals[] = From 97118bccd1bf7552753315eb89de330f203005c4 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 27 Oct 2020 13:33:47 -0700 Subject: [PATCH 057/227] Permissions Parsing Summary: Adds tests, typesafety and null checks around parsing permissions. Reviewed By: KylinChang Differential Revision: D24491015 fbshipit-source-id: fb35f86244128f78292757efa6d7a0bb23d719aa --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 4 + .../Internal/FBSDKInternalUtility.m | 10 +- .../Internal/FBSDKInternalUtilityTests.m | 81 +++++++++++++++ .../Helpers/SampleRawRemotePermissions.swift | 99 +++++++++++++++++++ 4 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index b65c34bde8..42ba768af0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -960,6 +960,7 @@ F4EB317F2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EB317E2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m */; }; F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */; }; F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */; }; + F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */; }; F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */; }; F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; @@ -1620,6 +1621,7 @@ F4EB317E2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestPiggybackManagerTests.m; sourceTree = ""; }; F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleGraphRequestConnection.swift; sourceTree = ""; }; F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleGraphRequest.swift; sourceTree = ""; }; + F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleRawRemotePermissions.swift; sourceTree = ""; }; F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationCenterSpy.h; sourceTree = ""; }; F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationCenterSpy.m; sourceTree = ""; }; F4F98BB324CB77F400F0D6EC /* FBSDKSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKSafeCast.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.h; sourceTree = ""; }; @@ -2723,6 +2725,7 @@ F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */, F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */, + F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */, ); path = Helpers; sourceTree = ""; @@ -4205,6 +4208,7 @@ F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, + F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */, 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 148bbb195f..bf5ba5e928 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -109,11 +109,15 @@ + (void)extractPermissionsFromResponse:(NSDictionary *)responseObject declinedPermissions:(NSMutableSet *)declinedPermissions expiredPermissions:(NSMutableSet *)expiredPermissions { - NSArray *resultData = responseObject[@"data"]; + NSArray *resultData = [FBSDKTypeUtility dictionary:responseObject objectForKey:@"data" ofType:NSArray.class]; if (resultData.count > 0) { for (NSDictionary *permissionsDictionary in resultData) { - NSString *permissionName = permissionsDictionary[@"permission"]; - NSString *status = permissionsDictionary[@"status"]; + NSString *permissionName = [FBSDKTypeUtility dictionary:permissionsDictionary objectForKey:@"permission" ofType:NSString.class]; + NSString *status = [FBSDKTypeUtility dictionary:permissionsDictionary objectForKey:@"status" ofType:NSString.class]; + + if (!permissionName || !status) { + continue; + } if ([status isEqualToString:@"granted"]) { [grantedPermissions addObject:permissionName]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m index fab9b4108d..7848e60cda 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m @@ -20,6 +20,7 @@ #import #import "FBSDKCoreKit.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKInternalUtility.h" @interface FBSDKInternalUtilityTests : XCTestCase @@ -132,4 +133,84 @@ - (void)testFacebookURL XCTAssertEqualObjects(URLString, @"https://m.facebook.com/" FBSDK_TARGET_PLATFORM_VERSION @"/dialog/share"); } +- (void)testParsingPermissionsWithFuzzyValues +{ + NSMutableSet *grantedPermissions = [NSMutableSet set]; + NSMutableSet *declinedPermissions = [NSMutableSet set]; + NSMutableSet *expiredPermissions = [NSMutableSet set]; + + // A lack of a runtime crash is considered a success here. + for (int i = 0; i < 1000; i++) { + [FBSDKInternalUtility extractPermissionsFromResponse:SampleRawRemotePermissionList.randomValues + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions]; + } +} + +- (void)testExtractingPermissionsFromResponseWithInvalidTopLevelKey +{ + NSMutableSet *grantedPermissions = [NSMutableSet set]; + NSMutableSet *declinedPermissions = [NSMutableSet set]; + NSMutableSet *expiredPermissions = [NSMutableSet set]; + + [FBSDKInternalUtility extractPermissionsFromResponse:SampleRawRemotePermissionList.missingTopLevelKey + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions]; + XCTAssertEqual(grantedPermissions.count, 0, "Should not add granted permissions if top level key is missing"); + XCTAssertEqual(declinedPermissions.count, 0, "Should not add declined permissions if top level key is missing"); + XCTAssertEqual(expiredPermissions.count, 0, "Should not add expired permissions if top level key is missing"); +} + +- (void)testExtractingPermissionsFromResponseWithMissingPermissions +{ + NSMutableSet *grantedPermissions = [NSMutableSet set]; + NSMutableSet *declinedPermissions = [NSMutableSet set]; + NSMutableSet *expiredPermissions = [NSMutableSet set]; + + [FBSDKInternalUtility extractPermissionsFromResponse:SampleRawRemotePermissionList.missingPermissions + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions]; + XCTAssertEqual(grantedPermissions.count, 0, "Should not add missing granted permissions"); + XCTAssertEqual(declinedPermissions.count, 0, "Should not add missing declined permissions"); + XCTAssertEqual(expiredPermissions.count, 0, "Should not add missing expired permissions"); +} + +- (void)testExtractingPermissionsFromResponseWithMissingStatus +{ + NSMutableSet *grantedPermissions = [NSMutableSet set]; + NSMutableSet *declinedPermissions = [NSMutableSet set]; + NSMutableSet *expiredPermissions = [NSMutableSet set]; + + [FBSDKInternalUtility extractPermissionsFromResponse:SampleRawRemotePermissionList.missingStatus + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions]; + XCTAssertEqual(grantedPermissions.count, 0, "Should not add a permission with a missing status"); + XCTAssertEqual(declinedPermissions.count, 0, "Should not add a permission with a missing status"); + XCTAssertEqual(expiredPermissions.count, 0, "Should not add a permission with a missing status"); +} + +- (void)testExtractingPermissionsFromResponseWithValidPermissions +{ + NSMutableSet *grantedPermissions = [NSMutableSet set]; + NSMutableSet *declinedPermissions = [NSMutableSet set]; + NSMutableSet *expiredPermissions = [NSMutableSet set]; + + [FBSDKInternalUtility extractPermissionsFromResponse:SampleRawRemotePermissionList.validAllStatuses + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions]; + XCTAssertEqual(grantedPermissions.count, 1, "Should add granted permissions when available"); + XCTAssertTrue([grantedPermissions containsObject:@"email"], "Should add the correct permission to granted permissions"); + + XCTAssertEqual(declinedPermissions.count, 1, "Should add declined permissions when available"); + XCTAssertTrue([declinedPermissions containsObject:@"birthday"], "Should add the correct permission to declined permissions"); + + XCTAssertEqual(expiredPermissions.count, 1, "Should add expired permissions when available"); + XCTAssertTrue([expiredPermissions containsObject:@"first_name"], "Should add the correct permission to expired permissions"); +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift new file mode 100644 index 0000000000..aba991227d --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift @@ -0,0 +1,99 @@ +// 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 Foundation + +@objc +public class SampleRawRemotePermissionList : NSObject { + + @objc + public static var missingPermissions: [String: Any] { + [ + "data": [ + [ + "permission": nil, + "status": "granted" + ], + [ + "permission": nil, + "status": "declined" + ], + [ + "permission": nil, + "status": "expired" + ] + ] + ] + } + + @objc + public static var missingStatus: [String: Any] { + [ + "data": [ + [ + "permission": "email", + "status": nil + ] + ] + ] + } + + @objc + public static let missingTopLevelKey: [String: Any] = [:] + + @objc + public static var randomValues: Any { + let json: Any = [ + "data": [ + [ + "permission": "foo", + "status": "granted" + ] + ] + ] + return Fuzzer.randomize(json: json) + } + + @objc + public static var validAllStatuses: [String: Any] { + [ + "data": [ + [ + "permission": "email", + "status": "granted" + ], + [ + "permission": "birthday", + "status": "declined" + ], + [ + "permission": "first_name", + "status": "expired" + ] + ] + ] + } + +} + +@objc public class SampleRawRemotePermission : NSObject { + + @objc public static let missingTopLevelKey: [String: Any] = [:] + + +} From 034ea8a28fd2c5ad0fc4f73791f5db120ba740ca Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 27 Oct 2020 13:33:47 -0700 Subject: [PATCH 058/227] GraphRequestPiggybackManager Tests 2/n Summary: $title Reviewed By: KylinChang Differential Revision: D24462119 fbshipit-source-id: 3e3e7b16233be944f6ddfd985b924f6fb4e21a17 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m | 11 + .../FBSDKGraphRequestPiggybackManager.m | 8 +- .../FBSDKGraphRequestPiggybackManagerTests.m | 392 +++++++++++++++++- 3 files changed, 398 insertions(+), 13 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m index 969e5d598c..b8c50da038 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m @@ -286,4 +286,15 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:self.graphDomain forKey:FBSDK_ACCESSTOKEN_GRAPH_DOMAIN_KEY]; } +#pragma mark - Testability + +#if DEBUG + ++ (void)resetCurrentAccessTokenCache +{ + g_currentAccessToken = nil; +} + +#endif + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m index 7ade819841..84982b3dce 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m @@ -90,10 +90,10 @@ + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permission flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:extendRequest completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { - tokenString = result[@"access_token"]; - expirationDateNumber = result[@"expires_at"]; - dataAccessExpirationDateNumber = result[@"data_access_expiration_time"]; - graphDomain = result[@"graph_domain"]; + tokenString = [FBSDKTypeUtility dictionary:result objectForKey:@"access_token" ofType:NSString.class]; + expirationDateNumber = [FBSDKTypeUtility dictionary:result objectForKey:@"expires_at" ofType:NSNumber.class]; + dataAccessExpirationDateNumber = [FBSDKTypeUtility dictionary:result objectForKey:@"data_access_expiration_time" ofType:NSNumber.class]; + graphDomain = [FBSDKTypeUtility dictionary:result objectForKey:@"graph_domain" ofType:NSString.class]; expectingCallbackComplete(); }]; FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/permissions" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m index 087dcef153..ff363d2028 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -22,6 +22,11 @@ #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKTestCase.h" +#import "SampleAccessToken.h" + +@interface FBSDKAccessToken (Testing) ++ (void)resetCurrentAccessTokenCache; +@end @interface FBSDKGraphRequestPiggybackManager (Testing) @@ -39,6 +44,27 @@ @implementation FBSDKGraphRequestPiggybackManagerTests typedef FBSDKGraphRequestPiggybackManager Manager; +- (void)setUp +{ + [super setUp]; + + [self resetCaches]; +} + +- (void)tearDown +{ + [super tearDown]; + + [self resetCaches]; +} + +- (void)resetCaches +{ + [FBSDKAccessToken resetCurrentAccessTokenCache]; +} + +// MARK: - Defaults + - (void)testRefreshThresholdInSeconds { int oneDayInSeconds = 24 * 60 * 60; @@ -59,15 +85,7 @@ - (void)testRefreshRetryInSeconds ); } -- (void)testAddingRequestsWithoutAppID -{ - [self stubAppID:@""]; - - OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:OCMArg.any])); - OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addServerConfigurationPiggyback:OCMArg.any])); - - [Manager addPiggybackRequests:SampleGraphRequestConnection.empty]; -} +// MARK: - Request Eligibility - (void)testSafeForAddingWithMatchingGraphVersionWithAttachment { @@ -101,6 +119,18 @@ - (void)testSafeForAddingWithoutMatchingGraphVersionWithoutAttachment ); } +// MARK: - Adding Requests + +- (void)testAddingRequestsWithoutAppID +{ + [self stubAppID:@""]; + + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:OCMArg.any])); + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addServerConfigurationPiggyback:OCMArg.any])); + + [Manager addPiggybackRequests:SampleGraphRequestConnection.empty]; +} + - (void)testAddingRequestsForConnectionWithSafeRequests { [self stubAppID:@"abc123"]; @@ -138,4 +168,348 @@ - (void)testAddingRequestsForConnectionWithSafeAndUnsafeRequests [Manager addPiggybackRequests:connection]; } +// MARK: - Adding Token Extension Piggyback + +- (void)testAddsTokenExtensionRequest +{ + [self stubAppID:@"abc123"]; + [self stubCurrentAccessTokenWith:SampleAccessToken.validToken]; + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + + [Manager addRefreshPiggyback:connection permissionHandler:nil]; + + FBSDKGraphRequestMetadata *metadata = connection.requests.firstObject; + FBSDKGraphRequest *request = metadata.request; + XCTAssertNotNil(request, "Adding a refresh piggyback to a connection should add a request for refreshing the access token"); + + XCTAssertEqualObjects( + request.graphPath, + @"oauth/access_token", + "Should add a request with the correct graph path for refreshing a token" + ); + NSDictionary *expectedParameters = @{ + @"grant_type" : @"fb_extend_sso_token", + @"fields" : @"", + @"client_id" : SampleAccessToken.validToken.appID + }; + XCTAssertTrue( + [request.parameters isEqualToDictionary:expectedParameters], + "Should add a request with the correct parameters for refreshing a token" + ); + XCTAssertEqual( + request.flags, + FBSDKGraphRequestFlagDisableErrorRecovery, + "Should add a request with the correct flags" + ); +} + +- (void)testCompletingTokenExtensionRequestWithDefaultValues +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:nil]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedTokenString:SampleAccessToken.validToken.tokenString]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithUpdatedEmptyTokenString +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken + results:@{@"access_token" : @""}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj withExpectedTokenString:@""]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithUpdatedWhitespaceOnlyTokenString +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken + results:@{@"access_token" : @" "}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj withExpectedTokenString:@" "]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithInvalidExpirationDate +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken + results:@{@"expires_at" : @"0"}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj]; + return true; + }]] + ) + ); + + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken + results:@{@"expires_at" : @"-1000"}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithUnreasonableValidExpirationDate +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken + results:@{@"expires_at" : @100}]; + + NSDate *expectedExpirationDate = [NSDate dateWithTimeIntervalSince1970:100]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj expectedExpirationDate:expectedExpirationDate]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithReasonableValidExpirationDate +{ + NSTimeInterval oneWeek = 60 * 60 * 24 * 7; + NSDate *oneWeekFromNow = [NSDate dateWithTimeIntervalSinceNow:oneWeek]; + // This is an acceptable value but really should not be. + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken + results:@{@"expires_at" : @(oneWeekFromNow.timeIntervalSince1970)}]; + + NSDate *expectedExpirationDate = [NSDate dateWithTimeIntervalSince1970:oneWeekFromNow.timeIntervalSince1970]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj expectedExpirationDate:expectedExpirationDate]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithInvalidDataExpirationDate +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{@"data_access_expiration_time" : @"0"}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj]; + return true; + }]] + ) + ); + + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{@"data_access_expiration_time" : @"-1000"}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithUnreasonableValidDataExpirationDate +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{@"data_access_expiration_time" : @100}]; + + NSDate *expectedExpirationDate = [NSDate dateWithTimeIntervalSince1970:100]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj expectedDataExpirationDate:expectedExpirationDate]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithReasonableValidDataExpirationDate +{ + NSTimeInterval oneWeek = 60 * 60 * 24 * 7; + NSDate *oneWeekFromNow = [NSDate dateWithTimeIntervalSinceNow:oneWeek]; + // This is an acceptable value but really should not be. + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{@"data_access_expiration_time" : @(oneWeekFromNow.timeIntervalSince1970)}]; + + NSDate *expectedExpirationDate = [NSDate dateWithTimeIntervalSince1970:oneWeekFromNow.timeIntervalSince1970]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj expectedDataExpirationDate:expectedExpirationDate]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithUpdatedEmptyGraphDomain +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{@"graph_domain" : @""}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj withExpectedGraphDomain:@""]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithUpdatedWhitespaceOnlyGraphDomain +{ + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{@"graph_domain" : @" "}]; + + // Check that an access token with the expected field values was set + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj withExpectedGraphDomain:@" "]; + return true; + }]] + ) + ); +} + +- (void)testCompletingTokenExtensionRequestWithFuzzyValues +{ + for (int i = 0; i < 1000; i++) { + [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{ + @"access_token" : [Fuzzer random], + @"expires_at" : [Fuzzer random], + @"data_access_expiration_time" : [Fuzzer random], + @"graph_domain" : [Fuzzer random] + }]; + } +} + +// MARK: - Helpers + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token +{ + [self validateRefreshedToken:token + withExpectedTokenString:SampleAccessToken.validToken.tokenString + expectedRefreshDate:[NSDate date] + expectedExpirationDate:NSDate.distantFuture + expectedDataExpirationDate:NSDate.distantFuture + expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; +} + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token + withExpectedTokenString:(NSString *)expectedTokenString +{ + [self validateRefreshedToken:token + withExpectedTokenString:expectedTokenString + expectedRefreshDate:[NSDate date] + expectedExpirationDate:NSDate.distantFuture + expectedDataExpirationDate:NSDate.distantFuture + expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; +} + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token + expectedExpirationDate:(NSDate *)expectedExpirationDate +{ + [self validateRefreshedToken:token + withExpectedTokenString:SampleAccessToken.validToken.tokenString + expectedRefreshDate:[NSDate date] + expectedExpirationDate:expectedExpirationDate + expectedDataExpirationDate:NSDate.distantFuture + expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; +} + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token + expectedDataExpirationDate:(NSDate *)expectedDataExpirationDate +{ + [self validateRefreshedToken:token + withExpectedTokenString:SampleAccessToken.validToken.tokenString + expectedRefreshDate:[NSDate date] + expectedExpirationDate:NSDate.distantFuture + expectedDataExpirationDate:expectedDataExpirationDate + expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; +} + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token + withExpectedGraphDomain:(NSString *)expectedGraphDomain +{ + [self validateRefreshedToken:token + withExpectedTokenString:SampleAccessToken.validToken.tokenString + expectedRefreshDate:[NSDate date] + expectedExpirationDate:NSDate.distantFuture + expectedDataExpirationDate:NSDate.distantFuture + expectedGraphDomain:expectedGraphDomain]; +} + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token + withExpectedTokenString:(NSString *)expectedTokenString + expectedRefreshDate:(NSDate *)expectedRefreshDate + expectedExpirationDate:(NSDate *)expectedExpirationDate + expectedDataExpirationDate:(NSDate *)expectedDataExpirationDate + expectedGraphDomain:(NSString *)expectedGraphDomain +{ + XCTAssertEqualObjects(token.tokenString, expectedTokenString, "A refreshed token should have the expected token string"); + XCTAssertEqualWithAccuracy(token.refreshDate.timeIntervalSince1970, expectedRefreshDate.timeIntervalSince1970, 1, "A refreshed token should have the expected refresh date"); + XCTAssertEqualObjects(token.expirationDate, expectedExpirationDate, "A refreshed token should have the expected expiration date"); + XCTAssertEqualObjects(token.dataAccessExpirationDate, expectedDataExpirationDate, "A refreshed token should have the expected data access expiration date"); + XCTAssertEqualObjects(token.graphDomain, expectedGraphDomain, "A refreshed token should have the expected graph domain"); +} + +- (void)completeTokenRefreshForAccessToken:(FBSDKAccessToken *)token results:(NSDictionary *)results +{ + [self stubAppID:token.appID]; + [self stubCurrentAccessTokenWith:token]; + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + + [Manager addRefreshPiggyback:connection permissionHandler:nil]; + + FBSDKGraphRequestMetadata *metadata = connection.requests.firstObject; + + // The callback that sets the token ignores the first call to it + // because it's waiting on the permissions call to complete first. + // We can get around this for now by invoking the handler twice. + metadata.completionHandler(connection, @{}, nil); + metadata.completionHandler(connection, results, nil); +} + @end From 140d6739f9c646e4d4d731cb6c09daee41abe451 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 27 Oct 2020 13:33:47 -0700 Subject: [PATCH 059/227] GraphRequestPiggybackManager Tests 3/n Summary: $title Reviewed By: KylinChang Differential Revision: D24511936 fbshipit-source-id: 4335b0b394e6a8fc7166a2f884f283e0fbabe81d --- .../Internal/Helpers/SampleAccessToken.h | 4 +- .../Internal/Helpers/SampleAccessToken.m | 15 + .../Helpers/SampleRawRemotePermissions.swift | 27 ++ .../FBSDKGraphRequestPiggybackManagerTests.m | 329 +++++++++++++++++- 4 files changed, 369 insertions(+), 6 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h index 210a815d12..193101cbd6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h @@ -25,7 +25,9 @@ NS_ASSUME_NONNULL_BEGIN @interface SampleAccessToken : NSObject + (FBSDKAccessToken *)validToken; - ++ (FBSDKAccessToken *)validTokenWithPermissions:(NSArray *)permissions + declinedPermissions:(NSArray *)declinedPermissions + expiredPermissions:(NSArray *)expiredPermissions; @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m index 30af95890a..0c36e27659 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m @@ -33,4 +33,19 @@ + (FBSDKAccessToken *)validToken dataAccessExpirationDate:nil]; } ++ (FBSDKAccessToken *)validTokenWithPermissions:(NSArray *)permissions + declinedPermissions:(NSArray *)declinedPermissions + expiredPermissions:(NSArray *)expiredPermissions +{ + return [[FBSDKAccessToken alloc] initWithTokenString:@"123" + permissions:permissions + declinedPermissions:declinedPermissions + expiredPermissions:expiredPermissions + appID:@"123" + userID:@"user123" + expirationDate:nil + refreshDate:nil + dataAccessExpirationDate:nil]; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift index aba991227d..1f7123c11d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift @@ -89,6 +89,33 @@ public class SampleRawRemotePermissionList : NSObject { ] } + @objc + public static func with( + granted: [String] = [], + declined: [String] = [], + expired: [String] = [] + ) -> [String: Any] { + let grantedPermissions = granted.map { + return [ + "permission": $0, + "status": "granted" + ] + } + let declinedPermissions = declined.map { + return [ + "permission": $0, + "status": "declined" + ] + } + let expiredPermissions = expired.map { + return [ + "permission": $0, + "status": "expired" + ] + } + return ["data": grantedPermissions + expiredPermissions + declinedPermissions] + } + } @objc public class SampleRawRemotePermission : NSObject { diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m index ff363d2028..2a2cd81adc 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -425,6 +425,250 @@ - (void)testCompletingTokenExtensionRequestWithFuzzyValues } } +// MARK: - Adding Permissions Refresh Piggyback + +- (void)testAddsPermissionsRefreshRequest +{ + [self stubAppID:@"abc123"]; + [self stubCurrentAccessTokenWith:SampleAccessToken.validToken]; + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + + [Manager addRefreshPiggyback:connection permissionHandler:nil]; + + FBSDKGraphRequestMetadata *metadata = connection.requests.lastObject; + FBSDKGraphRequest *request = metadata.request; + XCTAssertNotNil(request, "Adding a refresh piggyback to a connection should add a request for refreshing permissions"); + + XCTAssertEqualObjects( + request.graphPath, + @"me/permissions", + "Should add a request with the correct graph path for refreshing permissions" + ); + + NSDictionary *expectedParameters = @{@"fields" : @""}; + XCTAssertTrue( + [request.parameters isEqualToDictionary:expectedParameters], + "Should add a request with the correct parameters for refreshing permissions" + ); + XCTAssertEqual( + request.flags, + FBSDKGraphRequestFlagDisableErrorRecovery, + "Should add a request with the correct flags for refreshing permissions" + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithEmptyResults +{ + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + + [self completePermissionsRefreshForAccessToken:token results:nil]; + + // Refreshed token clears permissions when there is no error + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedPermissions:@[] + expectedDeclinedPermissions:@[] + expectedExpiredPermissions:@[] + ]; + return true; + }]] + ) + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithEmptyResultsWithError +{ + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + + [self completePermissionsRefreshForAccessToken:token results:nil error:[NSError new]]; + + // Refreshed token uses permissions from current access token when there is an error on permissions refresh + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedPermissions:token.permissions.allObjects + expectedDeclinedPermissions:token.declinedPermissions.allObjects + expectedExpiredPermissions:token.expiredPermissions.allObjects + ]; + return true; + }]] + ) + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithNewGrantedPermissions +{ + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + + NSDictionary *results = [SampleRawRemotePermissionList withGranted:@[@"foo"] declined:@[] expired:@[]]; + + [self completePermissionsRefreshForAccessToken:token results:results]; + + // Refreshed token clears unspecified permissions when there are newly specified permissions in the response + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedPermissions:@[@"foo"] + expectedDeclinedPermissions:@[] + expectedExpiredPermissions:@[] + ]; + return true; + }]] + ) + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithNewDeclinedPermissions +{ + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + + NSDictionary *results = [SampleRawRemotePermissionList withGranted:@[] declined:@[@"foo"] expired:@[]]; + + [self completePermissionsRefreshForAccessToken:token results:results]; + + // Refreshed token clears unspecified permissions when there are newly specified permissions in the response + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedPermissions:@[] + expectedDeclinedPermissions:@[@"foo"] + expectedExpiredPermissions:@[] + ]; + return true; + }]] + ) + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithNewExpiredPermissions +{ + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + [self stubCurrentAccessTokenWith:token]; + + NSDictionary *results = [SampleRawRemotePermissionList withGranted:@[] declined:@[] expired:@[@"foo"]]; + + [self completePermissionsRefreshForAccessToken:SampleAccessToken.validToken results:results]; + + // Refreshed token clears unspecified permissions when there are newly specified permissions in the response + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedPermissions:@[] + expectedDeclinedPermissions:@[] + expectedExpiredPermissions:@[@"foo"] + ]; + return true; + }]] + ) + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithNewPermissions +{ + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + + NSDictionary *results = [SampleRawRemotePermissionList withGranted:@[@"foo"] + declined:@[@"bar"] + expired:@[@"baz"]]; + + [self completePermissionsRefreshForAccessToken:token results:results]; + + // Refreshed token clears unspecified permissions when there are newly specified permissions in the response + OCMVerify( + ClassMethod( + [self.accessTokenClassMock setCurrentAccessToken:[OCMArg checkWithBlock:^BOOL (id obj) { + [self validateRefreshedToken:obj + withExpectedPermissions:@[@"foo"] + expectedDeclinedPermissions:@[@"bar"] + expectedExpiredPermissions:@[@"baz"] + ]; + return true; + }]] + ) + ); +} + +- (void)testCompletingPermissionsRefreshRequestWithPermissionsHandlerWithoutError +{ + XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:self.name]; + FBSDKAccessToken *expectedToken = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + [self stubCurrentAccessTokenWith:expectedToken]; + + NSDictionary *results = [SampleRawRemotePermissionList withGranted:@[@"foo"] + declined:@[@"bar"] + expired:@[@"baz"]]; + + [self completePermissionsRefreshForAccessToken:SampleAccessToken.validToken + results:results + permissionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + XCTAssertEqualObjects( + result, + results, + "Should pass the raw results to the provided permissions handler" + ); + XCTAssertNil( + error, + "Should invoke the permissions handler regardless of error state" + ); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[expectation] timeout:1]; +} + +- (void)testCompletingPermissionsRefreshRequestWithPermissionsHandlerWithError +{ + XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:self.name]; + FBSDKAccessToken *expectedToken = [SampleAccessToken validTokenWithPermissions:@[@"email"] + declinedPermissions:@[@"publish"] + expiredPermissions:@[@"friends"]]; + [self stubCurrentAccessTokenWith:expectedToken]; + + NSDictionary *results = [SampleRawRemotePermissionList withGranted:@[@"foo"] + declined:@[@"bar"] + expired:@[@"baz"]]; + NSError *expectedError = [NSError new]; + + [self completePermissionsRefreshForAccessToken:SampleAccessToken.validToken + results:results + error:expectedError + permissionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + XCTAssertEqualObjects( + result, + results, + "Should pass the raw results to the provided permissions handler" + ); + XCTAssertEqualObjects( + error, + expectedError, + "Should pass the error through to the permissions handler" + ); + [expectation fulfill]; + }]; + + [self waitForExpectations:@[expectation] timeout:1]; +} + // MARK: - Helpers - (void)validateRefreshedToken:(FBSDKAccessToken *)token @@ -434,7 +678,10 @@ - (void)validateRefreshedToken:(FBSDKAccessToken *)token expectedRefreshDate:[NSDate date] expectedExpirationDate:NSDate.distantFuture expectedDataExpirationDate:NSDate.distantFuture - expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; + expectedGraphDomain:SampleAccessToken.validToken.graphDomain + expectedPermissions:[NSArray array] + expectedDeclinedPermissions:[NSArray array] + expectedExpiredPermissions:[NSArray array]]; } - (void)validateRefreshedToken:(FBSDKAccessToken *)token @@ -445,7 +692,10 @@ - (void)validateRefreshedToken:(FBSDKAccessToken *)token expectedRefreshDate:[NSDate date] expectedExpirationDate:NSDate.distantFuture expectedDataExpirationDate:NSDate.distantFuture - expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; + expectedGraphDomain:SampleAccessToken.validToken.graphDomain + expectedPermissions:[NSArray array] + expectedDeclinedPermissions:[NSArray array] + expectedExpiredPermissions:[NSArray array]]; } - (void)validateRefreshedToken:(FBSDKAccessToken *)token @@ -456,7 +706,10 @@ - (void)validateRefreshedToken:(FBSDKAccessToken *)token expectedRefreshDate:[NSDate date] expectedExpirationDate:expectedExpirationDate expectedDataExpirationDate:NSDate.distantFuture - expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; + expectedGraphDomain:SampleAccessToken.validToken.graphDomain + expectedPermissions:[NSArray array] + expectedDeclinedPermissions:[NSArray array] + expectedExpiredPermissions:[NSArray array]]; } - (void)validateRefreshedToken:(FBSDKAccessToken *)token @@ -467,7 +720,10 @@ - (void)validateRefreshedToken:(FBSDKAccessToken *)token expectedRefreshDate:[NSDate date] expectedExpirationDate:NSDate.distantFuture expectedDataExpirationDate:expectedDataExpirationDate - expectedGraphDomain:SampleAccessToken.validToken.graphDomain]; + expectedGraphDomain:SampleAccessToken.validToken.graphDomain + expectedPermissions:[NSArray array] + expectedDeclinedPermissions:[NSArray array] + expectedExpiredPermissions:[NSArray array]]; } - (void)validateRefreshedToken:(FBSDKAccessToken *)token @@ -478,7 +734,26 @@ - (void)validateRefreshedToken:(FBSDKAccessToken *)token expectedRefreshDate:[NSDate date] expectedExpirationDate:NSDate.distantFuture expectedDataExpirationDate:NSDate.distantFuture - expectedGraphDomain:expectedGraphDomain]; + expectedGraphDomain:expectedGraphDomain + expectedPermissions:[NSArray array] + expectedDeclinedPermissions:[NSArray array] + expectedExpiredPermissions:[NSArray array]]; +} + +- (void)validateRefreshedToken:(FBSDKAccessToken *)token + withExpectedPermissions:(NSArray *)expectedPermissions + expectedDeclinedPermissions:(NSArray *)expectedDeclinedPermissions + expectedExpiredPermissions:(NSArray *)expectedExpiredPermissions +{ + [self validateRefreshedToken:token + withExpectedTokenString:SampleAccessToken.validToken.tokenString + expectedRefreshDate:[NSDate date] + expectedExpirationDate:NSDate.distantFuture + expectedDataExpirationDate:NSDate.distantFuture + expectedGraphDomain:SampleAccessToken.validToken.graphDomain + expectedPermissions:expectedPermissions + expectedDeclinedPermissions:expectedDeclinedPermissions + expectedExpiredPermissions:expectedExpiredPermissions]; } - (void)validateRefreshedToken:(FBSDKAccessToken *)token @@ -487,12 +762,18 @@ - (void)validateRefreshedToken:(FBSDKAccessToken *)token expectedExpirationDate:(NSDate *)expectedExpirationDate expectedDataExpirationDate:(NSDate *)expectedDataExpirationDate expectedGraphDomain:(NSString *)expectedGraphDomain + expectedPermissions:(NSArray *)expectedPermissions + expectedDeclinedPermissions:(NSArray *)expectedDeclinedPermissions + expectedExpiredPermissions:(NSArray *)expectedExpiredPermissions { XCTAssertEqualObjects(token.tokenString, expectedTokenString, "A refreshed token should have the expected token string"); XCTAssertEqualWithAccuracy(token.refreshDate.timeIntervalSince1970, expectedRefreshDate.timeIntervalSince1970, 1, "A refreshed token should have the expected refresh date"); XCTAssertEqualObjects(token.expirationDate, expectedExpirationDate, "A refreshed token should have the expected expiration date"); XCTAssertEqualObjects(token.dataAccessExpirationDate, expectedDataExpirationDate, "A refreshed token should have the expected data access expiration date"); XCTAssertEqualObjects(token.graphDomain, expectedGraphDomain, "A refreshed token should have the expected graph domain"); + XCTAssertEqualObjects(token.permissions.allObjects, expectedPermissions, "A refreshed token should have the expected permissions"); + XCTAssertEqualObjects(token.declinedPermissions.allObjects, expectedDeclinedPermissions, "A refreshed token should have the expected declined permissions"); + XCTAssertEqualObjects(token.expiredPermissions.allObjects, expectedExpiredPermissions, "A refreshed token should have the expected expired permissions"); } - (void)completeTokenRefreshForAccessToken:(FBSDKAccessToken *)token results:(NSDictionary *)results @@ -512,4 +793,42 @@ - (void)completeTokenRefreshForAccessToken:(FBSDKAccessToken *)token results:(NS metadata.completionHandler(connection, results, nil); } +- (void)completePermissionsRefreshForAccessToken:(FBSDKAccessToken *)token + results:(NSDictionary *)results +{ + [self completePermissionsRefreshForAccessToken:token results:results error:nil]; +} + +- (void)completePermissionsRefreshForAccessToken:(FBSDKAccessToken *)token + results:(NSDictionary *)results + error:(NSError *)error +{ + [self completePermissionsRefreshForAccessToken:token results:results error:error permissionHandler:nil]; +} + +- (void)completePermissionsRefreshForAccessToken:(FBSDKAccessToken *)token + results:(NSDictionary *)results + permissionHandler:(FBSDKGraphRequestBlock)permissionHandler +{ + [self completePermissionsRefreshForAccessToken:token results:results error:nil permissionHandler:permissionHandler]; +} + +- (void)completePermissionsRefreshForAccessToken:(FBSDKAccessToken *)token + results:(NSDictionary *)results + error:(NSError *)error + permissionHandler:(FBSDKGraphRequestBlock)permissionHandler +{ + [self stubAppID:token.appID]; + [self stubCurrentAccessTokenWith:token]; + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + + [Manager addRefreshPiggyback:connection permissionHandler:permissionHandler]; + + FBSDKGraphRequestMetadata *tokenRefreshRequestMetadata = connection.requests.firstObject; + FBSDKGraphRequestMetadata *permissionsRequestMetadata = connection.requests.lastObject; + + tokenRefreshRequestMetadata.completionHandler(connection, nil, nil); + permissionsRequestMetadata.completionHandler(connection, results, error); +} + @end From adec1217018e4f69c3bcd9bd6d7d98f37d0b21b5 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 27 Oct 2020 15:36:15 -0700 Subject: [PATCH 060/227] GraphRequestPiggybackManager Tests 4/n Summary: $title Reviewed By: KylinChang Differential Revision: D24516712 fbshipit-source-id: 1fa66e1da4895ef0ceecdf0a919367b0511f26a8 --- .../FBSDKGraphRequestPiggybackManager.m | 25 +++-- .../Internal/Helpers/FBSDKTestCase.h | 3 + .../Internal/Helpers/FBSDKTestCase.m | 11 +++ .../Internal/Helpers/SampleAccessToken.h | 2 + .../Internal/Helpers/SampleAccessToken.m | 13 +++ .../FBSDKGraphRequestPiggybackManagerTests.m | 91 +++++++++++++++++++ 6 files changed, 137 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m index 84982b3dce..871fc5e92f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m @@ -25,6 +25,8 @@ @implementation FBSDKGraphRequestPiggybackManager +static NSDate *_lastRefreshTry = nil; + + (void)addPiggybackRequests:(FBSDKGraphRequestConnection *)connection { if ([FBSDKSettings appID].length > 0) { @@ -123,19 +125,13 @@ + (void)addRefreshPiggybackIfStale:(FBSDKGraphRequestConnection *)connection // don't piggy back more than once an hour as a cheap way of // retrying in cases of errors and preventing duplicate refreshes. // obviously this is not foolproof but is simple and sufficient. - static NSDate *lastRefreshTry; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - lastRefreshTry = [NSDate distantPast]; - }); - NSDate *now = [NSDate date]; NSDate *tokenRefreshDate = [FBSDKAccessToken currentAccessToken].refreshDate; if (tokenRefreshDate - && [now timeIntervalSinceDate:lastRefreshTry] > [self _tokenRefreshRetryInSeconds] + && [now timeIntervalSinceDate:[self _lastRefreshTry]] > [self _tokenRefreshRetryInSeconds] && [now timeIntervalSinceDate:tokenRefreshDate] > [self _tokenRefreshThresholdInSeconds]) { [self addRefreshPiggyback:connection permissionHandler:NULL]; - lastRefreshTry = [NSDate date]; + [self _setLastRefreshTry:[NSDate date]]; } } @@ -170,4 +166,17 @@ + (int)_tokenRefreshRetryInSeconds return FBSDKTokenRefreshRetrySeconds; } ++ (NSDate *)_lastRefreshTry +{ + if (!_lastRefreshTry) { + _lastRefreshTry = [NSDate distantPast]; + } + return _lastRefreshTry; +} + ++ (void)_setLastRefreshTry:(NSDate *)date +{ + _lastRefreshTry = date; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index a166e44abe..48c61b0e16 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -217,6 +217,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKGraphRequest.startWithCompletionHandler:` and returns the provided result, error and connection - (void)stubAppLinkResolverRequestBuilderWithIdiomSpecificField:(nullable NSString *)field; +/// Stubs `FBSDKGraphRequestPiggybackManager._lastRefreshTry` and returns the provided `NSDate` +- (void)stubGraphRequestPiggybackManagerLastRefreshTryWith:(NSDate *)date; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index a310713c5a..80c596f867 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -41,6 +41,10 @@ @interface FBSDKAppEvents (Testing) + (FBSDKAppEvents *)singleton; @end +@interface FBSDKGraphRequestPiggybackManager (Testing) ++ (NSDate *)_lastRefreshTry; +@end + @interface FBSDKSettings (Testing) + (void)_logIfSDKSettingsChanged; @end @@ -431,6 +435,13 @@ - (void)stubAppLinkResolverRequestBuilderWithIdiomSpecificField:(nullable NSStri OCMStub([_appLinkResolverRequestBuilderMock getIdiomSpecificField]).andReturn(field); } +- (void)stubGraphRequestPiggybackManagerLastRefreshTryWith:(NSDate *)date +{ + OCMStub(ClassMethod([_graphRequestPiggybackManagerMock _lastRefreshTry])).andReturn(date); +} + +// MARK: - Helpers + - (id)nsNullIfNil:(id)nilValue { id converted = nilValue; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h index 193101cbd6..b359f50abd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h @@ -28,6 +28,8 @@ NS_ASSUME_NONNULL_BEGIN + (FBSDKAccessToken *)validTokenWithPermissions:(NSArray *)permissions declinedPermissions:(NSArray *)declinedPermissions expiredPermissions:(NSArray *)expiredPermissions; ++ (FBSDKAccessToken *)validWithRefreshDate:(NSDate *)date; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m index 0c36e27659..fde86d8502 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m @@ -33,6 +33,19 @@ + (FBSDKAccessToken *)validToken dataAccessExpirationDate:nil]; } ++ (FBSDKAccessToken *)validWithRefreshDate:(NSDate *)date +{ + return [[FBSDKAccessToken alloc] initWithTokenString:@"123" + permissions:@[] + declinedPermissions:@[] + expiredPermissions:@[] + appID:@"123" + userID:@"user123" + expirationDate:nil + refreshDate:date + dataAccessExpirationDate:nil]; +} + + (FBSDKAccessToken *)validTokenWithPermissions:(NSArray *)permissions declinedPermissions:(NSArray *)declinedPermissions expiredPermissions:(NSArray *)expiredPermissions diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m index 2a2cd81adc..f7d3bc3302 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -33,6 +33,7 @@ @interface FBSDKGraphRequestPiggybackManager (Testing) + (int)_tokenRefreshThresholdInSeconds; + (int)_tokenRefreshRetryInSeconds; + (BOOL)_safeForPiggyback:(FBSDKGraphRequest *)request; ++ (void)_setLastRefreshTry:(NSDate *)date; @end @@ -669,8 +670,98 @@ - (void)testCompletingPermissionsRefreshRequestWithPermissionsHandlerWithError [self waitForExpectations:@[expectation] timeout:1]; } +// MARK: - Refreshing if Stale + +- (void)testRefreshIfStaleWithoutAccessToken +{ + [self stubCurrentAccessTokenWith:nil]; + + // Shouldn't add the refresh if there's no access token + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; +} + +- (void)testRefreshIfStaleWithAccessTokenWithoutRefreshDate +{ + [self stubCurrentAccessTokenWith:SampleAccessToken.validToken]; + + // Should not add the refresh if the access token is missing a refresh date + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; +} + +// | Last refresh try > an hour ago | Token refresh date > a day ago | should refresh | +// | true | true | true | +- (void)testRefreshIfStaleWithOldRefreshWithOldTokenRefresh +{ + [self stubGraphRequestPiggybackManagerLastRefreshTryWith:NSDate.distantPast]; + [self stubCurrentAccessTokenWith:self.twoDayOldToken]; + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; + + OCMVerify(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); +} + +// | Last refresh try > an hour ago | Token refresh date > a day ago | should refresh | +// | true | false | false | +- (void)testRefreshIfStaleWithOldLastRefreshWithRecentTokenRefresh +{ + [self stubGraphRequestPiggybackManagerLastRefreshTryWith:NSDate.distantPast]; + [self stubCurrentAccessTokenWith:SampleAccessToken.validToken]; + + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; +} + +// | Last refresh try > an hour ago | Token refresh date > a day ago | should refresh | +// | false | false | false | +- (void)testRefreshIfStaleWithRecentLastRefreshWithRecentTokenRefresh +{ + // Used for manipulating the initial value of the method scoped constant `lastRefreshTry` + [self stubGraphRequestPiggybackManagerLastRefreshTryWith:NSDate.distantFuture]; + + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; +} + +// | Last refresh try > an hour ago | Token refresh date > a day ago | should refresh | +// | false | true | false | +- (void)testRefreshIfStaleWithRecentLastRefreshOldTokenRefresh +{ + // Used for manipulating the initial value of the method scoped constant `lastRefreshTry` + [self stubGraphRequestPiggybackManagerLastRefreshTryWith:NSDate.distantFuture]; + [self stubCurrentAccessTokenWith:self.twoDayOldToken]; + + OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; +} + +- (void)testRefreshIfStaleSideEffects +{ + // Used for manipulating the initial value of the method scoped constant `lastRefreshTry` + [self stubGraphRequestPiggybackManagerLastRefreshTryWith:NSDate.distantPast]; + [self stubCurrentAccessTokenWith:self.twoDayOldToken]; + + [Manager addRefreshPiggybackIfStale:SampleGraphRequestConnection.empty]; + + OCMVerify(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggyback:OCMArg.any permissionHandler:NULL])); + // Should update last refresh try + OCMVerify(ClassMethod([self.graphRequestPiggybackManagerMock _setLastRefreshTry:OCMArg.any])); +} + // MARK: - Helpers +- (FBSDKAccessToken *)twoDayOldToken +{ + int twoDaysInSeconds = 60 * 60 * 48; + return [SampleAccessToken validWithRefreshDate:[NSDate dateWithTimeIntervalSinceNow:-twoDaysInSeconds]]; +} + - (void)validateRefreshedToken:(FBSDKAccessToken *)token { [self validateRefreshedToken:token From 7e98b182cd05d55375105e5cd1cc07408ed312f8 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 27 Oct 2020 15:36:15 -0700 Subject: [PATCH 061/227] GraphRequestPiggybackManagerTests 5/n Summary: $title Reviewed By: KylinChang Differential Revision: D24540358 fbshipit-source-id: 196a441a829a10eee7ae20a9ef4b3871c8773f0e --- .../FBSDKGraphRequestPiggybackManagerTests.m | 140 +++++++++++++++++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m index f7d3bc3302..eaf6e56fad 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -21,6 +21,7 @@ #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKGraphRequestPiggybackManager.h" +#import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "SampleAccessToken.h" @@ -754,12 +755,147 @@ - (void)testRefreshIfStaleSideEffects OCMVerify(ClassMethod([self.graphRequestPiggybackManagerMock _setLastRefreshTry:OCMArg.any])); } +// MARK: - Server Configuration Piggyback + +- (void)testAddingServerConfigurationPiggybackWithDefaultConfigurationExpiredCache +{ + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ + @"defaults" : @YES, + @"timestamp" : self.twoDaysAgo + }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + [self stubAppID:config.appID]; + + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [Manager addServerConfigurationPiggyback:connection]; + FBSDKGraphRequestMetadata *requestMetadata = connection.requests.firstObject; + FBSDKGraphRequest *expectedServerConfigurationRequest = [FBSDKServerConfigurationManager requestToLoadServerConfiguration:nil]; + + [self validateServerConfigurationRequest:requestMetadata.request isEqualTo:expectedServerConfigurationRequest]; +} + +- (void)testAddingServerConfigurationPiggybackWithDefaultConfigurationNonExpiredCache +{ + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ + @"defaults" : @YES, + @"timestamp" : NSDate.date + }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [Manager addServerConfigurationPiggyback:connection]; + + XCTAssertEqual( + connection.requests.count, + 1, + "Should add a server configuration request for a default config with a non-expired cache" + ); +} + +- (void)testAddingServerConfigurationPiggybackWithCustomConfigurationExpiredCache +{ + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ + @"defaults" : @YES, + @"timestamp" : self.twoDaysAgo + }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [Manager addServerConfigurationPiggyback:connection]; + + XCTAssertEqual( + connection.requests.count, + 1, + "Should add a server configuration request for a default config with an expired cached" + ); +} + +- (void)testAddingServerConfigurationPiggybackWithCustomConfigurationNonExpiredCache +{ + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ + @"defaults" : @NO, + @"timestamp" : NSDate.date + }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [Manager addServerConfigurationPiggyback:connection]; + + XCTAssertEqual( + connection.requests.count, + 0, + "Should not add a server configuration request for a custom configuration with a non-expired cache" + ); +} + +- (void)testAddingServerConfigurationPiggybackWithCustomConfigurationMissingTimeout +{ + // Esoterica - the default timeout is nil in the default configuration + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ + @"defaults" : @NO + }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [Manager addServerConfigurationPiggyback:connection]; + + XCTAssertEqual( + connection.requests.count, + 1, + "Should add a server configuration request for a custom configuration with a missing cache timeout" + ); +} + +- (void)testAddingServerConfigurationPiggybackWithDefaultConfigurationMissingTimeout +{ + // Esoterica - the default timeout is nil in the default configuration + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ + @"defaults" : @YES + }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [Manager addServerConfigurationPiggyback:connection]; + + XCTAssertEqual( + connection.requests.count, + 1, + "Should add a server configuration request for a default configuration with a missing cache timeout" + ); +} + // MARK: - Helpers -- (FBSDKAccessToken *)twoDayOldToken +- (NSDate *)twoDaysAgo { int twoDaysInSeconds = 60 * 60 * 48; - return [SampleAccessToken validWithRefreshDate:[NSDate dateWithTimeIntervalSinceNow:-twoDaysInSeconds]]; + return [NSDate dateWithTimeIntervalSinceNow:-twoDaysInSeconds]; +} + +- (FBSDKAccessToken *)twoDayOldToken +{ + return [SampleAccessToken validWithRefreshDate:self.twoDaysAgo]; +} + +- (void)validateServerConfigurationRequest:(FBSDKGraphRequest *)request isEqualTo:(FBSDKGraphRequest *)expectedRequest +{ + XCTAssertNotNil(request, "Adding a server configuration piggyback should add a request to fetch the server configuration"); + + XCTAssertEqualObjects( + request.graphPath, + expectedRequest.graphPath, + "Should add a request with the expected graph path for fetching a server configuration" + ); + XCTAssertEqualObjects( + request.parameters, + expectedRequest.parameters, + "Should add a request with the correct parameters for fetching a server configuration" + ); + XCTAssertEqual( + request.flags, + expectedRequest.flags, + "Should add a request with the correct flags for fetching a server configuration" + ); } - (void)validateRefreshedToken:(FBSDKAccessToken *)token From a1b7ddb8caae3c77c40f4a9ff0082bfc2a31e5e0 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 28 Oct 2020 15:49:17 -0700 Subject: [PATCH 062/227] Bump min os version for aggregate pod (#1553) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1553 CocoaPod publishing will fail since aggregate CocoaPod `FacebookSDK` has a minimum version lower than its dependencies. This fixes that. Reviewed By: Mxiim Differential Revision: D24600872 fbshipit-source-id: 9fcac976db30969f26c65a043a874d7502eec41d --- FacebookSDK.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FacebookSDK.podspec b/FacebookSDK.podspec index ac26de8166..773317701a 100644 --- a/FacebookSDK.podspec +++ b/FacebookSDK.podspec @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.author = 'Facebook' s.platform = :ios, :tvos - s.ios.deployment_target = '8.0' + s.ios.deployment_target = '9.0' s.tvos.deployment_target = '10.0' s.source = { :git => 'https://github.com/facebook/facebook-ios-sdk.git', From f5fdb30d6cac73688be86109c394864f30fd253f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 30 Oct 2020 09:11:17 -0700 Subject: [PATCH 063/227] Fix some minor clang typos and errors Summary: If these were treated as errors instead of warnings, they'd be caught at compile time. Reviewed By: chatura-atapattu Differential Revision: D24195426 fbshipit-source-id: 23215000795daa78f51a4419a79c997b36e176d6 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m | 2 +- FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m | 2 +- .../FBSDKServerConfigurationManager.m | 9 ++++----- .../FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m index dfa9060df5..7d965830b7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m @@ -468,7 +468,7 @@ + (BOOL)isSDKInitialized #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" return [FBSDKSettings isAutoInitEnabled] || g_isSDKInitialized; - #pragma clange diagnostic pop + #pragma clang diagnostic pop } // MARK: - Testability diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m index 7aa0d386da..cd0e26895a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequest.m @@ -178,7 +178,7 @@ + (NSString *)serializeURL:(NSString *)baseUrl #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSURL *parsedURL = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; - #pragma clang pop + #pragma clang diagnostic pop if ([httpMethod isEqualToString:FBSDKHTTPMethodPOST] && !forBatch) { return baseUrl; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m index a137480151..bb951827e4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m @@ -62,9 +62,12 @@ @implementation FBSDKServerConfigurationManager static NSError *_serverConfigurationError; static NSDate *_serverConfigurationErrorTimestamp; static const NSTimeInterval kTimeout = 4.0; -static BOOL _printedUpdateMessage; static BOOL _requeryFinishedForAppStart; +#if DEBUG +static BOOL _printedUpdateMessage; +#endif + typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures) { FBSDKServerConfigurationManagerAppEventsFeaturesNone = 0, @@ -341,10 +344,6 @@ + (void)_didProcessConfigurationFromNetwork:(FBSDKServerConfiguration *)serverCo [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorInformational logEntry:updateMessage]; } #endif - - if (!_printedUpdateMessage) { - _printedUpdateMessage = _printedUpdateMessage; - } } // update the cached copy in NSUserDefaults diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m index 7b46797c02..5199abc732 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m @@ -59,7 +59,7 @@ @implementation FBSDKVideoUploader NSUInteger _videoSize; } -#pragma Public Method +#pragma mark Public Method - (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id)delegate { self = [super init]; @@ -79,7 +79,7 @@ - (void)start [self _postStartRequest]; } -#pragma Helper Method +#pragma mark Helper Method - (void)_postStartRequest { From d65983bebc23381beab7e74a7e37b9848ca60549 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 30 Oct 2020 12:21:04 -0700 Subject: [PATCH 064/227] Cleanup profile tests Summary: EZ deleting unused interface. Reviewed By: dreamolight Differential Revision: D24551501 fbshipit-source-id: 9772f1047e19e33d0e1a0bdea88a1445d61b36b3 --- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index f417a4f58d..d0eda5eb60 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -26,23 +26,8 @@ #import "SampleAccessToken.h" #import "SampleUserProfile.h" -@interface FBSDKSettings () -+ (NSString *)userAgentSuffix; -+ (void)setUserAgentSuffix:(NSString *)suffix; -+ (void)resetLoggingBehaviorsCache; -+ (void)resetFacebookAppIDCache; -+ (void)resetFacebookUrlSchemeSuffixCache; +@interface FBSDKSettings (Testing) + (void)resetFacebookClientTokenCache; -+ (void)resetFacebookDisplayNameCache; -+ (void)resetFacebookDomainPartCache; -+ (void)resetFacebookJpegCompressionQualityCache; -+ (void)resetFacebookAutoInitEnabledCache; -+ (void)resetFacebookInstrumentEnabledCache; -+ (void)resetFacebookAutoLogAppEventsEnabledCache; -+ (void)resetFacebookAdvertiserIDCollectionEnabledCache; -+ (void)resetUserAgentSuffixCache; -+ (void)resetFacebookCodelessDebugLogEnabledCache; -+ (void)resetDataProcessingOptionsCache; @end @interface FBSDKProfile (Testing) From a12182ddfb978a97104250fd6cbe8428c25c3988 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 2 Nov 2020 10:59:33 -0800 Subject: [PATCH 065/227] Unit test network call cleanup Summary: Cleans up obvious cases of unit tests hitting the network. This should cut down on some of the flakiness we've been seeing lately. Reviewed By: Oliverccccct Differential Revision: D24653377 fbshipit-source-id: 1040276f43c547acc6fb5a38482719893fef7f79 --- .../FBSDKGraphRequestConnectionTests.m | 4 ++-- .../Internal/AppEvents/FBSDKAppEventsTests.m | 3 +++ .../AppEvents/FBSDKAppEventsUtilityTests.m | 3 +++ .../Internal/Basics/FBSDKCrashHandlerTests.m | 8 ++++++-- .../Internal/Helpers/FBSDKTestCase.h | 10 ++++++++++ .../Internal/Helpers/FBSDKTestCase.m | 14 ++++++++++++++ .../Internal/Instrument/FBSDKCrashObserverTests.m | 11 ++++++++++- .../Internal/Instrument/FBSDKCrashShieldTests.m | 11 ++++++++++- .../Monitoring/FBSDKMethodUsageMonitorTests.m | 10 +++++++--- .../Internal/Monitoring/FBSDKMonitorTests.m | 9 ++++++--- .../Monitoring/FBSDKPerformanceMonitorTests.m | 10 +++++++--- .../FBSDKGraphRequestPiggybackManagerTests.m | 6 +++++- 12 files changed, 83 insertions(+), 16 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m index f695df1cfd..f07fd959b2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m @@ -104,8 +104,8 @@ - (void)testClientToken [[[mockUtility stub] andReturn:nil] gzip:[OCMArg any]]; XCTestExpectation *exp = [self expectationWithDescription:@"completed request"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - [FBSDKSettings setClientToken:@"clienttoken"]; + [self stubCurrentAccessTokenWith:nil]; + [self stubClientTokenWith:@"clienttoken"]; [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { // If it's a batch request, the token will be in the body. If it's a single request it will be in the url // we should check that it's in one or the other. diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index 0c577407eb..2a06647c8f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -126,6 +126,9 @@ - (void)setUp // Mock FBSDKAppEventsUtility methods [self stubAppEventsUtilityShouldDropAppEventWith:NO]; + + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; } - (void)tearDown diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 181749ffd9..0835631f55 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -55,6 +55,9 @@ - (void)setUp _mockAppEventsUtility = OCMClassMock([FBSDKAppEventsUtility class]); [FBSDKAppEvents setUserID:@"test-user-id"]; _mockNSLocale = OCMClassMock([NSLocale class]); + + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; } - (void)tearDown diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m index a3d961ef8c..39b966e1ec 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m @@ -24,6 +24,7 @@ #import "FBSDKCrashObserver.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" +#import "FBSDKTestCase.h" @interface FBSDKCrashHandler () @@ -40,14 +41,17 @@ + (void)saveCrashLog:(NSDictionary *)crashLog; @end -@interface FBSDKCrashHandlerTests : XCTestCase +@interface FBSDKCrashHandlerTests : FBSDKTestCase @end @implementation FBSDKCrashHandlerTests - (void)setUp { - [FBSDKCrashObserver enable]; + [super setUp]; + + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; } - (void)testSaveSignal diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 48c61b0e16..5b453197fa 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -121,6 +121,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKGraphRequestPiggybackManager` class mock between tests @property (nullable, nonatomic, assign) id graphRequestPiggybackManagerMock; +/// Used for sharing a `FBSDKGraphRequestConnection` class mock between tests +@property (nullable, nonatomic, assign) id graphRequestConnectionClassMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; @@ -220,6 +223,13 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKGraphRequestPiggybackManager._lastRefreshTry` and returns the provided `NSDate` - (void)stubGraphRequestPiggybackManagerLastRefreshTryWith:(NSDate *)date; +/// Disables creation of graph request connections so that they cannot be started. +/// This is the nuclear option. It should be removed as soon as possible so that we can test important things +/// like whether or not a given method actually started a graph request. +/// This should be used only as needed as a stopgap to keep tests +/// from hitting the network while proper mocks are being written. +- (void)stubAllocatingGraphRequestConnection; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 80c596f867..57e93fb865 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -83,6 +83,7 @@ - (void)setUp [self setUpGraphRequestMock]; [self setUpModelManagerClassMock]; [self setUpGraphRequestPiggybackManagerMock]; + [self setUpGraphRequestConnectionClassMock]; } - (void)tearDown @@ -154,6 +155,9 @@ - (void)tearDown [_graphRequestPiggybackManagerMock stopMocking]; _graphRequestPiggybackManagerMock = nil; + + [_graphRequestConnectionClassMock stopMocking]; + _graphRequestConnectionClassMock = nil; } - (void)setUpSettingsMock @@ -267,6 +271,11 @@ - (void)setUpGraphRequestPiggybackManagerMock self.graphRequestPiggybackManagerMock = OCMClassMock(FBSDKGraphRequestPiggybackManager.class); } +- (void)setUpGraphRequestConnectionClassMock +{ + self.graphRequestConnectionClassMock = OCMClassMock(FBSDKGraphRequestConnection.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID @@ -440,6 +449,11 @@ - (void)stubGraphRequestPiggybackManagerLastRefreshTryWith:(NSDate *)date OCMStub(ClassMethod([_graphRequestPiggybackManagerMock _lastRefreshTry])).andReturn(date); } +- (void)stubAllocatingGraphRequestConnection +{ + OCMStub(ClassMethod([_graphRequestConnectionClassMock alloc])); +} + // MARK: - Helpers - (id)nsNullIfNil:(id)nilValue diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m index 2b2515d467..d5209347c0 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashObserverTests.m @@ -21,6 +21,7 @@ #import "FBSDKCrashObserver.h" #import "FBSDKFeatureManager.h" +#import "FBSDKTestCase.h" @interface FBSDKCrashObserver () @@ -28,11 +29,19 @@ + (FBSDKCrashObserver *)sharedInstance; @end -@interface FBSDKCrashObserverTests : XCTestCase +@interface FBSDKCrashObserverTests : FBSDKTestCase @end @implementation FBSDKCrashObserverTests +- (void)setUp +{ + [super setUp]; + + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; +} + - (void)testDidReceiveCrashLogs { FBSDKCrashObserver *crashObserver = [FBSDKCrashObserver sharedInstance]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m index a0172b13c7..7cbe338d1d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m @@ -21,6 +21,7 @@ #import "FBSDKCrashShield.h" #import "FBSDKFeatureManager.h" +#import "FBSDKTestCase.h" @interface FBSDKCrashShield () @@ -29,11 +30,19 @@ + (nullable NSString *)getClassName:(NSString *)entry; @end -@interface FBSDKCrashShieldTests : XCTestCase +@interface FBSDKCrashShieldTests : FBSDKTestCase @end @implementation FBSDKCrashShieldTests +- (void)setUp +{ + [super setUp]; + + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; +} + - (void)testGetFeature { // gated feature in corekit diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m index 911284acb3..1a75249ad1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMethodUsageMonitorTests.m @@ -20,6 +20,7 @@ #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKTestCase.h" @interface FBSDKMonitor (Testing) @@ -30,7 +31,7 @@ + (void)flush; @end -@interface FBSDKMethodUsageMonitorTests : XCTestCase +@interface FBSDKMethodUsageMonitorTests : FBSDKTestCase @end @implementation FBSDKMethodUsageMonitorTests @@ -39,15 +40,18 @@ - (void)setUp { [super setUp]; + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; + [FBSDKMonitor enable]; } - (void)tearDown { - [super tearDown]; - [FBSDKMonitor flush]; [FBSDKMonitor disable]; + + [super tearDown]; } - (void)testRecordingMethodUsage diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m index 34d0b749d1..4602a4fbc7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m @@ -20,6 +20,7 @@ #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKTestCase.h" #import "FakeMonitorStore.h" #import "TestMonitorEntry.h" @@ -33,7 +34,7 @@ + (void)applicationMovingFromActiveStateOrTerminating; @end -@interface FBSDKMonitorTests : XCTestCase +@interface FBSDKMonitorTests : FBSDKTestCase @property (nonatomic) id entry; @property (nonatomic) FakeMonitorStore *store; @@ -62,18 +63,20 @@ - (void)setUp networkerMock = OCMClassMock([FBSDKMonitorNetworker class]); notificationCenterMock = OCMClassMock([NSNotificationCenter class]); timerMock = OCMClassMock([NSTimer class]); + + [self stubAllocatingGraphRequestConnection]; } - (void)tearDown { - [super tearDown]; - [networkerMock stopMocking]; [notificationCenterMock stopMocking]; [timerMock stopMocking]; [FBSDKMonitor flush]; [FBSDKMonitor disable]; [FBSDKMonitor setStore:nil]; + + [super tearDown]; } - (void)testRecordingWhenDisabled diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m index 221d2ce2f4..b431d7fcec 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKPerformanceMonitorTests.m @@ -20,6 +20,7 @@ #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKTestCase.h" @interface FBSDKMonitor (Testing) @@ -30,7 +31,7 @@ + (void)flush; @end -@interface FBSDKPerformanceMonitorTests : XCTestCase +@interface FBSDKPerformanceMonitorTests : FBSDKTestCase @end @implementation FBSDKPerformanceMonitorTests @@ -40,14 +41,17 @@ - (void)setUp [super setUp]; [FBSDKMonitor enable]; + + // This should be removed when these tests are updated to check the actual requests that are created + [self stubAllocatingGraphRequestConnection]; } - (void)tearDown { - [super tearDown]; - [FBSDKMonitor flush]; [FBSDKMonitor disable]; + + [super tearDown]; } - (void)testRecordingPerformance diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m index eaf6e56fad..e2130445b5 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -136,6 +136,8 @@ - (void)testAddingRequestsWithoutAppID - (void)testAddingRequestsForConnectionWithSafeRequests { [self stubAppID:@"abc123"]; + [self stubFetchingCachedServerConfiguration]; + FBSDKGraphRequestConnection *connection = [SampleGraphRequestConnection withRequests:@[SampleGraphRequest.valid]]; [Manager addPiggybackRequests:connection]; @@ -147,6 +149,7 @@ - (void)testAddingRequestsForConnectionWithSafeRequests - (void)testAddingRequestsForConnectionWithUnsafeRequests { [self stubAppID:@"abc123"]; + [self stubFetchingCachedServerConfiguration]; FBSDKGraphRequestConnection *connection = [SampleGraphRequestConnection withRequests:@[SampleGraphRequest.withAttachment]]; OCMReject(ClassMethod([self.graphRequestPiggybackManagerMock addRefreshPiggybackIfStale:connection])); @@ -158,6 +161,7 @@ - (void)testAddingRequestsForConnectionWithUnsafeRequests - (void)testAddingRequestsForConnectionWithSafeAndUnsafeRequests { [self stubAppID:@"abc123"]; + [self stubFetchingCachedServerConfiguration]; FBSDKGraphRequestConnection *connection = [SampleGraphRequestConnection withRequests:@[ SampleGraphRequest.valid, SampleGraphRequest.withAttachment @@ -417,7 +421,7 @@ - (void)testCompletingTokenExtensionRequestWithUpdatedWhitespaceOnlyGraphDomain - (void)testCompletingTokenExtensionRequestWithFuzzyValues { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { [self completeTokenRefreshForAccessToken:SampleAccessToken.validToken results:@{ @"access_token" : [Fuzzer random], @"expires_at" : [Fuzzer random], From 98c0e378929bd05dd30b875fa0696292179126b6 Mon Sep 17 00:00:00 2001 From: Stan Wu Date: Wed, 4 Nov 2020 11:27:57 -0800 Subject: [PATCH 066/227] Fix FBSDKCoreKit_Basics.zip (#1558) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1558 `release_basics ` was the last job for releasing, however, due to the cache in `BUILD_ROOT`, it's actually `FBSDKCoreKit.framework` from `BuildAllKits` ended up with being shipped as Basics module. Reviewed By: Oliverccccct Differential Revision: D24724966 fbshipit-source-id: f48ba01b86a08c973dc374e88a13997973e7f8a9 --- .circleci/config.yml | 2 +- scripts/run.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c71f909a20..b5ade62254 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -82,7 +82,7 @@ commands: - attach_workspace: at: . - run: | - xcodebuild build \ + xcodebuild clean build \ -workspace FacebookSDK.xcworkspace \ -scheme << parameters.scheme >> \ -configuration << parameters.configuration >> diff --git a/scripts/run.sh b/scripts/run.sh index d8901b6bbc..38f544c206 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -442,7 +442,7 @@ release_sdk() { # Release frameworks in static release_static() { release_basics() { - xcodebuild build \ + xcodebuild clean build \ -workspace FacebookSDK.xcworkspace \ -scheme BuildCoreKitBasics \ -configuration Release | xcpretty @@ -461,12 +461,12 @@ release_sdk() { cd .. } - xcodebuild build \ + xcodebuild clean build \ -workspace FacebookSDK.xcworkspace \ -scheme BuildAllKits \ -configuration Release | xcpretty - xcodebuild build \ + xcodebuild clean build \ -workspace FacebookSDK.xcworkspace \ -scheme BuildAllKits_TV \ -configuration Release | xcpretty From 3465d2e919f9ddd9f2c1c1f9e5e1768cff730df5 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Wed, 4 Nov 2020 11:49:59 -0800 Subject: [PATCH 067/227] remove implementation of signal handler Reviewed By: dreamolight Differential Revision: D24719364 fbshipit-source-id: 643ca5cae9f681d4f4356b2019056b30c5362b70 --- .../Internal/Basics/FBSDKCrashHandlerTests.m | 15 ---- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 71 ------------------- 2 files changed, 86 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m index 39b966e1ec..5a4ba77cde 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m @@ -19,8 +19,6 @@ #import #import -#include - #import "FBSDKCrashObserver.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" @@ -36,7 +34,6 @@ + (BOOL)callstack:(NSArray *)callstack containsPrefix:(NSArray *)prefixList; + (NSArray *> *)filterCrashLogs:(NSArray *)prefixList processedCrashLogs:(NSArray *> *)processedCrashLogs; -+ (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack; + (void)saveCrashLog:(NSDictionary *)crashLog; @end @@ -54,18 +51,6 @@ - (void)setUp [self stubAllocatingGraphRequestConnection]; } -- (void)testSaveSignal -{ - NSArray *callStack = @[@"(2 DEV METHODS)", - @"-[FBSDKAccessToken getPermissions]+2321432", - @"-[FBSDKAccessToken getPermissions]+2324084", - @"(14 DEV METHODS)", ]; - id handlerMock = [OCMockObject niceMockForClass:[FBSDKCrashHandler class]]; - [[handlerMock expect] saveCrashLog:[OCMArg any]]; - [FBSDKCrashHandler saveSignal:11 withCallStack:callStack]; // SIGSEGV - [handlerMock verify]; -} - - (void)testGetFBSDKVersion { NSString *basicsVersion = [FBSDKCrashHandler getFBSDKVersion]; diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index e3b895ab5e..ee430c43af 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -20,7 +20,6 @@ #import -#include #import #import "FBSDKLibAnalyzer.h" @@ -32,23 +31,6 @@ #define FBSDK_VERSION_STRING @"8.1.0" #endif -static const int fatalSignals[] = -{ - SIGBUS, - SIGFPE, - SIGILL, - SIGPIPE, - SIGSEGV, - SIGSYS, - SIGTRAP, -}; -static const int fatalSignalsCount = sizeof(fatalSignals) / sizeof(int); -static struct sigaction *previousSignalHandlers = NULL; - -static void installSignalsHandler(void); -static void uninstallSignalsHandler(void); -static void FBSDKSignalHandler(int signal, siginfo_t *signalInfo, void *userContext); - static NSUncaughtExceptionHandler *previousExceptionHandler = NULL; static NSString *mappingTableIdentifier = NULL; static NSString *directoryPath; @@ -122,7 +104,6 @@ + (void)disable { _isTurnedOff = YES; [FBSDKCrashHandler uninstallExceptionsHandler]; - uninstallSignalsHandler(); _observers = nil; } @@ -134,7 +115,6 @@ + (void)addObserver:(id)observer static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ [FBSDKCrashHandler installExceptionsHandler]; - installSignalsHandler(); _processedCrashLogs = [self getProcessedCrashLogs]; }); @synchronized(_observers) { @@ -155,7 +135,6 @@ + (void)removeObserver:(id)observer [_observers removeObject:observer]; if (_observers.count == 0) { [FBSDKCrashHandler uninstallExceptionsHandler]; - uninstallSignalsHandler(); } } } @@ -187,45 +166,6 @@ static void FBSDKExceptionHandler(NSException *exception) } } -static void installSignalsHandler() -{ - previousSignalHandlers = malloc(sizeof(*previousSignalHandlers) * (unsigned)fatalSignalsCount); - struct sigaction action = {{0}, 0, 0}; - action.sa_flags = SA_SIGINFO | SA_ONSTACK; -#if defined(__LP64__) && __LP64__ - action.sa_flags |= SA_64REGSET; -#endif - sigemptyset(&action.sa_mask); - for (size_t i = 0; i < fatalSignalsCount; i++) { - sigaddset(&action.sa_mask, fatalSignals[i]); - } - action.sa_sigaction = &FBSDKSignalHandler; - - for (int i = 0; i < fatalSignalsCount; i++) { - sigaction(fatalSignals[i], &action, &previousSignalHandlers[i]); - } -} - -static void uninstallSignalsHandler() -{ - for (int i = 0; i < fatalSignalsCount; i++) { - sigaction(fatalSignals[i], &previousSignalHandlers[i], NULL); - } -} - -static void FBSDKSignalHandler(int sig, siginfo_t *signalInfo, void *userContext) -{ - uninstallSignalsHandler(); - NSMutableArray *callStack = [[NSThread callStackSymbols] mutableCopy]; - if (callStack) { - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)]; - if (callStack.count > 2 && [callStack objectsAtIndexes:indexSet]) { - [callStack removeObjectsAtIndexes:indexSet]; - } - } - [FBSDKCrashHandler saveSignal:sig withCallStack:callStack]; -} - #pragma mark - Storage + (void)saveException:(NSException *)exception @@ -239,17 +179,6 @@ + (void)saveException:(NSException *)exception } } -+ (void)saveSignal:(int)signal withCallStack:(NSArray *)callStack -{ - if (callStack) { - NSString *signalDescription = [NSString stringWithCString:strsignal(signal) encoding:NSUTF8StringEncoding] ?: [NSString stringWithFormat:@"SIGNUM(%i)", signal]; - [self saveCrashLog:@{ - kFBSDKCallstack : callStack, - kFBSDKCrashReason : signalDescription, - }]; - } -} - + (NSArray *> *)getProcessedCrashLogs { NSArray *> *crashLogs = [self loadCrashLogs]; From 705245005271fa125450c948302e6448525805ea Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Wed, 4 Nov 2020 16:11:20 -0800 Subject: [PATCH 068/227] Fix swiftlint warnings in the facebook-ios-sdk (#1559) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1559 This commit fixes the current swiftlint warnings in the SDK. - Added a blank line between "import Foundation" and "testable import FBSDKCoreKit" to fix sorted_imports. - Excluded "RawAppEventsConfigurationResponseFixtures" in .swiftlint.yml for the type_name violation. - Ignored the trailing_comma rule to allow trailing commas. The following warnings were fixed: ``` warning: Colon Violation: Colons should be next to the identifier when specifying a type and next to the key in dictionary literals. (colon) warning: Type Name Violation: Type name should be between 3 and 40 characters long: 'RawAppEventsConfigurationResponseFixtures' (type_name) warning: Sorted Imports Violation: Imports should be sorted. (sorted_imports) warning: Vertical Whitespace Violation: Limit vertical whitespace to a single empty line. Currently 2. (vertical_whitespace) ``` Reviewed By: joesus Differential Revision: D24691969 fbshipit-source-id: 4fc7a87d613d7053eccbd49519e93206a32b97ef --- .swiftlint.yml | 4 +++- .../Internal/Helpers/SampleGraphRequest.swift | 3 ++- .../Internal/Helpers/SampleGraphRequestConnection.swift | 3 ++- .../Internal/Helpers/SampleRawRemotePermissions.swift | 6 ++---- .../TestXcodeIntegration/AppDelegate.swift | 6 +----- .../TestXcodeIntegration/SceneDelegate.swift | 3 --- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 079b218014..2466a484b9 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -34,6 +34,8 @@ nesting: type_level: 2 private_outlet: allow_private_set: true +type_name: + excluded: [RawAppEventsConfigurationResponseFixtures] disabled_rules: - attributes @@ -55,6 +57,7 @@ disabled_rules: - discouraged_optional_collection - function_default_parameter_at_end - todo + - trailing_comma opt_in_rules: - array_init @@ -153,7 +156,6 @@ opt_in_rules: - switch_case_alignment - syntactic_sugar - trailing_closure - - trailing_comma - trailing_newline - trailing_semicolon - trailing_whitespace diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift index ba3360c149..e5aaf4ee35 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequest.swift @@ -17,9 +17,10 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import Foundation + @testable import FBSDKCoreKit -@objc public class SampleGraphRequest : NSObject { +@objc public class SampleGraphRequest: NSObject { @objc public static let valid = create() @objc public static var withOutdatedVersionWithAttachment = create( diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift index bdebc5cd81..947f2bae6d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleGraphRequestConnection.swift @@ -17,9 +17,10 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import Foundation + @testable import FBSDKCoreKit -@objc public class SampleGraphRequestConnection : NSObject { +@objc public class SampleGraphRequestConnection: NSObject { @objc public static var empty: GraphRequestConnection { GraphRequestConnection() diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift index 1f7123c11d..119611c949 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleRawRemotePermissions.swift @@ -19,7 +19,7 @@ import Foundation @objc -public class SampleRawRemotePermissionList : NSObject { +public class SampleRawRemotePermissionList: NSObject { @objc public static var missingPermissions: [String: Any] { @@ -118,9 +118,7 @@ public class SampleRawRemotePermissionList : NSObject { } -@objc public class SampleRawRemotePermission : NSObject { +@objc public class SampleRawRemotePermission: NSObject { @objc public static let missingTopLevelKey: [String: Any] = [:] - - } diff --git a/testing/TestXcodeIntegration/TestXcodeIntegration/AppDelegate.swift b/testing/TestXcodeIntegration/TestXcodeIntegration/AppDelegate.swift index 01c7535b5d..8d4867f2f9 100644 --- a/testing/TestXcodeIntegration/TestXcodeIntegration/AppDelegate.swift +++ b/testing/TestXcodeIntegration/TestXcodeIntegration/AppDelegate.swift @@ -19,15 +19,13 @@ import UIKit import FBSDKCoreKit +import FBSDKGamingServicesKit import FBSDKLoginKit import FBSDKShareKit -import FBSDKGamingServicesKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true @@ -46,6 +44,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } - - } diff --git a/testing/TestXcodeIntegration/TestXcodeIntegration/SceneDelegate.swift b/testing/TestXcodeIntegration/TestXcodeIntegration/SceneDelegate.swift index 5fd28c2a78..ab03ec700d 100644 --- a/testing/TestXcodeIntegration/TestXcodeIntegration/SceneDelegate.swift +++ b/testing/TestXcodeIntegration/TestXcodeIntegration/SceneDelegate.swift @@ -22,7 +22,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. @@ -57,6 +56,4 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // Use this method to save data, release shared resources, and store enough scene-specific state information // to restore the scene back to its current state. } - - } From 56261b53ced3ff2b0b332688beba1e8e29d24525 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 4 Nov 2020 18:10:32 -0800 Subject: [PATCH 069/227] Adding UshbaKit Project Summary: Adds ability to build universal ushba binary for distribution. Reviewed By: robtimp Differential Revision: D24657072 fbshipit-source-id: 304df1152f2ffb33f300e949f6ccb137d68f9d63 --- FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj | 4 ++-- .../FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h | 8 ++++++++ .../FBSDKCoreKit/Internal/FBSDKProfile+Internal.h | 1 - .../Internal/FBSDKProfilePictureView+Internal.h | 2 +- .../FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h | 2 +- .../FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m | 1 + 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 42ba768af0..ab153d0d9f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -678,7 +678,6 @@ 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 */; }; - B301910E253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */; }; B3C20ACD250B100F00DEC008 /* FBSDKAccessToken+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */; }; BF1C64E624039AD50052C580 /* FBSDKViewHierarchyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BF1C64E524039AD50052C580 /* FBSDKViewHierarchyTests.m */; }; BF247C822374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = BF247C802374E1B100A522C0 /* FBSDKSuggestedEventsIndexer.h */; }; @@ -935,6 +934,7 @@ F4A52B17242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; F4A826B524EC6F9900EB2CD4 /* SampleUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */; }; F4A826B724EC6FAD00EB2CD4 /* FBSDKProfileTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */; }; + F4AE435225508FEA00FA9DE6 /* FBSDKProfilePictureView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */; }; F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */; }; F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF2292241954B400BFB494 /* FBSDKMonitorStoreTests.m */; }; F4BF22A3241954D800BFB494 /* FBSDKMonitorStore.h in Headers */ = {isa = PBXBuildFile; fileRef = F4BF22A1241954D800BFB494 /* FBSDKMonitorStore.h */; }; @@ -3053,7 +3053,6 @@ 7E5557381A8D833100344F86 /* FBSDKAppLinkResolver.h in Headers */, 9D32A8401A69941A000A936D /* FBSDKAccessTokenCaching.h in Headers */, F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, - B301910E253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h in Headers */, 894C0ADF1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h in Headers */, 890414741A647D8800617215 /* FBSDKCoreKit+Internal.h in Headers */, 7EB63DA01A9BE730003A7AED /* FBSDKMeasurementEventListener.h in Headers */, @@ -3075,6 +3074,7 @@ 9DD50A3C1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.h in Headers */, 894C0B111A7021F8009137EF /* FBSDKBase64.h in Headers */, 9D0BC15B1A8D427800BE8BA4 /* FBSDKAppEventsUtility.h in Headers */, + F4AE435225508FEA00FA9DE6 /* FBSDKProfilePictureView+Internal.h in Headers */, 9D0BC1541A8D23DB00BE8BA4 /* FBSDKAppEvents+Internal.h in Headers */, 9D28F1931DB14DBB0057D709 /* FBSDKImageDownloader.h in Headers */, 9D3AF4501A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h in Headers */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index e036237088..a3c00a6257 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -61,6 +61,7 @@ #import "FBSDKSmartDeviceDialogView.h" #endif + #import "FBSDKAccessToken+Internal.h" #import "FBSDKAccessTokenCache.h" #import "FBSDKAccessTokenCaching.h" #import "FBSDKAppEvents+Internal.h" @@ -82,6 +83,7 @@ #import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequestConnection+Internal.h" #import "FBSDKGraphRequestMetadata.h" + #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKIcon.h" #import "FBSDKImageDownloader.h" #import "FBSDKInternalUtility.h" @@ -91,6 +93,8 @@ #import "FBSDKLogo.h" #import "FBSDKMath.h" #import "FBSDKMonitorHeaders.h" + #import "FBSDKProfile+Internal.h" + #import "FBSDKProfilePictureView+Internal.h" #import "FBSDKRestrictiveDataFilterManager.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfiguration+Internal.h" @@ -140,6 +144,7 @@ #import "../AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.h" #import "Base64/FBSDKBase64.h" #import "ErrorRecovery/FBSDKErrorRecoveryAttempter.h" + #import "FBSDKAccessToken+Internal.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" #import "FBSDKDeviceRequestsHelper.h" @@ -149,12 +154,15 @@ #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKMath.h" + #import "FBSDKProfile+Internal.h" + #import "FBSDKProfilePictureView+Internal.h" #import "FBSDKSettings+Internal.h" #import "FBSDKSwizzler.h" #import "Monitoring/FBSDKMonitorHeaders.h" #import "Network/FBSDKGraphRequest+Internal.h" #import "Network/FBSDKGraphRequestConnection+Internal.h" #import "Network/FBSDKGraphRequestMetadata.h" + #import "Network/FBSDKGraphRequestPiggybackManager.h" #import "ServerConfiguration/FBSDKDialogConfiguration.h" #import "ServerConfiguration/FBSDKGateKeeperManager.h" #import "ServerConfiguration/FBSDKServerConfiguration.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h index 92f1dac3f8..0e85dd3aa0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h @@ -21,7 +21,6 @@ #if !TARGET_OS_TV #import "FBSDKCoreKit+Internal.h" - #import "FBSDKProfile.h" NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h index 388773a43b..a9496c50f2 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfilePictureView+Internal.h @@ -16,7 +16,7 @@ // 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 "FBSDKProfilePictureView.h" +#import "FBSDKCoreKit+Internal.h" #import "TargetConditionals.h" #if !TARGET_OS_TV diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h index 313c9d4e37..97cda0957c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h @@ -16,8 +16,8 @@ // 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 "../FBSDKLoginKit.h" #import "FBSDKLoginCompletion+Internal.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" +#import "FBSDKLoginManagerLogger.h" #import "FBSDKLoginUtility.h" diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m index b4fd34b75c..c48fd7a0ad 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m @@ -23,6 +23,7 @@ #import "_FBSDKLoginRecoveryAttempter.h" #import "FBSDKLoginKit+Internal.h" + #import "FBSDKLoginManagerLoginResult+Internal.h" @implementation _FBSDKLoginRecoveryAttempter From 970c06183411e6a53d6f78cdf10675cd0221db42 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 4 Nov 2020 18:10:32 -0800 Subject: [PATCH 070/227] Fix compiler warnings for UshbaKit build Summary: Fix compiler warnings for new build mostly related to type-checking and nullability. Reviewed By: robtimp Differential Revision: D24695332 fbshipit-source-id: 27e496a90e90915d4f028b5d6c1a59c518907bae --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 14 ++++++-------- .../FBSDKCoreKit/Internal/FBSDKProfile+Internal.h | 2 ++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index 13e058fd8b..a0cebd3dcd 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -194,14 +194,6 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:self.refreshDate forKey:FBSDKPROFILE_REFRESHDATE_KEY]; } - #pragma mark - Private - -+ (void)observeChangeAccessTokenChange:(NSNotification *)notification -{ - FBSDKAccessToken *token = notification.userInfo[FBSDKAccessTokenChangeNewKey]; - [self loadProfileWithToken:token completion:NULL]; -} - @end @implementation FBSDKProfile (Internal) @@ -342,6 +334,12 @@ + (void)loadProfileWithToken:(FBSDKAccessToken *)token } } ++ (void)observeChangeAccessTokenChange:(NSNotification *)notification +{ + FBSDKAccessToken *token = notification.userInfo[FBSDKAccessTokenChangeNewKey]; + [self loadProfileWithToken:token completion:NULL]; +} + #pragma clang diagnostic pop @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h index 0e85dd3aa0..04bc662c6c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h @@ -42,6 +42,8 @@ typedef void (^FBSDKParseProfileBlock)(id result, FBSDKProfile *_Nonnull *_Nulla + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(_Nullable FBSDKProfileBlock)completion; ++ (void)observeChangeAccessTokenChange:(NSNotification *)notification; + @end NS_ASSUME_NONNULL_END From 1053abf5b33a2006cd2c9c5699c3387e40c97150 Mon Sep 17 00:00:00 2001 From: Stan Wu Date: Wed, 4 Nov 2020 23:42:57 -0800 Subject: [PATCH 071/227] Expose a few functions in FBSDKUserDataStore as public (#1557) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1557 As title Reviewed By: Oliverccccct, tianqibt, KylinChang Differential Revision: D24723890 fbshipit-source-id: dff26144a4b7c0515423e58b42c69d2a82543f53 --- FBSDKCoreKit.podspec | 1 + .../FBSDKCoreKit.xcodeproj/project.pbxproj | 22 +++++- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 37 ++++------ .../Internal/AAM/FBSDKMetadataIndexer.m | 10 +++ .../FBSDKCoreKit_Basics/FBSDKUserDataStore.m | 48 ++++++++---- .../include/FBSDKUserDataStore+Internal.h | 35 +++++++++ .../include/FBSDKUserDataStore.h | 73 ++++++++++++++----- 7 files changed, 169 insertions(+), 57 deletions(-) create mode 100644 Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore+Internal.h diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index 941e1df5c8..89442bf543 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -48,6 +48,7 @@ Pod::Spec.new do |s| s.subspec 'Basics' do |ss| ss.source_files = 'Sources/FBSDKCoreKit_Basics/**/*.{h,m}' + ss.private_header_files = 'Sources/FBSDKCoreKit_Basics/**/*+Internal.h' ss.library = 'z' end diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index ab153d0d9f..4723ebdcf3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -747,7 +747,7 @@ C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; C57044D124E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; C57044D224E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; - C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; + C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C57044CD24E26678009637AD /* FBSDKUserDataStore.h */; }; @@ -771,6 +771,14 @@ C5D25D3721795B790037B13D /* FBSDKCodelessIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = C5D25D3421795B790037B13D /* FBSDKCodelessIndexer.h */; }; C5D25D3821795B790037B13D /* FBSDKCodelessIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = C5D25D3521795B790037B13D /* FBSDKCodelessIndexer.m */; }; C5D25D3921795B790037B13D /* FBSDKCodelessIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = C5D25D3521795B790037B13D /* FBSDKCodelessIndexer.m */; }; + C5EAFA5E255283C100458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFA9B25528EA300458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFAA925528EAE00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFAB725528EAF00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFAB825528EB000458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFAC625528EB100458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFAC725528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; + C5EAFAD525528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; C5F6EC861FA24FAF009EB258 /* FBSDKPaymentObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */; }; C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */; }; E4416C0123F61902009CCBFA /* FBSDKModelParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */; }; @@ -1516,6 +1524,7 @@ C5C7B74922D84F64004A5A0C /* FBSDKFeatureManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKFeatureManager.m; sourceTree = ""; }; C5D25D3421795B790037B13D /* FBSDKCodelessIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCodelessIndexer.h; sourceTree = ""; }; C5D25D3521795B790037B13D /* FBSDKCodelessIndexer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKCodelessIndexer.m; sourceTree = ""; }; + C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKUserDataStore+Internal.h"; sourceTree = ""; }; C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPaymentObserverTests.m; sourceTree = ""; }; C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterTests.m; sourceTree = ""; }; E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKModelParser.h; sourceTree = ""; }; @@ -2660,6 +2669,7 @@ F4A11B4724E36E5200D4C010 /* include */ = { isa = PBXGroup; children = ( + C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */, F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */, F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */, F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */, @@ -2833,6 +2843,7 @@ F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */, F4D8D8DF2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */, 814AC8271D1B528900D61E6C /* FBSDKDeviceButton.h in Headers */, + C5EAFAB725528EAF00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, F42004922416C30300AD7006 /* FBSDKMonitor.h in Headers */, F468B26724C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */, 814AC8291D1B528900D61E6C /* FBSDKAccessTokenCache.h in Headers */, @@ -3035,6 +3046,7 @@ 52963AA0215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h in Headers */, C5696F78209BBC35009C931F /* FBSDKCodelessPathComponent.h in Headers */, 81B71D991D19C87400933E93 /* FBSDKGraphRequestConnection.h in Headers */, + C5EAFA9B25528EA300458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, 81B71D9A1D19C87400933E93 /* FBSDKKeychainStore.h in Headers */, 81B71D9B1D19C87400933E93 /* FBSDKTestUsersManager.h in Headers */, C5C7B74B22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */, @@ -3110,6 +3122,7 @@ C5696F87209BBC35009C931F /* FBSDKViewHierarchyMacros.h in Headers */, 52963A90215992F400C7B252 /* FBSDKAppLinkTarget.h in Headers */, C5696F83209BBC35009C931F /* FBSDKViewHierarchy.h in Headers */, + C5EAFA5E255283C100458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, 9DA81AF61AA4EF3300B9FE0B /* FBSDKProfile.h in Headers */, 5DBC72D12373793300A9D859 /* FBSDKModelManager.h in Headers */, C4FC99D9202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.h in Headers */, @@ -3221,6 +3234,7 @@ F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */, 5DB7B07E230363190012E8CB /* FBSDKInstrumentManager.h in Headers */, F42004912416C30300AD7006 /* FBSDKMonitor.h in Headers */, + C5EAFAA925528EAE00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, 9D9E16AE1CB46C8900C8B68F /* FBSDKDeviceButton.h in Headers */, F468B26624C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */, 9D6DEEB41BC23855001A94ED /* FBSDKAccessTokenCache.h in Headers */, @@ -3292,8 +3306,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */, + F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, + C5EAFAB825528EB000458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3303,6 +3318,7 @@ files = ( F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */, + C5EAFAC725528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3312,6 +3328,7 @@ files = ( F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */, + C5EAFAC625528EB100458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3321,6 +3338,7 @@ files = ( F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */, + C5EAFAD525528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index ca27e40c2c..99a7ef6dcb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -739,46 +739,37 @@ + (void)setUserEmail:(nullable NSString *)email zip:(nullable NSString *)zip country:(nullable NSString *)country { - [FBSDKUserDataStore setAndHashUserEmail:email - firstName:firstName - lastName:lastName - phone:phone - dateOfBirth:dateOfBirth - gender:gender - city:city - state:state - zip:zip - country:country]; + [FBSDKUserDataStore setUserEmail:email + firstName:firstName + lastName:lastName + phone:phone + dateOfBirth:dateOfBirth + gender:gender + city:city + state:state + zip:zip + country:country]; } + (NSString *)getUserData { - return [FBSDKUserDataStore getHashedData]; + return [FBSDKUserDataStore getUserData]; } + (void)clearUserData { - [FBSDKUserDataStore setAndHashUserEmail:nil - firstName:nil - lastName:nil - phone:nil - dateOfBirth:nil - gender:nil - city:nil - state:nil - zip:nil - country:nil]; + [FBSDKUserDataStore clearUserData]; } + (void)setUserData:(nullable NSString *)data forType:(FBSDKAppEventUserDataType)type { - [FBSDKUserDataStore setAndHashData:data forType:type]; + [FBSDKUserDataStore setUserData:data forType:type]; } + (void)clearUserDataForType:(FBSDKAppEventUserDataType)type { - [FBSDKUserDataStore clearDataForType:type]; + [FBSDKUserDataStore clearUserDataForType:type]; } + (void)updateUserProperties:(NSDictionary *)properties handler:(FBSDKGraphRequestBlock)handler diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m index db11c899d8..a54a9547bc 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/AAM/FBSDKMetadataIndexer.m @@ -30,6 +30,16 @@ #import "FBSDKCoreKit+Internal.h" +@interface FBSDKUserDataStore (Internal) + ++ (void)setInternalHashData:(nullable NSString *)hashData + forType:(FBSDKAppEventUserDataType)type; ++ (void)setEnabledRules:(NSArray *)rules; + ++ (nullable NSString *)getInternalHashedDataForType:(FBSDKAppEventUserDataType)type; + +@end + static const int FBSDKMetadataIndexerMaxTextLength = 100; static const int FBSDKMetadataIndexerMaxIndicatorLength = 100; static const int FBSDKMetadataIndexerMaxValue = 5; diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m b/Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m index e6da0e1334..f2384c4540 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKUserDataStore.m @@ -17,6 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKUserDataStore.h" +#import "FBSDKUserDataStore+Internal.h" #import "FBSDKBasicUtility.h" #import "FBSDKTypeUtility.h" @@ -55,16 +56,16 @@ + (void)initialize enabledRules = [[NSMutableSet alloc] init]; } -+ (void)setAndHashUserEmail:(nullable NSString *)email - firstName:(nullable NSString *)firstName - lastName:(nullable NSString *)lastName - phone:(nullable NSString *)phone - dateOfBirth:(nullable NSString *)dateOfBirth - gender:(nullable NSString *)gender - city:(nullable NSString *)city - state:(nullable NSString *)state - zip:(nullable NSString *)zip - country:(nullable NSString *)country ++ (void)setUserEmail:(nullable NSString *)email + firstName:(nullable NSString *)firstName + lastName:(nullable NSString *)lastName + phone:(nullable NSString *)phone + dateOfBirth:(nullable NSString *)dateOfBirth + gender:(nullable NSString *)gender + city:(nullable NSString *)city + state:(nullable NSString *)state + zip:(nullable NSString *)zip + country:(nullable NSString *)country { NSMutableDictionary *ud = [[NSMutableDictionary alloc] init]; if (email) { @@ -105,8 +106,8 @@ + (void)setAndHashUserEmail:(nullable NSString *)email }); } -+ (void)setAndHashData:(nullable NSString *)data - forType:(FBSDKAppEventUserDataType)type ++ (void)setUserData:(nullable NSString *)data + forType:(FBSDKAppEventUserDataType)type { [FBSDKUserDataStore setHashData:[FBSDKUserDataStore encryptData:data type:type] forType:type]; @@ -147,9 +148,14 @@ + (void)setEnabledRules:(NSArray *)rules } } -+ (void)clearDataForType:(FBSDKAppEventUserDataType)type ++ (void)clearUserDataForType:(FBSDKAppEventUserDataType)type +{ + [FBSDKUserDataStore setUserData:nil forType:type]; +} + ++ (NSString *)getUserData { - [FBSDKUserDataStore setAndHashData:nil forType:type]; + return [FBSDKUserDataStore getHashedData]; } + (NSString *)getHashedData @@ -168,6 +174,20 @@ + (NSString *)getHashedData return hashedUserDataString; } ++ (void)clearUserData +{ + [FBSDKUserDataStore setUserEmail:nil + firstName:nil + lastName:nil + phone:nil + dateOfBirth:nil + gender:nil + city:nil + state:nil + zip:nil + country:nil]; +} + + (NSString *)getInternalHashedDataForType:(FBSDKAppEventUserDataType)type { __block NSString *hashedData; diff --git a/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore+Internal.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore+Internal.h new file mode 100644 index 0000000000..2804ed010a --- /dev/null +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore+Internal.h @@ -0,0 +1,35 @@ +// 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 "FBSDKUserDataStore.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKUserDataStore (Internal) + ++ (void)setInternalHashData:(nullable NSString *)hashData + forType:(FBSDKAppEventUserDataType)type; ++ (void)setEnabledRules:(NSArray *)rules; + ++ (nullable NSString *)getInternalHashedDataForType:(FBSDKAppEventUserDataType)type; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h index f2e935128e..0539599351 100644 --- a/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKUserDataStore.h @@ -57,24 +57,61 @@ FOUNDATION_EXPORT FBSDKAppEventUserDataType FBSDKAppEventCountry; NS_SWIFT_NAME(UserDataStore) @interface FBSDKUserDataStore : NSObject -+ (void)setAndHashUserEmail:(nullable NSString *)email - firstName:(nullable NSString *)firstName - lastName:(nullable NSString *)lastName - phone:(nullable NSString *)phone - dateOfBirth:(nullable NSString *)dateOfBirth - gender:(nullable NSString *)gender - city:(nullable NSString *)city - state:(nullable NSString *)state - zip:(nullable NSString *)zip - country:(nullable NSString *)country; -+ (void)setAndHashData:(nullable NSString *)data - forType:(FBSDKAppEventUserDataType)type; -+ (void)setInternalHashData:(nullable NSString *)hashData - forType:(FBSDKAppEventUserDataType)type; -+ (void)setEnabledRules:(NSArray *)rules; -+ (nullable NSString *)getHashedData; -+ (nullable NSString *)getInternalHashedDataForType:(FBSDKAppEventUserDataType)type; -+ (void)clearDataForType:(FBSDKAppEventUserDataType)type; +/* + Sets custom user data to associate with all app events. All user data are hashed + and used to match Facebook user from this instance of an application. + + The user data will be persisted between application instances. + + @param email user's email + @param firstName user's first name + @param lastName user's last name + @param phone user's phone + @param dateOfBirth user's date of birth + @param gender user's gender + @param city user's city + @param state user's state + @param zip user's zip + @param country user's country + */ ++ (void)setUserEmail:(nullable NSString *)email + firstName:(nullable NSString *)firstName + lastName:(nullable NSString *)lastName + phone:(nullable NSString *)phone + dateOfBirth:(nullable NSString *)dateOfBirth + gender:(nullable NSString *)gender + city:(nullable NSString *)city + state:(nullable NSString *)state + zip:(nullable NSString *)zip + country:(nullable NSString *)country +NS_SWIFT_NAME(setUser(email:firstName:lastName:phone:dateOfBirth:gender:city:state:zip:country:)); + +/* + Returns the set user data else nil +*/ ++ (nullable NSString *)getUserData; + +/* + Clears the current user data +*/ ++ (void)clearUserData; + +/* + Sets custom user data to associate with all app events. All user data are hashed + and used to match Facebook user from this instance of an application. + + The user data will be persisted between application instances. + + @param data data + @param type data type, e.g. FBSDKAppEventEmail, FBSDKAppEventPhone + */ ++ (void)setUserData:(nullable NSString *)data + forType:(FBSDKAppEventUserDataType)type; + +/* + Clears the current user data of certain type + */ ++ (void)clearUserDataForType:(FBSDKAppEventUserDataType)type; @end From c28e3c51123359deb1e8c8188c04de6b81d0b51b Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 5 Nov 2020 11:00:52 -0800 Subject: [PATCH 072/227] Remove invalid reference to FBSDKGamingServicesKit copy-Info.plist in FBSDKGamingServicesKit.xcodeproj Summary: The FBSDKGamingServicesKit copy-Info.plist file doesn't exist so removed the invalid reference from the project file Reviewed By: joesus Differential Revision: D24751986 fbshipit-source-id: 57acfadeaadfa12db3682ea7c06f273e5431e50b --- .../FBSDKGamingServicesKit.xcodeproj/project.pbxproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj index 52b8cf25dd..87733daf9d 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj @@ -308,7 +308,6 @@ F4F7CA3D23F49C110030A346 /* FBSDKCoreKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FBSDKCoreKit.xcodeproj; path = ../FBSDKCoreKit/FBSDKCoreKit.xcodeproj; sourceTree = ""; }; F4F7CA6823F49D1B0030A346 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; F4F7CA9923F49D6F0030A346 /* FBSDKGamingServicesKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKGamingServicesKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F4F7CA9A23F49D6F0030A346 /* FBSDKGamingServicesKit copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "FBSDKGamingServicesKit copy-Info.plist"; path = "/Users/joesusnick/fbsource/fbobjc/ios-sdk/FBSDKGamingServicesKit/FBSDKGamingServicesKit copy-Info.plist"; sourceTree = ""; }; F4F7CAA123F4A1390030A346 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -377,7 +376,6 @@ F46A224124D9F14D005878A8 /* FBSDKGamingServicesKitTests */, F4F7CA3223F498ED0030A346 /* Frameworks */, F4F7CA9923F49D6F0030A346 /* FBSDKGamingServicesKit.framework */, - F4F7CA9A23F49D6F0030A346 /* FBSDKGamingServicesKit copy-Info.plist */, F46A224024D9F14D005878A8 /* FBSDKGamingServicesKitTests.xctest */, ); sourceTree = ""; From 508983de98fc5ffecc1b2e6642be94730b76104b Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 5 Nov 2020 12:57:35 -0800 Subject: [PATCH 073/227] Remove the line from .gitattributes that treats pbxproj files as binary (#1561) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1561 The "*.pbxproj binary merge=union" line was added in a prior commit (D18655686 (https://github.com/facebook/facebook-ios-sdk/commit/c54b37a25c5b407959b6c087931bb8c34bb1c163)) as a way to automatically resolve merge conflicts in Xcode project files based on this article: https://thoughtbot.com/blog/xcode-and-git-bridging-the-gap The article doesn't specify why the pbxproj file should be treated as a binary, however one side effect is that the `git diff` command will no longer show changes in the project file. For example if a project file is changed it will just show the following: ``` Binary files a/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj and b/FBSDKGamingServicesKit/FBSDKGamingServicesKit.xcodeproj/project.pbxproj differ ``` It doesn't seem like the binary attribute is necessary to use the merge=union strategy as the following article https://roadfiresoftware.com/2015/09/automatically-resolving-git-merge-conflicts-in-xcodes-project-pbxproj/ However I'm not convinced that we need the merge=union strategy since resolving conflicts in project files is fairly simple and mostly only occurs when two files have been added in the same location in the project. Even then the conflict is easy to resolve. Furthermore it doesn't look like this strategy works reliably. This StackOverflow answer indicates that the user tried this strategy and ended up removing it since it didn't work in about 1 of 4 cases: https://stackoverflow.com/a/18275082. (When it doesn't work it will prevent the project from being opened at all and would have to fixed manually anyway). And finally, if there is a conflict between two similarly named files that have been added to the location in the project file, resolving the conflict manually allows the alphabetical order of the files to be corrected if needed. Reviewed By: joesus Differential Revision: D24762186 fbshipit-source-id: 5454843d193f401f9b95c31898ad1e58a4c1a03e --- .gitattributes | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 983658214c..4712d86ebc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ *.strings diff=localizablestrings -*.pbxproj binary merge=union From 13eed5258d991a1891d4b12a589a5068b92da570 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 5 Nov 2020 16:45:48 -0800 Subject: [PATCH 074/227] Adding Unit test target to Ushba Workspace Summary: Mostly fixes header imports so that they'll work with Xcode and Buck. This required removing some headers and using internal categories instead. Reviewed By: jvlyn Differential Revision: D24739770 fbshipit-source-id: 03e6e18cc4f71161dc3ec6a5b2e530fea6ba7faa --- FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 1 + 1 file changed, 1 insertion(+) diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 77aeb30541..2860ec4fb8 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -22,6 +22,7 @@ #import +#import "FBSDKLoginManager.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLoginResult.h" #import "FBSDKLoginUtilityTests.h" From b3e8c0ac2956b846879b038acdf7eaeee9c736a6 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 5 Nov 2020 17:14:54 -0800 Subject: [PATCH 075/227] Remove the "Recovered References" group from the FBSDKCoreKit project in Xcode Summary: I checked and all of these files are already present under FBSDKCoreKit/Basics (and the headers are present under FBSDKCoreKit/Basics/include). Reviewed By: joesus Differential Revision: D24770723 fbshipit-source-id: ff64cc9f80cf1754d2a824116076eb63a1df55be --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 78 ------------------- 1 file changed, 78 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 4723ebdcf3..a6738a613e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -841,19 +841,6 @@ F462DC0023B9575100FFCECA /* FBSDKServerConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8917C4AB1B7A46C800B0B96B /* FBSDKServerConfiguration+Internal.h */; }; F462DC0123B9578E00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D69FC421AA66BBC0068EC76 /* FBSDKGraphRequestConnection+Internal.h */; }; F462DC0223B9578F00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D69FC421AA66BBC0068EC76 /* FBSDKGraphRequestConnection+Internal.h */; }; - F468B22E24C2399900979F8D /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */; }; - F468B22F24C2399900979F8D /* FBSDKBasicUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */; }; - F468B23424C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; - F468B23524C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; - F468B23624C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; - F468B23724C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */; }; - F468B23E24C2399900979F8D /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22024C2399800979F8D /* FBSDKCrashObserving.h */; }; - F468B23F24C2399900979F8D /* FBSDKCrashObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22024C2399800979F8D /* FBSDKCrashObserving.h */; }; - F468B24424C2399900979F8D /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22124C2399800979F8D /* FBSDKTypeUtility.h */; }; - F468B24624C2399900979F8D /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22124C2399800979F8D /* FBSDKTypeUtility.h */; }; - F468B24724C2399900979F8D /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22124C2399800979F8D /* FBSDKTypeUtility.h */; }; - F468B26624C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */; }; - F468B26724C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */; }; F468B2A024C2457000979F8D /* FBSDKRestrictiveData.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */; }; F468B2A124C2457000979F8D /* FBSDKRestrictiveData.h in Headers */ = {isa = PBXBuildFile; fileRef = F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */; }; F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */; }; @@ -986,10 +973,6 @@ F4FE998424D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998524D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; F4FE998624D906BA008879A4 /* FBSDKJSONValue.m in Sources */ = {isa = PBXBuildFile; fileRef = F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */; }; - F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; - F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; - F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; - F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */ = {isa = PBXBuildFile; fileRef = F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */; }; F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */; }; F916581624F6BB4D00BB759A /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9DE56B824F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.h */; }; F916581724F6BB5100BB759A /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9DE56B924F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m */; }; @@ -1551,19 +1534,6 @@ F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationManagerTests.m; sourceTree = ""; }; F43960CE2425513100C1868F /* FakeMonitorStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeMonitorStore.h; sourceTree = ""; }; F43960CF2425513100C1868F /* FakeMonitorStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeMonitorStore.m; sourceTree = ""; }; - F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKBasicUtility.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKBasicUtility.h; sourceTree = ""; }; - F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCoreKit_Basics.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCoreKit_Basics.h; sourceTree = ""; }; - F468B22024C2399800979F8D /* FBSDKCrashObserving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKCrashObserving.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCrashObserving.h; sourceTree = ""; }; - F468B22124C2399800979F8D /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKTypeUtility.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKTypeUtility.h; sourceTree = ""; }; - F468B22224C2399800979F8D /* FBSDKLibAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKLibAnalyzer.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKLibAnalyzer.m; sourceTree = ""; }; - F468B22324C2399800979F8D /* FBSDKURLSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKURLSession.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSession.m; sourceTree = ""; }; - F468B22424C2399800979F8D /* FBSDKCrashHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKCrashHandler.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKCrashHandler.m; sourceTree = ""; }; - F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKLibAnalyzer.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKLibAnalyzer.h; sourceTree = ""; }; - F468B22624C2399900979F8D /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKURLSessionTask.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSessionTask.h; sourceTree = ""; }; - F468B22724C2399900979F8D /* FBSDKURLSessionTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKURLSessionTask.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSessionTask.m; sourceTree = ""; }; - F468B22824C2399900979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKTypeUtility.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKTypeUtility.m; sourceTree = ""; }; - F468B22924C2399900979F8D /* FBSDKBasicUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKBasicUtility.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKBasicUtility.m; sourceTree = ""; }; - F468B22A24C2399900979F8D /* FBSDKURLSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKURLSession.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKURLSession.h; sourceTree = ""; }; F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; @@ -1633,13 +1603,8 @@ F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleRawRemotePermissions.swift; sourceTree = ""; }; F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationCenterSpy.h; sourceTree = ""; }; F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationCenterSpy.m; sourceTree = ""; }; - F4F98BB324CB77F400F0D6EC /* FBSDKSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKSafeCast.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.h; sourceTree = ""; }; - F4F98BC224CB77F400F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCast.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.m; sourceTree = ""; }; - F4F98C0F24CB7F6D00F0D6EC /* FBSDKSafeCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKSafeCast.h; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.h; sourceTree = ""; }; - F4F98C1024CB7F6D00F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCast.m; path = ../../../FBSDKCoreKit_Basics/Sources/FBSDKSafeCast.m; sourceTree = ""; }; F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSafeCast.m; sourceTree = ""; }; F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValue.m; sourceTree = ""; }; - F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKJSONValue.h; path = ../../../Sources/FBSDKCoreKit_Basics/FBSDKJSONValue.h; sourceTree = ""; }; F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkConversionConfigurationTests.m; sourceTree = ""; }; F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkRuleTests.m; sourceTree = ""; }; F93680D4249D490600446E35 /* FBSDKSettingsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSettingsTests.m; path = Internal/FBSDKSettingsTests.m; sourceTree = ""; }; @@ -2263,7 +2228,6 @@ 893F44A31A644536001DB0B6 /* Frameworks */, 9D2697481A5DF40700143BFC /* Products */, 9D222B581A670D1300832F83 /* Submodules */, - F468B2B324C24A9500979F8D /* Recovered References */, ); indentWidth = 2; sourceTree = ""; @@ -2631,31 +2595,6 @@ path = Monitoring; sourceTree = ""; }; - F468B2B324C24A9500979F8D /* Recovered References */ = { - isa = PBXGroup; - children = ( - F468B22324C2399800979F8D /* FBSDKURLSession.m */, - F468B22924C2399900979F8D /* FBSDKBasicUtility.m */, - F468B22724C2399900979F8D /* FBSDKURLSessionTask.m */, - F468B22424C2399800979F8D /* FBSDKCrashHandler.m */, - F468B22824C2399900979F8D /* FBSDKTypeUtility.m */, - F468B22224C2399800979F8D /* FBSDKLibAnalyzer.m */, - F468B22A24C2399900979F8D /* FBSDKURLSession.h */, - F468B22524C2399800979F8D /* FBSDKLibAnalyzer.h */, - F468B21E24C2399800979F8D /* FBSDKBasicUtility.h */, - F468B22624C2399900979F8D /* FBSDKURLSessionTask.h */, - F468B21F24C2399800979F8D /* FBSDKCoreKit_Basics.h */, - F468B22124C2399800979F8D /* FBSDKTypeUtility.h */, - F468B22024C2399800979F8D /* FBSDKCrashObserving.h */, - F4F98BC224CB77F400F0D6EC /* FBSDKSafeCast.m */, - F4F98BB324CB77F400F0D6EC /* FBSDKSafeCast.h */, - F4F98C1024CB7F6D00F0D6EC /* FBSDKSafeCast.m */, - F4F98C0F24CB7F6D00F0D6EC /* FBSDKSafeCast.h */, - F4FE997E24D906B9008879A4 /* FBSDKJSONValue.h */, - ); - name = "Recovered References"; - sourceTree = ""; - }; F487DBCA231EBD8B008416A9 /* Swift */ = { isa = PBXGroup; children = ( @@ -2819,7 +2758,6 @@ files = ( 814AC8171D1B528900D61E6C /* FBSDKKeychainStoreViaBundleID.h in Headers */, 5D6DF16D2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, - F468B23724C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, 814AC8181D1B528900D61E6C /* FBSDKError.h in Headers */, 814AC8191D1B528900D61E6C /* FBSDKButton.h in Headers */, 814AC81A1D1B528900D61E6C /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -2845,14 +2783,12 @@ 814AC8271D1B528900D61E6C /* FBSDKDeviceButton.h in Headers */, C5EAFAB725528EAF00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, F42004922416C30300AD7006 /* FBSDKMonitor.h in Headers */, - F468B26724C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */, 814AC8291D1B528900D61E6C /* FBSDKAccessTokenCache.h in Headers */, 814AC82A1D1B528900D61E6C /* FBSDKAppEventsState.h in Headers */, 814AC82B1D1B528900D61E6C /* FBSDKAppEvents+Internal.h in Headers */, 52D4F0D51D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */, 814AC82C1D1B528900D61E6C /* FBSDKTestUsersManager.h in Headers */, 814AC82D1D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, - F468B22F24C2399900979F8D /* FBSDKBasicUtility.h in Headers */, 814AC82E1D1B528900D61E6C /* FBSDKGraphRequestBody.h in Headers */, 033429CA208951E400C94913 /* FBSDKAccessTokenExpirer.h in Headers */, 814AC8301D1B528900D61E6C /* FBSDKGraphRequestDataAttachment.h in Headers */, @@ -2874,9 +2810,7 @@ F4A52B01242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */, 814AC83C1D1B528900D61E6C /* FBSDKUIUtility.h in Headers */, 814AC83D1D1B528900D61E6C /* FBSDKAppEvents.h in Headers */, - F468B23F24C2399900979F8D /* FBSDKCrashObserving.h in Headers */, F9FD9A6521659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */, - F468B24724C2399900979F8D /* FBSDKTypeUtility.h in Headers */, 814AC83E1D1B528900D61E6C /* FBSDKErrorConfiguration.h in Headers */, 814AC83F1D1B528900D61E6C /* FBSDKConstants.h in Headers */, 814AC8401D1B528900D61E6C /* FBSDKMath.h in Headers */, @@ -3029,7 +2963,6 @@ 81B71D8D1D19C87400933E93 /* FBSDKGraphRequestDataAttachment.h in Headers */, 81B71D901D19C87400933E93 /* FBSDKSettings.h in Headers */, 81B71D911D19C87400933E93 /* FBSDKServerConfiguration.h in Headers */, - F468B23524C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, C57044D024E26678009637AD /* FBSDKUserDataStore.h in Headers */, BFC02456237B6B9300A596EE /* FBSDKModelRuntime.hpp in Headers */, 81B71D921D19C87400933E93 /* FBSDKAppEventsStateManager.h in Headers */, @@ -3176,7 +3109,6 @@ 89830F2F1A7805E100226ABB /* FBSDKServerConfiguration.h in Headers */, 9D0BC15F1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.h in Headers */, 9D3AF4601A9EC24800EEF724 /* FBSDKErrorRecoveryConfiguration.h in Headers */, - F468B23424C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, FD9E154D23777AC900A005EC /* FBSDKModelRuntime.hpp in Headers */, 9D0BC1571A8D23E200BE8BA4 /* FBSDKAppEvents.h in Headers */, C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */, @@ -3190,7 +3122,6 @@ C5D25D3621795B790037B13D /* FBSDKCodelessIndexer.h in Headers */, F4210E2E241B00790061F56D /* FBSDKMethodUsageMonitor.h in Headers */, 5D6DF16A2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, - F468B24424C2399900979F8D /* FBSDKTypeUtility.h in Headers */, 52963A88215992F400C7B252 /* FBSDKAppLinkReturnToRefererController.h in Headers */, C5696F77209BBC35009C931F /* FBSDKCodelessPathComponent.h in Headers */, 9DC6589E1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.h in Headers */, @@ -3210,7 +3141,6 @@ files = ( 9D6DEECE1BC23A56001A94ED /* FBSDKKeychainStoreViaBundleID.h in Headers */, 5D6DF16C2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, - F468B23624C2399900979F8D /* FBSDKCoreKit_Basics.h in Headers */, 9DB0FA901BC22AE9005EB8B1 /* FBSDKError.h in Headers */, 9D65383B1BF413B3008A08E9 /* FBSDKButton.h in Headers */, 9D6DEEB91BC2389F001A94ED /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -3236,14 +3166,12 @@ F42004912416C30300AD7006 /* FBSDKMonitor.h in Headers */, C5EAFAA925528EAE00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, 9D9E16AE1CB46C8900C8B68F /* FBSDKDeviceButton.h in Headers */, - F468B26624C2399900979F8D /* FBSDKLibAnalyzer.h in Headers */, 9D6DEEB41BC23855001A94ED /* FBSDKAccessTokenCache.h in Headers */, 9D6DEEB21BC23838001A94ED /* FBSDKAppEventsState.h in Headers */, 9DB0FA8A1BC1CED0005EB8B1 /* FBSDKAppEvents+Internal.h in Headers */, 52D4F0D41D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */, 9D6DEEDB1BC24295001A94ED /* FBSDKTestUsersManager.h in Headers */, 9D6DEED11BC23A93001A94ED /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, - F468B22E24C2399900979F8D /* FBSDKBasicUtility.h in Headers */, 9DB0FAA01BC22CF5005EB8B1 /* FBSDKGraphRequestBody.h in Headers */, 033429C9208951E400C94913 /* FBSDKAccessTokenExpirer.h in Headers */, 9DB0FAA21BC22D00005EB8B1 /* FBSDKGraphRequestDataAttachment.h in Headers */, @@ -3265,9 +3193,7 @@ 9D6DEEAB1BC236D6001A94ED /* FBSDKAppEventsDeviceInfo.h in Headers */, 9D65383F1BF44F9F008A08E9 /* FBSDKUIUtility.h in Headers */, 9DB0FA8B1BC1CED8005EB8B1 /* FBSDKAppEvents.h in Headers */, - F468B23E24C2399900979F8D /* FBSDKCrashObserving.h in Headers */, F9FD9A6421659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */, - F468B24624C2399900979F8D /* FBSDKTypeUtility.h in Headers */, 9DB0FA9A1BC22BE5005EB8B1 /* FBSDKErrorConfiguration.h in Headers */, 9DB0FA8E1BC22ACA005EB8B1 /* FBSDKConstants.h in Headers */, 9D6DEEBC1BC238EE001A94ED /* FBSDKMath.h in Headers */, @@ -3307,7 +3233,6 @@ buildActionMask = 2147483647; files = ( C57044D324E26678009637AD /* FBSDKUserDataStore.h in Headers */, - F4FE998B24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C5EAFAB825528EB000458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3316,7 +3241,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4FE998D24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D524E26678009637AD /* FBSDKUserDataStore.h in Headers */, C5EAFAC725528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); @@ -3326,7 +3250,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4FE998C24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D424E26678009637AD /* FBSDKUserDataStore.h in Headers */, C5EAFAC625528EB100458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); @@ -3336,7 +3259,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F4FE998E24D906BA008879A4 /* FBSDKJSONValue.h in Headers */, C57044D624E26678009637AD /* FBSDKUserDataStore.h in Headers */, C5EAFAD525528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, ); From 661e513485ac147e9dd8a9f4b4d597c80087036f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 5 Nov 2020 19:25:48 -0800 Subject: [PATCH 076/227] Unit test hardening - FBSDKCrashShield Summary: Adds more coverage and prevents the unit tests from making network calls. Reviewed By: jawwad Differential Revision: D24634018 fbshipit-source-id: dfc201da7bd3d6a2300d9400960be1290696225d --- .../Instrument/CrashReport/FBSDKCrashShield.m | 8 +- .../Internal/Helpers/FBSDKTestCase.h | 18 ++ .../Internal/Helpers/FBSDKTestCase.m | 39 ++++ .../Instrument/FBSDKCrashShieldTests.m | 212 +++++++++++++++--- 4 files changed, 249 insertions(+), 28 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m index 0b38e76d2f..d529e63d3b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m @@ -111,9 +111,10 @@ + (void)analyze:(NSArray *> *)crashLogs + (nullable NSString *)getFeature:(NSArray *)callstack { + NSArray *validCallstack = [FBSDKTypeUtility arrayValue:callstack]; NSArray *featureNames = _featureMapping.allKeys; - for (NSString *entry in callstack) { - NSString *className = [self getClassName:entry]; + for (NSString *entry in validCallstack) { + NSString *className = [self getClassName:[FBSDKTypeUtility stringValue:entry]]; for (NSString *featureName in featureNames) { NSArray *classArray = [FBSDKTypeUtility dictionary:_featureMapping objectForKey:featureName ofType:NSObject.class]; if (className && [classArray containsObject:className]) { @@ -126,7 +127,8 @@ + (nullable NSString *)getFeature:(NSArray *)callstack + (nullable NSString *)getClassName:(NSString *)entry { - NSArray *items = [entry componentsSeparatedByString:@" "]; + NSString *validEntry = [FBSDKTypeUtility stringValue:entry]; + NSArray *items = [validEntry componentsSeparatedByString:@" "]; NSString *className = nil; // parse class name only from an entry in format "-[className functionName]+offset" // or "+[className functionName]+offset" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 5b453197fa..9380e952e7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -124,6 +124,12 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKGraphRequestConnection` class mock between tests @property (nullable, nonatomic, assign) id graphRequestConnectionClassMock; +/// Used for sharing a `FBSDKCrashShield` class mock between tests +@property (nullable, nonatomic, assign) id crashShieldClassMock; + +/// Used for sharing a `NSDate` class mock between tests +@property (nullable, nonatomic, assign) id nsDateClassMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; @@ -230,6 +236,18 @@ Also, to get a better understanding of mocking, please read the documentation at /// from hitting the network while proper mocks are being written. - (void)stubAllocatingGraphRequestConnection; +/// Stubs `FBSDKFeatureManager.disableFeature:` for the provided feature +- (void)stubDisableFeature:(NSString *)feature; + +/// Stubs `FBSDKSettings.isDataProcessingRestricted` and returns the provided value +- (void)stubIsDataProcessingRestricted:(BOOL)isRestricted; + +/// Stubs `NSDate`'s `date` method to return the shared date mock +- (void)stubDate; + +/// Stubs `NSDate`'s `timeIntervalSince1970` method and returns the provided time interval +- (void)stubTimeIntervalSince1970WithTimeInterval:(NSTimeInterval)interval; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 57e93fb865..eeba7ad2d7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -29,6 +29,7 @@ #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" +#import "FBSDKCrashShield.h" #import "FBSDKFeatureManager.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKKeychainStore.h" @@ -84,6 +85,8 @@ - (void)setUp [self setUpModelManagerClassMock]; [self setUpGraphRequestPiggybackManagerMock]; [self setUpGraphRequestConnectionClassMock]; + [self setUpCrashShieldClassMock]; + [self setUpNSDateClassMock]; } - (void)tearDown @@ -158,6 +161,12 @@ - (void)tearDown [_graphRequestConnectionClassMock stopMocking]; _graphRequestConnectionClassMock = nil; + + [_crashShieldClassMock stopMocking]; + _crashShieldClassMock = nil; + + [_nsDateClassMock stopMocking]; + _nsDateClassMock = nil; } - (void)setUpSettingsMock @@ -276,6 +285,16 @@ - (void)setUpGraphRequestConnectionClassMock self.graphRequestConnectionClassMock = OCMClassMock(FBSDKGraphRequestConnection.class); } +- (void)setUpCrashShieldClassMock +{ + self.crashShieldClassMock = OCMClassMock(FBSDKCrashShield.class); +} + +- (void)setUpNSDateClassMock +{ + self.nsDateClassMock = OCMClassMock(NSDate.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID @@ -454,6 +473,26 @@ - (void)stubAllocatingGraphRequestConnection OCMStub(ClassMethod([_graphRequestConnectionClassMock alloc])); } +- (void)stubDisableFeature:(NSString *)feature +{ + OCMStub(ClassMethod([_featureManagerClassMock disableFeature:feature])); +} + +- (void)stubIsDataProcessingRestricted:(BOOL)isRestricted +{ + OCMStub(ClassMethod([_settingsClassMock isDataProcessingRestricted])).andReturn(isRestricted); +} + +- (void)stubDate +{ + OCMStub([_nsDateClassMock date]).andReturn(_nsDateClassMock); +} + +- (void)stubTimeIntervalSince1970WithTimeInterval:(NSTimeInterval)interval +{ + OCMStub([_nsDateClassMock timeIntervalSince1970]).andReturn(interval); +} + // MARK: - Helpers - (id)nsNullIfNil:(id)nilValue diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m index 7cbe338d1d..1755b7053f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m @@ -19,11 +19,12 @@ #import #import +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKCrashShield.h" #import "FBSDKFeatureManager.h" #import "FBSDKTestCase.h" -@interface FBSDKCrashShield () +@interface FBSDKCrashShield (Testing) + (nullable NSString *)getFeature:(NSArray *)callstack; + (nullable NSString *)getClassName:(NSString *)entry; @@ -35,13 +36,7 @@ @interface FBSDKCrashShieldTests : FBSDKTestCase @implementation FBSDKCrashShieldTests -- (void)setUp -{ - [super setUp]; - - // This should be removed when these tests are updated to check the actual requests that are created - [self stubAllocatingGraphRequestConnection]; -} +// MARK: - Get Feature - (void)testGetFeature { @@ -83,6 +78,25 @@ - (void)testGetFeature XCTAssertNil(featureName5); } +- (void)testParsingFeatureFromValidCallstack +{ + NSArray *callstack = @[@"(4 DEV METHODS)", + @"+[FBSDKVideoUploader crash]+84", + @"(22 DEV METHODS)"]; + for (int i = 0; i < 100; i++) { + [FBSDKCrashShield getFeature:[Fuzzer randomizeWithJson:callstack]]; + } +} + +- (void)testParsingFeatureFromGarbage +{ + for (int i = 0; i < 100; i++) { + [FBSDKCrashShield getFeature:Fuzzer.random]; + } +} + +// MARK: - Get Class Name + - (void)testGetClassName { // class method @@ -101,32 +115,169 @@ - (void)testGetClassName XCTAssertNil(className3); } -- (void)testAnalyzeCrashCausedByCoreKitFeature +- (void)testParsingClassName { - NSArray *> *crashLogs = [FBSDKCrashShieldTests getCrashLogs:YES]; - id mockCrashShield = [OCMockObject niceMockForClass:[FBSDKCrashShield class]]; - id mockFeatureManager = [OCMockObject niceMockForClass:[FBSDKFeatureManager class]]; + for (int i = 0; i < 100; i++) { + [FBSDKCrashShield getClassName:Fuzzer.random]; + } +} - [[[mockCrashShield expect] andForwardToRealObject] getFeature:crashLogs[0][@"callstack"]]; - [[[mockFeatureManager expect] andForwardToRealObject] disableFeature:@"CodelessEvents"]; +- (void)testAnalyzingEmptyCrashLogs +{ + // Should not create a graph request for posting a non-existent crash + OCMReject(ClassMethod([self.graphRequestMock alloc])); - [FBSDKCrashShield analyze:crashLogs]; + [FBSDKCrashShield analyze:@[]]; +} - [mockFeatureManager verify]; - [mockCrashShield verify]; +- (void)testAnalyzingInvalidCrashLogs +{ + for (int i = 0; i < 100; i++) { + [FBSDKCrashShield getClassName:[Fuzzer randomizeWithJson:self.coreKitCrashLogs]]; + } } -- (void)testAnalyzeCrashCausedByNonCoreKitFeature +// MARK: - Analyze: Disabling Features + +- (void)testDisablingCoreKitFeatureWithDataProcessingRestricted { - NSArray *> *crashLogs = [FBSDKCrashShieldTests getCrashLogs:NO]; - id mockCrashShield = [OCMockObject niceMockForClass:[FBSDKCrashShield class]]; - id mockFeatureManager = [OCMockObject niceMockForClass:[FBSDKFeatureManager class]]; + [self stubIsDataProcessingRestricted:YES]; + [self preventGraphRequest]; - [[[mockCrashShield expect] andForwardToRealObject] getFeature:crashLogs[0][@"callstack"]]; - [[[mockFeatureManager reject] andForwardToRealObject] disableFeature:[OCMArg any]]; + [FBSDKCrashShield analyze:self.coreKitCrashLogs]; - [FBSDKCrashShield analyze:crashLogs]; - [mockCrashShield verify]; + // Should disable a core feature found in a crashlog regardless of data processing permissions + OCMVerify(ClassMethod([self.featureManagerClassMock disableFeature:@"CodelessEvents"])); +} + +- (void)testDisablingNonCoreKitFeatureWithDataProcessingRestricted +{ + [self stubIsDataProcessingRestricted:YES]; + [self preventGraphRequest]; + + // Should not disable a non core feature found in a crashlog regardless of data processing permissions + OCMReject(ClassMethod([self.featureManagerClassMock disableFeature:OCMArg.any])); + + [FBSDKCrashShield analyze:self.nonCoreKitCrashLogs]; +} + +- (void)testDisablingCoreKitFeatureWithDataProcessingUnrestricted +{ + [self stubIsDataProcessingRestricted:NO]; + [self preventGraphRequest]; + + [FBSDKCrashShield analyze:self.coreKitCrashLogs]; + + // Should disable a core feature found in a crashlog regardless of data processing permissions + OCMVerify(ClassMethod([self.featureManagerClassMock disableFeature:@"CodelessEvents"])); +} + +- (void)testDisablingNonCoreKitFeatureWithDataProcessingUnrestricted +{ + [self stubIsDataProcessingRestricted:NO]; + [self preventGraphRequest]; + + // Should not disable a non core feature found in a crashlog regardless of data processing permissions + OCMReject(ClassMethod([self.featureManagerClassMock disableFeature:OCMArg.any])); + + [FBSDKCrashShield analyze:self.nonCoreKitCrashLogs]; +} + +// MARK: - Analyze: Posting Crash Logs + +- (void)testPostingCoreKitCrashLogsWithDataProcessingRestricted +{ + [self stubIsDataProcessingRestricted:YES]; + + OCMReject([self.graphRequestMock alloc]); + + [FBSDKCrashShield analyze:self.coreKitCrashLogs]; +} + +- (void)testPostingNonCoreKitCrashLogsWithDataProcessingRestricted +{ + [self stubIsDataProcessingRestricted:YES]; + + OCMReject([self.graphRequestMock alloc]); + + [FBSDKCrashShield analyze:self.nonCoreKitCrashLogs]; +} + +- (void)testPostingCoreKitCrashLogsWithDataProcessingUnrestricted +{ + // Setup + [self stubIsDataProcessingRestricted:NO]; + [self stubAppID:self.appID]; + [self stubDate]; + [self stubTimeIntervalSince1970WithTimeInterval:10]; + + [self addInitializerStubsToGraphRequestMock]; + OCMExpect([self.graphRequestMock startWithCompletionHandler:nil]); + + // Act + [FBSDKCrashShield analyze:self.coreKitCrashLogs]; + + // Assert + NSString *expectedPath = [NSString stringWithFormat:@"%@/instruments", self.appID]; + NSDictionary *expectedParameters = @{ + @"crash_shield" : [self encodedCoreKitFeatureDataWithTimestamp:@"10"] + }; + OCMVerify( + [self.graphRequestMock initWithGraphPath:expectedPath + parameters:expectedParameters + HTTPMethod:FBSDKHTTPMethodPOST] + ); + OCMVerify([self.graphRequestMock startWithCompletionHandler:nil]); +} + +- (void)testPostingNonCoreKitCrashLogsWithDataProcessingUnrestricted +{ + [self stubIsDataProcessingRestricted:NO]; + [self stubAppID:self.appID]; + [self stubDate]; + [self stubTimeIntervalSince1970WithTimeInterval:10]; + + [self addInitializerStubsToGraphRequestMock]; + + OCMReject( + [self.graphRequestMock initWithGraphPath:OCMArg.any + parameters:OCMArg.any + HTTPMethod:FBSDKHTTPMethodPOST] + ); + OCMReject([self.graphRequestMock startWithCompletionHandler:nil]); + + [FBSDKCrashShield analyze:self.nonCoreKitCrashLogs]; +} + +// MARK: - Helpers + +- (void)addInitializerStubsToGraphRequestMock +{ + OCMStub(ClassMethod([self.graphRequestMock alloc])).andReturn(self.graphRequestMock); + OCMStub( + [self.graphRequestMock initWithGraphPath:OCMArg.any + parameters:OCMArg.any + HTTPMethod:FBSDKHTTPMethodPOST] + ).andReturn(self.graphRequestMock); +} + +- (NSString *)encodedCoreKitFeatureDataWithTimestamp:(NSString *)timestamp +{ + NSData *featureData = [FBSDKTypeUtility dataWithJSONObject:@{ + @"feature_names" : @[@"CodelessEvents"], + @"timestamp" : timestamp + } options:0 error:nil]; + return [[NSString alloc] initWithData:featureData encoding:NSUTF8StringEncoding]; +} + +- (NSArray *> *)coreKitCrashLogs +{ + return [FBSDKCrashShieldTests getCrashLogs:YES]; +} + +- (NSArray *> *)nonCoreKitCrashLogs +{ + return [FBSDKCrashShieldTests getCrashLogs:NO]; } + (NSArray *> *)getCrashLogs:(BOOL)isCoreKitFeature @@ -149,4 +300,15 @@ - (void)testAnalyzeCrashCausedByNonCoreKitFeature return crashLogs; } +- (void)preventGraphRequest +{ + OCMStub(ClassMethod([self.graphRequestMock alloc])).andReturn(self.graphRequestMock); + OCMStub( + [self.graphRequestMock initWithGraphPath:OCMArg.any + parameters:OCMArg.any + HTTPMethod:FBSDKHTTPMethodPOST] + ).andReturn(self.graphRequestMock); + OCMStub([self.graphRequestMock startWithCompletionHandler:nil]); +} + @end From 7acbcfc4b25f01ddc74a308dfc2069e3feb60dfc Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 6 Nov 2020 09:59:14 -0800 Subject: [PATCH 077/227] Reduce the number of iterations in the tests that use random data from 1000 to 100 (#1564) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1564 This should shave off a couple of seconds from the test suite. There were 2 tests that were taking more than one second when running `buck test :`, FBSDKErrorConfigurationTests and FBSDKServerConfigurationManagerTests. Before: ``` ... PASS <100ms 4 Passed 0 Skipped 0 Failed FBSDKCrashShieldTests PASS 1.4s 13 Passed 0 Skipped 0 Failed FBSDKErrorConfigurationTests PASS <100ms 3 Passed 0 Skipped 0 Failed FBSDKEventBindingTests ... PASS <100ms 5 Passed 0 Skipped 0 Failed FBSDKSafeCastTests PASS 1.1s 1 Passed 0 Skipped 0 Failed FBSDKServerConfigurationManagerTests PASS <100ms 171 Passed 0 Skipped 0 Failed FBSDKServerConfigurationTests ... ``` After: ``` ... PASS <100ms 4 Passed 0 Skipped 0 Failed FBSDKCrashShieldTests PASS 144ms 13 Passed 0 Skipped 0 Failed FBSDKErrorConfigurationTests PASS <100ms 3 Passed 0 Skipped 0 Failed FBSDKEventBindingTests ... PASS <100ms 5 Passed 0 Skipped 0 Failed FBSDKSafeCastTests PASS 815ms 1 Passed 0 Skipped 0 Failed FBSDKServerConfigurationManagerTests PASS <100ms 171 Passed 0 Skipped 0 Failed FBSDKServerConfigurationTests ... ``` Reviewed By: joesus Differential Revision: D24773919 fbshipit-source-id: a7dbd8a3299d72acd6830b117274b55015cadabd --- .../Codeless/FBSDKEventBindingTests.m | 2 +- .../FBSDKAppEventsConfigurationManagerTests.m | 2 +- .../FBSDKFeatureExtractorTests.m | 4 ++-- .../Internal/Basics/FBSDKTypeUtilityTests.m | 2 +- .../Internal/FBSDKErrorConfigurationTests.m | 22 +++++++++---------- .../Internal/FBSDKInternalUtilityTests.m | 2 +- .../FBSDKServerConfigurationManagerTests.m | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m index 95f7948fef..78ec774236 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m @@ -121,7 +121,7 @@ - (void)testEventBindingEquation - (void)testParsing { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSDictionary *sampleData = [FBSDKSampleEventBinding getSampleDictionary]; [FBSDKEventBindingManager parseArray:@[[Fuzzer randomizeWithJson:sampleData]]]; } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m index e80d79a59e..cfc1307787 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m @@ -39,7 +39,7 @@ @implementation FBSDKAppEventsConfigurationManagerTests - (void)testParsingResponses { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { [FBSDKAppEventsConfigurationManager _processResponse:RawAppEventsConfigurationResponseFixtures.random error:nil]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m index ccb5b0d35c..02e7056ce5 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SuggestedEvent/FBSDKFeatureExtractorTests.m @@ -262,7 +262,7 @@ - (void)testGetDenseFeature - (void)testGetDenseFeatureParsing { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSDictionary *viewHierarchy = [_viewHierarchy copy]; [FBSDKFeatureExtractor getDenseFeatures:[Fuzzer randomizeWithJson:viewHierarchy]]; } @@ -363,7 +363,7 @@ - (void)testRegextMatch - (void)testLoadRulesForKey { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { [FBSDKFeatureExtractor loadRulesForKey:Fuzzer.random]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m index 1f22ad9acb..8db33c0309 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKTypeUtilityTests.m @@ -66,7 +66,7 @@ - (void)testIsValidJSONWithInvalidJSON - (void)testIsValidJSONWithRandomValues { // Should not crash for any given value - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { [FBSDKTypeUtility isValidJSONObject:Fuzzer.random]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m index 28719c5086..19b144f592 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKErrorConfigurationTests.m @@ -79,7 +79,7 @@ - (void)testErrorConfigurationAdditonalArray - (void)testParsingRandomName { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : Fuzzer.random, @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @@ -96,7 +96,7 @@ - (void)testParsingRandomName - (void)testParsingRandomSubcodes { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : @190, @"subcodes" : @[Fuzzer.random] }], }, @@ -113,7 +113,7 @@ - (void)testParsingRandomSubcodes - (void)testParsingRandomCodes { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : Fuzzer.random, @"subcodes" : @[@459] }], }, @@ -130,7 +130,7 @@ - (void)testParsingRandomCodes - (void)testParsingRandomItemDictionaries { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[Fuzzer.random], }, @@ -147,7 +147,7 @@ - (void)testParsingRandomItemDictionaries - (void)testParsingRandomItems { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : Fuzzer.random, }, @@ -164,7 +164,7 @@ - (void)testParsingRandomItems - (void)testParsingRandomRecoveryMessage { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @@ -181,7 +181,7 @@ - (void)testParsingRandomRecoveryMessage - (void)testParsingRandomRecoveryOptionsArray { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @@ -198,7 +198,7 @@ - (void)testParsingRandomRecoveryOptionsArray - (void)testParsingRandomRecoveryOptions { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @@ -215,7 +215,7 @@ - (void)testParsingRandomRecoveryOptions - (void)testParsingRecoveryMessageWithoutOptions { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @@ -231,7 +231,7 @@ - (void)testParsingRecoveryMessageWithoutOptions - (void)testParsingRecoveryOptionsWithoutMessage { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = @[ @{ @"name" : @"other", @"items" : @[@{ @"code" : @190, @"subcodes" : @[@459] }], }, @@ -247,7 +247,7 @@ - (void)testParsingRecoveryOptionsWithoutMessage - (void)testParsingRandomEntries { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { NSArray *array = [Fuzzer randomizeWithJson:rawErrorCodeConfiguration]; FBSDKErrorConfiguration *configuration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m index 7848e60cda..2d527415ff 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m @@ -140,7 +140,7 @@ - (void)testParsingPermissionsWithFuzzyValues NSMutableSet *expiredPermissions = [NSMutableSet set]; // A lack of a runtime crash is considered a success here. - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { [FBSDKInternalUtility extractPermissionsFromResponse:SampleRawRemotePermissionList.randomValues grantedPermissions:grantedPermissions declinedPermissions:declinedPermissions diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m index 615f04bafc..7865981db9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m @@ -38,7 +38,7 @@ @implementation FBSDKServerConfigurationManagerTests - (void)testParsingResponses { - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 100; i++) { [FBSDKServerConfigurationManager processLoadRequestResponse:RawServerConfigurationResponseFixtures.random error:nil appID:nil]; } } From 1fe0b9f8cf10d56389d6ee4a00813b739db5e0f8 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 6 Nov 2020 10:02:59 -0800 Subject: [PATCH 078/227] Convert SampleUserProfile.m/h to Swift Summary: Converted SampleUserProfile.m/h to Swift Made the static valid method a static var since it's accessed like a property from within FBSDKProfileTests.m i.e. SampleUserProfile.valid.firstName and it can be accessed from within Swift the same way. (Alternatively if valid was a func the call would have to be updated to SampleUserProfile.valid().firstName in Swift). Reviewed By: joesus Differential Revision: D24773586 fbshipit-source-id: a13fcb46c60816a95c3d0451c254e6caa27c4b47 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +++--- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 2 +- .../Internal/Helpers/SampleUserProfile.m | 34 ------------------- ...eUserProfile.h => SampleUserProfile.swift} | 26 +++++++------- 4 files changed, 19 insertions(+), 53 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{SampleUserProfile.h => SampleUserProfile.swift} (75%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index a6738a613e..854460792a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ 52D4F0D31D91A1940030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */; }; 52D4F0D41D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */; }; 52D4F0D51D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */; }; + 5C49DF9E2554C9ED00E0FD91 /* SampleUserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */; }; 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */; }; 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */; }; 5D41131A229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D411318229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m */; }; @@ -927,7 +928,6 @@ F4A52B15242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; F4A52B16242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; F4A52B17242AA532005F65CE /* FBSDKPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */; }; - F4A826B524EC6F9900EB2CD4 /* SampleUserProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */; }; F4A826B724EC6FAD00EB2CD4 /* FBSDKProfileTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */; }; F4AE435225508FEA00FA9DE6 /* FBSDKProfilePictureView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */; }; F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */; }; @@ -1234,6 +1234,7 @@ 52963AA72159A13300C7B252 /* FBSDKMeasurementEvent_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMeasurementEvent_Internal.h; sourceTree = ""; }; 52963AAA2159A16E00C7B252 /* FBSDKMeasurementEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMeasurementEvent.h; sourceTree = ""; }; 52963AAB2159A16E00C7B252 /* FBSDKMeasurementEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMeasurementEvent.m; sourceTree = ""; }; + 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleUserProfile.swift; sourceTree = ""; }; 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsTests.m; sourceTree = ""; }; 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestTests.m; sourceTree = ""; }; 5D411318229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterManager.m; sourceTree = ""; }; @@ -1579,8 +1580,6 @@ F4A52B0A242A99C8005F65CE /* FBSDKPerformanceMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPerformanceMonitorTests.m; sourceTree = ""; }; F4A52B0C242AA532005F65CE /* FBSDKPerformanceMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKPerformanceMonitor.h; sourceTree = ""; }; F4A52B0D242AA532005F65CE /* FBSDKPerformanceMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPerformanceMonitor.m; sourceTree = ""; }; - F4A826A524EC6F9900EB2CD4 /* SampleUserProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleUserProfile.h; sourceTree = ""; }; - F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SampleUserProfile.m; sourceTree = ""; }; F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKProfileTests.m; sourceTree = ""; }; F4BD4022241EEDE500B45D39 /* FBSDKTestCoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTestCoder.h; sourceTree = ""; }; F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKTestCoder.m; sourceTree = ""; }; @@ -2645,8 +2644,6 @@ F4CD7CDA243E2CF7004C27F1 /* Helpers */ = { isa = PBXGroup; children = ( - F4A826A524EC6F9900EB2CD4 /* SampleUserProfile.h */, - F4A826B424EC6F9900EB2CD4 /* SampleUserProfile.m */, F496E58D24E49DBC006231A2 /* SampleAppEvents.h */, F496E58E24E49DBC006231A2 /* SampleAppEvents.m */, F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */, @@ -2675,6 +2672,7 @@ F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */, F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */, F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */, + 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */, ); path = Helpers; sourceTree = ""; @@ -4094,7 +4092,6 @@ F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */, 9DF18BCB1A9F2517000F6748 /* FBSDKErrorConfigurationTests.m in Sources */, 9D18A8E91A95495D00A41042 /* FBSDKAppEventsUtilityTests.m in Sources */, - F4A826B524EC6F9900EB2CD4 /* SampleUserProfile.m in Sources */, F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */, F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m in Sources */, F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */, @@ -4137,6 +4134,7 @@ F40B24C224732DD90059351C /* Fuzzer.swift in Sources */, 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */, F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */, + 5C49DF9E2554C9ED00E0FD91 /* SampleUserProfile.swift in Sources */, F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */, 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.m in Sources */, F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index d0eda5eb60..1b4cb2bcdf 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -20,11 +20,11 @@ #import #import "FBSDKCoreKit.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKProfile.h" #import "FBSDKProfile+Internal.h" #import "FBSDKTestCase.h" #import "SampleAccessToken.h" -#import "SampleUserProfile.h" @interface FBSDKSettings (Testing) + (void)resetFacebookClientTokenCache; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m deleted file mode 100644 index 1893bfea45..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.m +++ /dev/null @@ -1,34 +0,0 @@ -// 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 "SampleUserProfile.h" - -@implementation SampleUserProfile - -+ (FBSDKProfile *)valid -{ - return [[FBSDKProfile alloc] initWithUserID:@"123" - firstName:@"John" - middleName:@"K" - lastName:@"Smith" - name:@"John Smith" - linkURL:[NSURL URLWithString:@"http://www.example.com"] - refreshDate:NSDate.distantFuture]; -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift similarity index 75% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift index 12889c46f9..122b7b23d0 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift @@ -16,16 +16,18 @@ // 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 FBSDKCoreKit -#import "FBSDKProfile.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface SampleUserProfile : NSObject - -+ (FBSDKProfile *)valid; - -@end - -NS_ASSUME_NONNULL_END +@objc public class SampleUserProfile: NSObject { + @objc public static var valid: Profile { + return Profile( + userID: "123", + firstName: "John", + middleName: "K", + lastName: "Smith", + name: "John Smith", + linkURL: URL(string: "http://www.example.com"), + refreshDate: .distantFuture + ) + } +} From 89943d782e8280c4445965d336f5774ca4f4d917 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 6 Nov 2020 10:05:57 -0800 Subject: [PATCH 079/227] Update 2 Xcode project groups to folder references Summary: Updated the Swift group in FBSDKShareKit and the AppLinks group in FBSDKCoreKit to point to the actual folders on the filesystem. Reviewed By: joesus Differential Revision: D24774720 fbshipit-source-id: d7c3a70c4784184fb95530867fda3fa599830389 --- FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj | 6 +++--- FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 854460792a..362eef1997 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -1206,7 +1206,7 @@ 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValueTests.m; sourceTree = ""; }; 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppLinkResolverRequestBuilder.h; sourceTree = ""; }; 45540D9025271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkResolverRequestBuilder.m; sourceTree = ""; }; - 45540DB025271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppLinkResolverRequestBuilderTests.m; path = AppLinks/FBSDKAppLinkResolverRequestBuilderTests.m; sourceTree = ""; }; + 45540DB025271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkResolverRequestBuilderTests.m; sourceTree = ""; }; 4AF47CF11F42468D00A57A67 /* FBSDKDeviceUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKDeviceUtilities.m; sourceTree = ""; }; 4AF47CF21F42468D00A57A67 /* FBSDKDeviceUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKDeviceUtilities.h; sourceTree = ""; }; 4AF47CFE1F424A8700A57A67 /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.0.sdk/System/Library/Frameworks/CoreImage.framework; sourceTree = DEVELOPER_DIR; }; @@ -1268,7 +1268,7 @@ 7E3091791AA907E0004E91D5 /* FBSDKAppLinkUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkUtility.m; sourceTree = ""; }; 7E5557351A8D833100344F86 /* FBSDKAppLinkResolver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkResolver.m; sourceTree = ""; }; 7E5557361A8D833100344F86 /* FBSDKAppLinkResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppLinkResolver.h; sourceTree = ""; }; - 7E55573A1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppLinkResolverTests.m; path = AppLinks/FBSDKAppLinkResolverTests.m; sourceTree = ""; }; + 7E55573A1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkResolverTests.m; sourceTree = ""; }; 7E55573F1A8E89A800344F86 /* OHHTTPStubs.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OHHTTPStubs.xcodeproj; path = ../Carthage/Checkouts/OHHTTPStubs/OHHTTPStubs/OHHTTPStubs.xcodeproj; sourceTree = ""; }; 7EB63D9D1A9BE730003A7AED /* FBSDKMeasurementEventListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMeasurementEventListener.m; sourceTree = ""; }; 7EB63D9E1A9BE730003A7AED /* FBSDKMeasurementEventListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMeasurementEventListener.h; sourceTree = ""; }; @@ -1849,7 +1849,7 @@ 7E55573A1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m */, 45540DB025271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m */, ); - name = AppLinks; + path = AppLinks; sourceTree = ""; }; 7E5557401A8E89A800344F86 /* Products */ = { diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index 657b74ba25..08c0203179 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -537,7 +537,7 @@ EA3D469E1AA6835900D0C7D5 /* FBSDKAppInviteContent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppInviteContent.m; sourceTree = ""; }; EA6CCE931AA7855D00F1EC35 /* FBSDKAppInviteContentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppInviteContentTests.m; sourceTree = ""; }; EAC370A21AAE3A9C000F0F04 /* FBSDKGameRequestContentTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKGameRequestContentTests.m; sourceTree = ""; }; - F46FA682245362880060C902 /* Enums+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Enums+Extensions.swift"; path = "Swift/Enums+Extensions.swift"; sourceTree = ""; }; + F46FA682245362880060C902 /* Enums+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Enums+Extensions.swift"; sourceTree = ""; }; F4D7A84524520A6700A12EE5 /* FakeSharingDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeSharingDelegate.h; sourceTree = ""; }; F4D7A84624520A6700A12EE5 /* FakeSharingDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeSharingDelegate.m; sourceTree = ""; }; F4DC05072519457C0073B380 /* FBSDKCoreKitInternalImport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitInternalImport.h; sourceTree = ""; }; @@ -907,7 +907,7 @@ children = ( F46FA682245362880060C902 /* Enums+Extensions.swift */, ); - name = Swift; + path = Swift; sourceTree = ""; }; /* End PBXGroup section */ From a840db5682adcd3f563492e7a2b3e73759bfd731 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 6 Nov 2020 10:15:19 -0800 Subject: [PATCH 080/227] Add FBSDKGamingServicesKitTests to the BuildAllKits scheme Summary: The BuildAllKits test didn't include FBSDKGamingServicesKitTests. (It had FBSDKCoreKitTests, FBSDKLoginKitTests and FBSDKShareKitTests). The FBSDKGamingServicesKitTests were still run via `buck test :`, however they would not run in Xcode when using Command+U to run tests for the scheme. The compilation error I was initally getting was due to `carthage bootstrap` not completing, which is a known issue that is currently open https://github.com/Carthage/Carthage/issues/3019 The following workaround of using a custom `carthage.sh` file worked for me for that issue https://github.com/Carthage/Carthage/issues/3019#issuecomment-665136323 Reviewed By: joesus Differential Revision: D24778344 fbshipit-source-id: b105a9441439caf5f27c8d7276d2bed119de64c8 --- .../xcshareddata/xcschemes/BuildAllKits.xcscheme | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme b/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme index da0b807829..a2eacf429b 100644 --- a/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme +++ b/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme @@ -151,6 +151,16 @@ ReferencedContainer = "container:FBSDKShareKit/FBSDKShareKit.xcodeproj"> + + + + Date: Fri, 6 Nov 2020 10:39:12 -0800 Subject: [PATCH 081/227] add type check and nullable annotation Summary: D21789806 (https://github.com/facebook/facebook-ios-sdk/commit/02a780841e266910b66250ded50eef06a2473f8f) introduced the usage of FBSDKTypeUtility to FBSDKLibAnalyzer for type safety reason. [FBSDKTypeUtility array:objectAtIndex:] may return nil, so we need to add a nil check for `rawAddress` and its length. Similarly `[FBSDKTypeUtility dictionary: objectForKey: ofType:]` may return nil, so add nil check for the result from this function call, which is `methodName`. We received bug report: https://github.com/facebook/facebook-ios-sdk/issues/1555. `[FBSDKTypeUtility array:callstack objectAtIndex:i]` passed to `getAddress` was NSNumber rather than NSString as expected, although `callstack` is NSArray, and caused app to be terminated. So we need to add type check in `getAddress` method. This diff also adds missing nullable annotation to methods. Reviewed By: dreamolight Differential Revision: D24691269 fbshipit-source-id: 349a53ed19f0f66806e939ec27520163f72b46d3 --- .../FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m index 7da024782d..153617cc6c 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m @@ -129,8 +129,8 @@ + (void)addClass:(Class)class free(methods); } -+ (NSArray *)symbolicateCallstack:(NSArray *)callstack - methodMapping:(NSDictionary *)methodMapping ++ (nullable NSArray *)symbolicateCallstack:(NSArray *)callstack + methodMapping:(NSDictionary *)methodMapping { if (!callstack || !methodMapping) { return nil; @@ -145,6 +145,9 @@ + (void)addClass:(Class)class for (NSUInteger i = 0; i < callstack.count; i++) { NSString *rawAddress = [self getAddress:[FBSDKTypeUtility array:callstack objectAtIndex:i]]; + if (rawAddress.length < 10) { + continue; + } NSString *addressString = [NSString stringWithFormat:@"0x%@", [rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]]; NSString *methodAddress = [self searchMethod:addressString sortedAllAddress:sortedAllAddress]; @@ -168,12 +171,14 @@ + (void)addClass:(Class)class return containsFBSDKFunction ? symbolicatedCallstack : nil; } -+ (NSString *)getAddress:(NSString *)callstackEntry ++ (nullable NSString *)getAddress:(nullable NSString *)callstackEntry { - NSArray *components = [callstackEntry componentsSeparatedByString:@" "]; - for (NSString *component in components) { - if ([component containsString:@"0x"]) { - return component; + if ([callstackEntry isKindOfClass:[NSString class]]) { + NSArray *components = [callstackEntry componentsSeparatedByString:@" "]; + for (NSString *component in components) { + if ([component containsString:@"0x"]) { + return component; + } } } return nil; @@ -182,9 +187,6 @@ + (NSString *)getAddress:(NSString *)callstackEntry + (NSString *)getOffset:(NSString *)firstString secondString:(NSString *)secondString { - if (!firstString || !secondString) { - return nil; - } unsigned long long first = 0, second = 0; NSScanner *scanner = [NSScanner scannerWithString:firstString]; [scanner scanHexLongLong:&first]; @@ -196,8 +198,8 @@ + (NSString *)getOffset:(NSString *)firstString return [NSString stringWithFormat:@"+%llu", difference]; } -+ (NSString *)searchMethod:(NSString *)address - sortedAllAddress:(NSArray *)sortedAllAddress ++ (nullable NSString *)searchMethod:(NSString *)address + sortedAllAddress:(NSArray *)sortedAllAddress { if (0 == sortedAllAddress.count) { return nil; From b5963050ab1875815823f77a0982aa0a1c1535fa Mon Sep 17 00:00:00 2001 From: leschenok Date: Fri, 6 Nov 2020 11:44:09 -0800 Subject: [PATCH 082/227] Clean up unused API (#1460) Summary: Delete unused method. Method is not used since 95e67c98f0b53adc8a8ea610fdfd0457be3d4d2b commit Thanks for proposing a pull request! To help us review the request, please complete the following: - [X] sign [contributor license agreement](https://developers.facebook.com/opensource/cla) - [X] I've ensured that all existing tests pass and added tests (when/where necessary) - [ ] I've updated the documentation (when/where necessary) and [Changelog](CHANGELOG.md) (when/where necessary) - [ ] I've added the proper label to this pull request (e.g. `bug` for bug fixes) ## Pull Request Details Delete unused method. Method is not used since 95e67c9 commit Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1460 Differential Revision: D24761044 Pulled By: joesus fbshipit-source-id: 71db6d40aa7439dc68c46a5af717747b222d6051 --- .../Internal/FBSDKLoginCompletion.m | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 8be484dc4d..a5a9fe19e0 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -217,24 +217,6 @@ - (void)setErrorWithDictionary:(NSDictionary *)parameters _parameters.error = [NSError fbErrorFromReturnURLParameters:parameters]; } -- (void)attemptBrowserLogIn:(FBSDKLoginManager *)loginManager -{ - if (_observer != nil) { - [[NSNotificationCenter defaultCenter] removeObserver:_observer]; - _observer = nil; - } - - if ([FBSDKBridgeAPI sharedInstance].isActive) { - [loginManager logIn]; - } else { - // The application is active but due to notification ordering the FBSDKApplicationDelegate - // doesn't know it yet. Wait one more turn of the run loop. - dispatch_async(dispatch_get_main_queue(), ^{ - [self attemptBrowserLogIn:loginManager]; - }); - } -} - - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler { if (!handler) { From e40b1d800eb34b9e226f703a11d469c79459324b Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 6 Nov 2020 17:42:45 -0800 Subject: [PATCH 083/227] Convert FBSDKMonitoringConfigurationTestHelper.m to Swift Summary: Converted FBSDKMonitoringConfigurationTestHelper.m to Swift Reviewed By: joesus Differential Revision: D24805161 fbshipit-source-id: 95a2b7b38b31090bebcb48a951a4e9caa02af131 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 ++--- .../FBSDKMonitoringConfigurationTestHelper.m | 43 ------------------- ...DKMonitoringConfigurationTestHelper.swift} | 37 ++++++++-------- .../FBSDKMonitorConfigurationTests.m | 2 +- .../FBSDKServerConfigurationTests.m | 2 +- 5 files changed, 24 insertions(+), 70 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{FBSDKMonitoringConfigurationTestHelper.h => FBSDKMonitoringConfigurationTestHelper.swift} (68%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 362eef1997..149013de20 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -894,7 +894,7 @@ F468B35724C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35824C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; F468B35924C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */ = {isa = PBXBuildFile; fileRef = F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */; }; - F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m */; }; + F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift */; }; F46FA62D24533F450060C902 /* AccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBD9231EC293008416A9 /* AccessToken.swift */; }; F46FA63C24533F450060C902 /* AccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBD9231EC293008416A9 /* AccessToken.swift */; }; F46FA63D24533F610060C902 /* Permission.swift in Sources */ = {isa = PBXBuildFile; fileRef = F487DBCB231EC1A0008416A9 /* Permission.swift */; }; @@ -1543,8 +1543,7 @@ F468B2E724C25AB500979F8D /* FBSDKBasicUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKBasicUtility.m; sourceTree = ""; }; F468B2E824C25AB600979F8D /* FBSDKURLSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKURLSession.m; sourceTree = ""; }; F468B2E924C25AB600979F8D /* FBSDKLibAnalyzer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLibAnalyzer.m; sourceTree = ""; }; - F46C4847243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FBSDKMonitoringConfigurationTestHelper.h; path = FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h; sourceTree = SOURCE_ROOT; }; - F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKMonitoringConfigurationTestHelper.m; path = FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m; sourceTree = SOURCE_ROOT; }; + F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FBSDKMonitoringConfigurationTestHelper.swift; path = FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.swift; sourceTree = SOURCE_ROOT; }; F47E55FB24E1EA8D001497C9 /* FakeBundle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FakeBundle.m; sourceTree = ""; }; F47E560C24E1EA8D001497C9 /* FakeBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FakeBundle.h; sourceTree = ""; }; F487DBCB231EC1A0008416A9 /* Permission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Permission.swift; sourceTree = ""; }; @@ -2654,8 +2653,7 @@ F47E55FB24E1EA8D001497C9 /* FakeBundle.m */, F4BD4022241EEDE500B45D39 /* FBSDKTestCoder.h */, F4BD4023241EEDE500B45D39 /* FBSDKTestCoder.m */, - F46C4847243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.h */, - F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m */, + F46C4856243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift */, F40B24C124732DD90059351C /* Fuzzer.swift */, F4DE31F424DB695100297C18 /* FBSDKTestCase.h */, F4DE31F524DB695100297C18 /* FBSDKTestCase.m */, @@ -4144,7 +4142,7 @@ 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */, F4EB317F2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m in Sources */, F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, - F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.m in Sources */, + F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */, 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m deleted file mode 100644 index d89a6dc153..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.m +++ /dev/null @@ -1,43 +0,0 @@ -// 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 "FBSDKMonitoringConfigurationTestHelper.h" - -@implementation FBSDKMonitoringConfigurationTestHelper - -+ (NSDictionary *)sampleRatesWithEntryPairs:(NSDictionary *)pairs -{ - NSMutableArray *sampleRateDicts = [NSMutableArray array]; - - NSMutableDictionary *tmp = [NSMutableDictionary dictionary]; - [pairs enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) { - [sampleRateDicts addObject:[self sampleRateWithEntryName:key rate:obj]]; - }]; - - [tmp setObject:sampleRateDicts forKey:@"sample_rates"]; - return tmp; -} - -+ (NSDictionary *)sampleRateWithEntryName:(NSString *)name rate:(NSNumber *)rate -{ - NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithObject:name forKey:@"key"]; - [tmp setObject:rate forKey:@"value"]; - return tmp; -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.swift similarity index 68% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.swift index e8dc1f737f..0de6f44b63 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKMonitoringConfigurationTestHelper.swift @@ -16,24 +16,23 @@ // 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 Foundation -NS_ASSUME_NONNULL_BEGIN +@objcMembers +public class FBSDKMonitoringConfigurationTestHelper: NSObject { -@interface FBSDKMonitoringConfigurationTestHelper : NSObject - -/// Bundles key value pairs in the same format they're returned from the graph: -/// ex: -/// { -/// "sample_rates": [ -/// { -/// "key": "foo", -/// "value": 1 -/// } -/// ] -/// } -+ (NSDictionary *)sampleRatesWithEntryPairs:(NSDictionary *)pairs; - -@end - -NS_ASSUME_NONNULL_END + /// Bundles key value pairs in the same format they're returned from the graph. + /// ex: + /// { + /// "sample_rates": [ + /// { + /// "key": "foo", + /// "value": 1 + /// } + /// ] + /// } + public static func sampleRates(withEntryPairs pairs: [String: Any]) -> [String: Any] { + let sampleRateDicts = pairs.map { ["key": $0, "value": $1] } + return ["sample_rates": sampleRateDicts] + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m index 6686f58c16..f79faee885 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorConfigurationTests.m @@ -18,8 +18,8 @@ #import +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKMonitoringConfiguration.h" -#import "FBSDKMonitoringConfigurationTestHelper.h" #import "FBSDKTestCoder.h" #import "TestMonitorEntry.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m index efec344995..c2a1b67967 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationTests.m @@ -20,8 +20,8 @@ #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKEventBinding.h" -#import "FBSDKMonitoringConfigurationTestHelper.h" #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCoder.h" From 4cc89af8d47f314b4130b2d464da9fd33cbf2d2a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 9 Nov 2020 12:28:41 -0800 Subject: [PATCH 084/227] Unit test hardening - FBSDKInternalUtility 1/n Summary: Adding test coverage for FBSDKInternalUtility Also: * moves method for resetting caches on FBSDKSettings properties to the shared test case class. * renames `dictionaryFromFBURL` to be `parametersFromFBURL` Reviewed By: jawwad Differential Revision: D24806271 fbshipit-source-id: 34ca06c4170f8253fe73656381b75792e755a8f6 --- .../AppEvents/Internal/FBSDKTimeSpentData.m | 2 +- .../Internal/FBSDKInternalUtility.h | 2 +- .../Internal/FBSDKInternalUtility.m | 16 +- .../Internal/FBSDKInternalUtilityTests.m | 435 +++++++++++++++++- .../Internal/FBSDKSettingsTests.m | 40 +- .../Internal/Helpers/FBSDKTestCase.h | 15 + .../Internal/Helpers/FBSDKTestCase.m | 61 ++- .../FBSDKLoginKit/FBSDKReferralManager.m | 2 +- .../Internal/FBSDKLoginUtility.m | 2 +- .../FBSDKReferralManagerTests.m | 2 +- 10 files changed, 530 insertions(+), 47 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m index 7a9d9d2541..3a461c157f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKTimeSpentData.m @@ -271,7 +271,7 @@ - (NSDictionary *)appEventsParametersForDeactivate + (void)setSourceApplication:(NSString *)sourceApplication openURL:(NSURL *)url { [self setSourceApplication:sourceApplication - isFromAppLink:[FBSDKInternalUtility dictionaryFromFBURL:url][@"al_applink_data"] != nil]; + isFromAppLink:[FBSDKInternalUtility parametersFromFBURL:url][@"al_applink_data"] != nil]; } + (void)setSourceApplication:(NSString *)sourceApplication isFromAppLink:(BOOL)isFromAppLink diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h index 465a589ca6..a4e72d9a9d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h @@ -94,7 +94,7 @@ NS_SWIFT_NAME(InternalUtility) @param url The FB url. @return A dictionary with the key/value pairs. */ -+ (NSDictionary *)dictionaryFromFBURL:(NSURL *)url; ++ (NSDictionary *)parametersFromFBURL:(NSURL *)url; /** Constructs a Facebook URL. diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index bf5ba5e928..c44940849d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -69,7 +69,7 @@ + (NSURL *)appURLWithHost:(NSString *)host error:errorRef]; } -+ (NSDictionary *)dictionaryFromFBURL:(NSURL *)url ++ (NSDictionary *)parametersFromFBURL:(NSURL *)url { // version 3.2.3 of the Facebook app encodes the parameters in the query but // version 3.3 and above encode the parameters in the fragment; @@ -421,8 +421,20 @@ + (NSComparisonResult)_compareOperatingSystemVersion:(NSOperatingSystemVersion)v + (BOOL)_canOpenURLScheme:(NSString *)scheme { + scheme = [FBSDKTypeUtility stringValue:scheme]; + if (!scheme) { + return NO; + } + NSURLComponents *components = [[NSURLComponents alloc] init]; - components.scheme = scheme; + @try { + components.scheme = scheme; + } @catch (NSException *exception) { + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + formatString:@"Invalid URL scheme provided: %@", scheme]; + return NO; + } + components.path = @"/"; return [[UIApplication sharedApplication] canOpenURL:components.URL]; } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m index 2d527415ff..ea41ad5af0 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m @@ -16,23 +16,52 @@ // 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 "FBSDKCoreKit.h" #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKInternalUtility.h" +#import "FBSDKTestCase.h" -@interface FBSDKInternalUtilityTests : XCTestCase +@interface FBSDKInternalUtility (Testing) + ++ (BOOL)_canOpenURLScheme:(NSString *)scheme; + +@end + +@interface FBSDKInternalUtilityTests : FBSDKTestCase @end @implementation FBSDKInternalUtilityTests +{ + id _notificationCenterSpy; +} + +- (void)setUp +{ + [super setUp]; + + [self resetCachedSettings]; + + [FBSDKInternalUtility deleteFacebookCookies]; +} + +- (void)tearDown +{ + [self resetCachedSettings]; + + [super tearDown]; +} + +// MARK: - Facebook URL - (void)testFacebookURL { + [self stubFacebookDomainPartWith:@""]; NSString *URLString; NSString *tier = [FBSDKSettings facebookDomainPart]; - [FBSDKSettings setFacebookDomainPart:@""]; URLString = [FBSDKInternalUtility facebookURLWithHostPrefix:@"" @@ -133,6 +162,8 @@ - (void)testFacebookURL XCTAssertEqualObjects(URLString, @"https://m.facebook.com/" FBSDK_TARGET_PLATFORM_VERSION @"/dialog/share"); } +// MARK: - Extracting Permissions + - (void)testParsingPermissionsWithFuzzyValues { NSMutableSet *grantedPermissions = [NSMutableSet set]; @@ -213,4 +244,404 @@ - (void)testExtractingPermissionsFromResponseWithValidPermissions XCTAssertTrue([expiredPermissions containsObject:@"first_name"], "Should add the correct permission to expired permissions"); } +// MARK: - Can open URL scheme + +- (void)testCanOpenUrlSchemeWithMissingScheme +{ + // Should not even bother checking a nil scheme + OCMReject([self.sharedApplicationMock canOpenURL:OCMArg.any]); + + XCTAssertFalse( + [FBSDKInternalUtility _canOpenURLScheme:nil], + "Should not be able to open a missing scheme" + ); +} + +- (void)testCanOpenUrlSchemeWithInvalidSchemes +{ + // Should not even bother checking invalid schemes + OCMReject([self.sharedApplicationMock canOpenURL:OCMArg.any]); + + NSArray *invalidSchemes = @[ + @"http:", + @"", + @" ", + @"#@%(*&#$(^#@!$", + @"////foo", + @"foo:", + @"foo:/" + ]; + + for (NSString *scheme in invalidSchemes) { + [FBSDKInternalUtility _canOpenURLScheme:scheme]; + } +} + +- (void)testCanOpenUrlSchemeWithValidSchemes +{ + NSArray *validSchemes = @[ + @"foo", + @"FOO", + @"foo+bar", + @"foo-bar", + @"foo.bar" + ]; + + for (NSString *scheme in validSchemes) { + [FBSDKInternalUtility _canOpenURLScheme:scheme]; + + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@:/", scheme]]; + OCMVerify([self.sharedApplicationMock canOpenURL:url]); + } +} + +// MARK: - App URL Scheme + +- (void)testAppURLSchemeWithMissingAppIdMissingSuffix +{ + [self stubAppID:nil]; + [self stubAppUrlSchemeSuffixWith:nil]; + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + @"fb", + "Should return an app url scheme derived from the app id and app url scheme suffix" + ); +} + +- (void)testAppURLSchemeWithMissingAppIdInvalidSuffix +{ + [self stubAppID:nil]; + [self stubAppUrlSchemeSuffixWith:@" "]; + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + @"fb ", + "Should return an app url scheme derived from the app id and app url scheme suffix" + ); +} + +- (void)testAppURLSchemeWithMissingAppIdValidSuffix +{ + [self stubAppID:nil]; + [self stubAppUrlSchemeSuffixWith:@"foo"]; + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + @"fbfoo", + "Should return an app url scheme derived from the app id and app url scheme suffix" + ); +} + +- (void)testAppURLSchemeWithInvalidAppIdMissingSuffix +{ + [self stubAppID:@" "]; + [self stubAppUrlSchemeSuffixWith:nil]; + NSString *expected = [NSString stringWithFormat:@"fb%@", FBSDKSettings.appID]; + + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + expected, + "Should return an app url scheme derived app id and app url scheme suffix defined in settings" + ); +} + +- (void)testAppURLSchemeWithInvalidAppIdInvalidSuffix +{ + [self stubAppID:@" "]; + [self stubAppUrlSchemeSuffixWith:@" "]; + NSString *expected = [NSString stringWithFormat:@"fb%@%@", FBSDKSettings.appID, FBSDKSettings.appURLSchemeSuffix]; + + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + expected, + "Should return an app url scheme derived app id and app url scheme suffix defined in settings" + ); +} + +- (void)testAppURLSchemeWithInvalidAppIdValidSuffix +{ + [self stubAppID:@" "]; + [self stubAppUrlSchemeSuffixWith:@"foo"]; + NSString *expected = [NSString stringWithFormat:@"fb %@", FBSDKSettings.appURLSchemeSuffix]; + + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + expected, + "Should return an app url scheme derived app id and app url scheme suffix defined in settings" + ); +} + +- (void)testAppURLSchemeWithValidAppIdMissingSuffix +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:nil]; + NSString *expected = [NSString stringWithFormat:@"fb%@", FBSDKSettings.appID]; + + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + expected, + "Should return an app url scheme derived app id and app url scheme suffix defined in settings" + ); +} + +- (void)testAppURLSchemeWithValidAppIdInvalidSuffix +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:@" "]; + NSString *expected = [NSString stringWithFormat:@"fb%@%@", FBSDKSettings.appID, FBSDKSettings.appURLSchemeSuffix]; + + // This is not desired behavior but accurately reflects what is currently written. + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + expected, + "Should return an app url scheme derived app id and app url scheme suffix defined in settings" + ); +} + +- (void)testAppURLSchemeWithValidAppIdValidSuffix +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:@"foo"]; + NSString *expected = [NSString stringWithFormat:@"fb%@%@", FBSDKSettings.appID, FBSDKSettings.appURLSchemeSuffix]; + + XCTAssertEqualObjects( + [FBSDKInternalUtility appURLScheme], + expected, + "Should return an app url scheme derived app id and app url scheme suffix defined in settings" + ); +} + +// MARK: - App URL with host + +- (void)testAppUrlWithEmptyHost +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:@"foo"]; + + NSURL *url = [FBSDKInternalUtility appURLWithHost:@"" path:self.validPath queryParameters:self.validParameters error:nil]; + + XCTAssertNil(url.host, "Should not set an empty host."); +} + +- (void)testAppUrlWithValidHost +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:@"foo"]; + + NSURL *url = [FBSDKInternalUtility appURLWithHost:@"facebook" path:self.validPath queryParameters:self.validParameters error:nil]; + + XCTAssertEqualObjects(url.host, @"facebook", "Should set the expected host."); +} + +// MARK: - Check registered can open url scheme + +- (void)testCheckRegisteredCanOpenURLScheme +{ + NSString *scheme = @"foo"; + + [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:scheme]; + + OCMVerify([self.internalUtilityClassMock isRegisteredCanOpenURLScheme:scheme]); +} + +- (void)testCheckRegisteredCanOpenURLSchemeMultipleTimes +{ + NSString *scheme = @"foo"; + + [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:scheme]; + + // Should only check for a scheme a single time. + OCMReject([self.internalUtilityClassMock isRegisteredCanOpenURLScheme:scheme]); + + [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:scheme]; +} + +// MARK: - Dictionary from FBURL + +- (void)testWithAuthorizeHostNoParameters +{ + NSURL *url = [[NSURL alloc] initWithString:@"foo://authorize"]; + NSDictionary *parameters = [FBSDKInternalUtility parametersFromFBURL:url]; + + XCTAssertEqualObjects( + parameters, + @{}, + "Should not extract parameters from a url if there are none" + ); +} + +- (void)testWithAuthorizeHostNoFragment +{ + NSURL *url = [[NSURL alloc] initWithString:@"foo://authorize?foo=bar"]; + NSDictionary *parameters = [FBSDKInternalUtility parametersFromFBURL:url]; + + XCTAssertEqualObjects( + parameters, + @{@"foo" : @"bar"}, + "Should extract parameters from a url" + ); +} + +- (void)testWithAuthorizeHostAndFragment +{ + NSURL *url = [[NSURL alloc] initWithString:@"foo://authorize?foo=bar#param1=value1¶m2=value2"]; + NSDictionary *parameters = [FBSDKInternalUtility parametersFromFBURL:url]; + NSDictionary *expectedParameters = @{ + @"foo" : @"bar", + @"param1" : @"value1", + @"param2" : @"value2" + }; + + XCTAssertEqualObjects( + parameters, + expectedParameters, + "Extracted parameters from an auth url should include fragment parameters" + ); +} + +- (void)testWithoutAuthorizeHostNoParameters +{ + NSURL *url = [[NSURL alloc] initWithString:@"foo://example"]; + NSDictionary *parameters = [FBSDKInternalUtility parametersFromFBURL:url]; + + XCTAssertEqualObjects( + parameters, + @{}, + "Should not extract parameters from a url if there are none" + ); +} + +- (void)testWithoutAuthorizeHostNoFragment +{ + NSURL *url = [[NSURL alloc] initWithString:@"foo://example?foo=bar"]; + NSDictionary *parameters = [FBSDKInternalUtility parametersFromFBURL:url]; + + XCTAssertEqualObjects( + parameters, + @{@"foo" : @"bar"}, + "Should extract parameters from a url" + ); +} + +- (void)testWithoutAuthorizeHostWithFragment +{ + NSURL *url = [[NSURL alloc] initWithString:@"foo://example?foo=bar#param1=value1¶m2=value2"]; + NSDictionary *parameters = [FBSDKInternalUtility parametersFromFBURL:url]; + NSDictionary *expectedParameters = @{ @"foo" : @"bar" }; + + XCTAssertEqualObjects( + parameters, + expectedParameters, + "Extracted parameters from a non auth url should not include fragment parameters" + ); +} + +// MARK: - Cookies + +- (void)testDeletingDialogCookies +{ + NSHTTPCookie *cookie1 = [self cookieForUrl:self.dialogUrl]; + NSHTTPCookie *cookie2 = [self cookieForUrl:self.dialogUrl name:@"cookie 2"]; + + [NSHTTPCookieStorage.sharedHTTPCookieStorage setCookie:cookie1]; + [NSHTTPCookieStorage.sharedHTTPCookieStorage setCookie:cookie2]; + + NSArray *cookies = [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:self.dialogUrl]; + NSArray *expectedCookies = @[cookie1, cookie2]; + + XCTAssertEqualObjects(cookies, expectedCookies, "Sanity check that there are cookies to delete"); + + [FBSDKInternalUtility deleteFacebookCookies]; + XCTAssertEqual( + [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:self.dialogUrl], + @[], + "All cookies for the facebook dialog url should be deleted" + ); +} + +- (void)testDeletingNonDialogCookies +{ + NSHTTPCookie *cookie = [self cookieForUrl:self.nonDialogUrl]; + [NSHTTPCookieStorage.sharedHTTPCookieStorage setCookie:cookie]; + + NSArray *cookies = [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:self.nonDialogUrl]; + XCTAssertEqualObjects(cookies, @[cookie], "Sanity check that there are cookies to delete"); + + [FBSDKInternalUtility deleteFacebookCookies]; + XCTAssertEqualObjects( + [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:self.nonDialogUrl], + @[cookie], + "Should only delete cookies for the dialog url" + ); +} + +- (void)testDeletingMixOfCookies +{ + NSHTTPCookie *dialogCookie = [self cookieForUrl:self.dialogUrl]; + NSHTTPCookie *nonDialogCookie = [self cookieForUrl:self.nonDialogUrl]; + + [NSHTTPCookieStorage.sharedHTTPCookieStorage setCookie:dialogCookie]; + [NSHTTPCookieStorage.sharedHTTPCookieStorage setCookie:nonDialogCookie]; + + [FBSDKInternalUtility deleteFacebookCookies]; + + XCTAssertEqualObjects( + [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:self.dialogUrl], + @[], + "Should delete cookies for the dialog url" + ); + XCTAssertEqualObjects( + [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:self.nonDialogUrl], + @[nonDialogCookie], + "Should only delete cookies for the dialog url" + ); +} + +// MARK: - Helpers + +- (NSURL *)dialogUrl +{ + return [FBSDKInternalUtility facebookURLWithHostPrefix:@"m." + path:@"/dialog/" + queryParameters:@{} + error:NULL]; +} + +- (NSURL *)nonDialogUrl +{ + return [FBSDKInternalUtility facebookURLWithHostPrefix:@"m." + path:@"/foo/" + queryParameters:@{} + error:NULL]; +} + +- (NSHTTPCookie *)cookieForUrl:(NSURL *)url name:(NSString *)name +{ + return [NSHTTPCookie cookieWithProperties:@{ + NSHTTPCookieOriginURL : url, + NSHTTPCookiePath : url.path, + NSHTTPCookieName : name, + NSHTTPCookieValue : @"Is good" + }]; +} + +- (NSHTTPCookie *)cookieForUrl:(NSURL *)url +{ + return [self cookieForUrl:url name:@"MyCookie"]; +} + +- (NSString *)validPath +{ + return @"example"; +} + +- (NSDictionary *)validParameters +{ + return @{@"foo" : @"bar"}; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m index 958a63102d..470da19de6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m @@ -31,21 +31,6 @@ @interface FBSDKSettings () + (NSString *)userAgentSuffix; + (void)setUserAgentSuffix:(NSString *)suffix; -+ (void)resetLoggingBehaviorsCache; -+ (void)resetFacebookAppIDCache; -+ (void)resetFacebookUrlSchemeSuffixCache; -+ (void)resetFacebookClientTokenCache; -+ (void)resetFacebookDisplayNameCache; -+ (void)resetFacebookDomainPartCache; -+ (void)resetFacebookJpegCompressionQualityCache; -+ (void)resetFacebookAutoInitEnabledCache; -+ (void)resetFacebookInstrumentEnabledCache; -+ (void)resetFacebookAutoLogAppEventsEnabledCache; -+ (void)resetFacebookAdvertiserIDCollectionEnabledCache; -+ (void)resetAdvertiserTrackingStatusCache; -+ (void)resetUserAgentSuffixCache; -+ (void)resetFacebookCodelessDebugLogEnabledCache; -+ (void)resetDataProcessingOptionsCache; @end @interface FBSDKSettingsTests : FBSDKTestCase @@ -68,7 +53,7 @@ - (void)setUp { [super setUp]; - [self resetSettingsCaches]; + [self resetCachedSettings]; // Reset user defaults spy userDefaultsSpy = [UserDefaultsSpy new]; @@ -80,26 +65,7 @@ - (void)tearDown { [super tearDown]; - [self resetSettingsCaches]; -} - -- (void)resetSettingsCaches -{ - [FBSDKSettings resetLoggingBehaviorsCache]; - [FBSDKSettings resetFacebookAppIDCache]; - [FBSDKSettings resetFacebookUrlSchemeSuffixCache]; - [FBSDKSettings resetFacebookClientTokenCache]; - [FBSDKSettings resetFacebookDisplayNameCache]; - [FBSDKSettings resetFacebookDomainPartCache]; - [FBSDKSettings resetFacebookJpegCompressionQualityCache]; - [FBSDKSettings resetFacebookAutoInitEnabledCache]; - [FBSDKSettings resetFacebookInstrumentEnabledCache]; - [FBSDKSettings resetFacebookAutoLogAppEventsEnabledCache]; - [FBSDKSettings resetFacebookAdvertiserIDCollectionEnabledCache]; - [FBSDKSettings resetAdvertiserTrackingStatusCache]; - [FBSDKSettings resetUserAgentSuffixCache]; - [FBSDKSettings resetFacebookCodelessDebugLogEnabledCache]; - [FBSDKSettings resetDataProcessingOptionsCache]; + [self resetCachedSettings]; } - (void)testDefaultGraphAPIVersion @@ -1532,7 +1498,7 @@ - (void)testDataProcessingOptionsWithNonEmptyCache FBSDKSettings.dataProcessingOptions = @[]; // Reset internal storage - [FBSDKSettings resetDataProcessingOptionsCache]; + [self resetCachedSettings]; XCTAssertNotNil( FBSDKSettings.dataProcessingOptions, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 9380e952e7..60b9949753 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -130,6 +130,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `NSDate` class mock between tests @property (nullable, nonatomic, assign) id nsDateClassMock; +/// Used for sharing a `UIApplication.sharedApplication` mock between tests +@property (nullable, nonatomic, assign) id sharedApplicationMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; @@ -248,6 +251,18 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `NSDate`'s `timeIntervalSince1970` method and returns the provided time interval - (void)stubTimeIntervalSince1970WithTimeInterval:(NSTimeInterval)interval; +/// Stubs `FBSDKSettings.facebookDomainPart` with the provided value +- (void)stubFacebookDomainPartWith:(NSString *)domainPart; + +/// Stubs `UIApplication.sharedApplication`'s `canOpenURL:` method with the value +- (void)stubCanOpenURLWith:(BOOL)canOpenURL; + +/// Stubs `FBSDKSettings.appURLSchemeSuffix` and return the provided value +- (void)stubAppUrlSchemeSuffixWith:(nullable NSString *)suffix; + +/// Resets cached properties in `FBSDKSettings` +- (void)resetCachedSettings; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index eeba7ad2d7..747f13ec9d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -48,6 +48,21 @@ + (NSDate *)_lastRefreshTry; @interface FBSDKSettings (Testing) + (void)_logIfSDKSettingsChanged; ++ (void)resetLoggingBehaviorsCache; ++ (void)resetFacebookAppIDCache; ++ (void)resetFacebookUrlSchemeSuffixCache; ++ (void)resetFacebookClientTokenCache; ++ (void)resetFacebookDisplayNameCache; ++ (void)resetFacebookDomainPartCache; ++ (void)resetFacebookJpegCompressionQualityCache; ++ (void)resetFacebookAutoInitEnabledCache; ++ (void)resetFacebookInstrumentEnabledCache; ++ (void)resetFacebookAutoLogAppEventsEnabledCache; ++ (void)resetFacebookAdvertiserIDCollectionEnabledCache; ++ (void)resetAdvertiserTrackingStatusCache; ++ (void)resetUserAgentSuffixCache; ++ (void)resetFacebookCodelessDebugLogEnabledCache; ++ (void)resetDataProcessingOptionsCache; @end typedef void (^FBSDKSKAdNetworkReporterBlock)(void); @@ -87,6 +102,7 @@ - (void)setUp [self setUpGraphRequestConnectionClassMock]; [self setUpCrashShieldClassMock]; [self setUpNSDateClassMock]; + [self setUpSharedApplicationMock]; } - (void)tearDown @@ -167,6 +183,9 @@ - (void)tearDown [_nsDateClassMock stopMocking]; _nsDateClassMock = nil; + + [_sharedApplicationMock stopMocking]; + _sharedApplicationMock = nil; } - (void)setUpSettingsMock @@ -237,7 +256,7 @@ - (void)setUpSKAdNetworkMock - (void)setUpNSNotificationCenterMock { - self.nsNotificationCenterClassMock = OCMStrictClassMock(NSNotificationCenter.class); + self.nsNotificationCenterClassMock = OCMClassMock(NSNotificationCenter.class); } - (void)setUpMeasurementEventListenerMock @@ -295,6 +314,12 @@ - (void)setUpNSDateClassMock self.nsDateClassMock = OCMClassMock(NSDate.class); } +- (void)setUpSharedApplicationMock +{ + self.sharedApplicationMock = OCMClassMock(UIApplication.class); + OCMStub(ClassMethod([_sharedApplicationMock sharedApplication])).andReturn(_sharedApplicationMock); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID @@ -493,8 +518,42 @@ - (void)stubTimeIntervalSince1970WithTimeInterval:(NSTimeInterval)interval OCMStub([_nsDateClassMock timeIntervalSince1970]).andReturn(interval); } +- (void)stubFacebookDomainPartWith:(NSString *)domainPart +{ + OCMStub(ClassMethod([_settingsClassMock facebookDomainPart])).andReturn(domainPart); +} + +- (void)stubCanOpenURLWith:(BOOL)canOpenURL +{ + OCMStub([_sharedApplicationMock canOpenURL:OCMArg.any]).andReturn(canOpenURL); +} + +- (void)stubAppUrlSchemeSuffixWith:(NSString *)suffix +{ + OCMStub(ClassMethod([_settingsClassMock appURLSchemeSuffix])).andReturn(suffix); +} + // MARK: - Helpers +- (void)resetCachedSettings +{ + [FBSDKSettings resetLoggingBehaviorsCache]; + [FBSDKSettings resetFacebookAppIDCache]; + [FBSDKSettings resetFacebookUrlSchemeSuffixCache]; + [FBSDKSettings resetFacebookClientTokenCache]; + [FBSDKSettings resetFacebookDisplayNameCache]; + [FBSDKSettings resetFacebookDomainPartCache]; + [FBSDKSettings resetFacebookJpegCompressionQualityCache]; + [FBSDKSettings resetFacebookAutoInitEnabledCache]; + [FBSDKSettings resetFacebookInstrumentEnabledCache]; + [FBSDKSettings resetFacebookAutoLogAppEventsEnabledCache]; + [FBSDKSettings resetFacebookAdvertiserIDCollectionEnabledCache]; + [FBSDKSettings resetAdvertiserTrackingStatusCache]; + [FBSDKSettings resetUserAgentSuffixCache]; + [FBSDKSettings resetFacebookCodelessDebugLogEnabledCache]; + [FBSDKSettings resetDataProcessingOptionsCache]; +} + - (id)nsNullIfNil:(id)nilValue { id converted = nilValue; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m index 563dd31b92..9ddbfecb7c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralManager.m @@ -184,7 +184,7 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl if (isFacebookURL) { NSError *error; - NSDictionary *params = [FBSDKInternalUtility dictionaryFromFBURL:url]; + NSDictionary *params = [FBSDKInternalUtility parametersFromFBURL:url]; if (![self validateChallenge:params[ChalllengeKey]]) { error = [FBSDKError errorWithCode:FBSDKLoginErrorBadChallengeString diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m index 578db9154a..659c45b163 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m @@ -63,7 +63,7 @@ + (NSDictionary *)queryParamsFromLoginURL:(NSURL *)url return nil; } } - NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:[FBSDKInternalUtility dictionaryFromFBURL:url]]; + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:[FBSDKInternalUtility parametersFromFBURL:url]]; NSString *userID = [[self class] userIDFromSignedRequest:params[@"signed_request"]]; if (userID) { diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m index eae4d1b6e7..10bdb77c51 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m @@ -76,7 +76,7 @@ - (void)testReferralURL XCTAssertTrue([url.path hasSuffix:@"dialog/share_referral"]); - NSDictionary *params = [FBSDKInternalUtility dictionaryFromFBURL:url]; + NSDictionary *params = [FBSDKInternalUtility parametersFromFBURL:url]; NSString *appID = params[@"app_id"]; NSString *redirectURI = params[@"redirect_uri"]; NSString *challenge = params[@"state"]; From 764e626a091cb48d24678dd28f69a468294045a7 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Mon, 9 Nov 2020 15:09:30 -0800 Subject: [PATCH 085/227] Commit Xcode's auto update fix of BuildAllKits.xcscheme Summary: Anytime the BuildAllKits scheme is opened Xcode removes this reference, which most likely indicates that the reference is invalid / not needed. Also was under the TestAction section in Xcode, and tests in Xcode continue to run correctly. Reviewed By: joesus Differential Revision: D24840010 fbshipit-source-id: 09347b02f2f2e3a4812cc34cf9a8b150c91e3987 --- .../xcshareddata/xcschemes/BuildAllKits.xcscheme | 9 --------- 1 file changed, 9 deletions(-) diff --git a/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme b/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme index a2eacf429b..affdd215b3 100644 --- a/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme +++ b/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme @@ -111,15 +111,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - From be3253789363ff6100fd7b9ec92fbf609ff27b18 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Mon, 9 Nov 2020 15:25:49 -0800 Subject: [PATCH 086/227] Convert FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m to Swift Summary: Converted FBSDKAppLinkUtilityTests.m to Swift The FBSDKCoreKitTests-Bridging-Header.h file already existed but wasn't included in the project. Added it to the "Supporting Files" group and added a build configuration reference to it in FBSDKCoreKitTests.xcconfig Also added a test for isMatchURLScheme to ensure that NSBundle.mainBundle could be mocked in Swift. Reviewed By: joesus Differential Revision: D24766482 fbshipit-source-id: dacc5eab7e3603d88a8863bca5411ac73e168939 --- .../Configurations/FBSDKCoreKitTests.xcconfig | 2 + .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 ++-- .../FBSDKAppLinkUtilityTests.m | 44 ---------------- .../FBSDKAppLinkUtilityTests.swift | 50 +++++++++++++++++++ .../FBSDKCoreKitTests-Bridging-Header.h | 3 ++ 5 files changed, 61 insertions(+), 48 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.swift diff --git a/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig b/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig index d7205af39b..596e98b4fb 100644 --- a/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig +++ b/FBSDKCoreKit/Configurations/FBSDKCoreKitTests.xcconfig @@ -28,3 +28,5 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.0 HEADER_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) LIBRARY_SEARCH_PATHS = $(inherited) $(BUILT_PRODUCTS_DIR) + +SWIFT_OBJC_BRIDGING_HEADER = FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 149013de20..2c045a8fb3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -66,7 +66,7 @@ 0384CEBB208E60660013D404 /* FBSDKAccessTokenExpirer.m in Sources */ = {isa = PBXBuildFile; fileRef = 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */; }; 0384CED0208E606A0013D404 /* FBSDKAccessTokenExpirer.m in Sources */ = {isa = PBXBuildFile; fileRef = 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */; }; 0384CED1208E606B0013D404 /* FBSDKAccessTokenExpirer.m in Sources */ = {isa = PBXBuildFile; fileRef = 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */; }; - 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */; }; + 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift */; }; 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */; }; 45540D9125271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 45540D9225271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1202,7 +1202,7 @@ /* Begin PBXFileReference section */ 033429B020894D4700C94913 /* FBSDKAccessTokenExpirer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessTokenExpirer.h; sourceTree = ""; }; 033429B120894D4700C94913 /* FBSDKAccessTokenExpirer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessTokenExpirer.m; sourceTree = ""; }; - 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkUtilityTests.m; sourceTree = ""; }; + 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBSDKAppLinkUtilityTests.swift; sourceTree = ""; }; 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValueTests.m; sourceTree = ""; }; 45540D8F25271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppLinkResolverRequestBuilder.h; sourceTree = ""; }; 45540D9025271A4B008E853E /* FBSDKAppLinkResolverRequestBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppLinkResolverRequestBuilder.m; sourceTree = ""; }; @@ -1235,6 +1235,7 @@ 52963AAA2159A16E00C7B252 /* FBSDKMeasurementEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMeasurementEvent.h; sourceTree = ""; }; 52963AAB2159A16E00C7B252 /* FBSDKMeasurementEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMeasurementEvent.m; sourceTree = ""; }; 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleUserProfile.swift; sourceTree = ""; }; + 5C59531F25548690000D0A3C /* FBSDKCoreKitTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKCoreKitTests-Bridging-Header.h"; sourceTree = ""; }; 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsTests.m; sourceTree = ""; }; 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestTests.m; sourceTree = ""; }; 5D411318229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterManager.m; sourceTree = ""; }; @@ -2312,7 +2313,7 @@ 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.m */, 893F44A41A644552001DB0B6 /* Internal */, 9D2697571A5DF40700143BFC /* Supporting Files */, - 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m */, + 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift */, 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */, ); path = FBSDKCoreKitTests; @@ -2321,6 +2322,7 @@ 9D2697571A5DF40700143BFC /* Supporting Files */ = { isa = PBXGroup; children = ( + 5C59531F25548690000D0A3C /* FBSDKCoreKitTests-Bridging-Header.h */, 9D2697581A5DF40700143BFC /* Info.plist */, ); name = "Supporting Files"; @@ -4115,7 +4117,7 @@ 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */, F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */, F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */, - 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.m in Sources */, + 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift in Sources */, F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */, 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */, F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m deleted file mode 100644 index df1a6a8623..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.m +++ /dev/null @@ -1,44 +0,0 @@ -// 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 "FBSDKAppLinkUtility.h" - -@interface FBSDKURLAppInvitesTests : XCTestCase -@end - -@implementation FBSDKURLAppInvitesTests - -- (void)testWithNoPromoCode -{ - NSURL *url = [NSURL URLWithString:@"myapp://somelink/?someparam=somevalue"]; - id promoCode = [FBSDKAppLinkUtility appInvitePromotionCodeFromURL:url]; - XCTAssertNil(promoCode); -} - -- (void)testWithPromoCode -{ - NSURL *url = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22deeplink_context%22%3A%22%7B%5C%22promo_code%5C%22%3A%5C%22PROMOWORKS%5C%22%7D%22%7D%7D"]; - NSString *promoCode = [FBSDKAppLinkUtility appInvitePromotionCodeFromURL:url]; - XCTAssertNotNil(promoCode); - XCTAssertEqualObjects(promoCode, @"PROMOWORKS"); -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.swift new file mode 100644 index 0000000000..75984a2331 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAppLinkUtilityTests.swift @@ -0,0 +1,50 @@ +// 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 FBSDKCoreKit + +class FBSDKAppLinkUtilityTests: FBSDKTestCase { + func testWithNoPromoCode() { + let url = URL(string: "myapp://somelink/?someparam=somevalue")! // swiftlint:disable:this force_unwrapping + let promoCode = AppLinkUtility.appInvitePromotionCode(from: url) + XCTAssertNil(promoCode) + } + + func testWithPromoCode() { + let url = URL(string: "myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22deeplink_context%22%3A%22%7B%5C%22promo_code%5C%22%3A%5C%22PROMOWORKS%5C%22%7D%22%7D%7D")! // swiftlint:disable:this line_length force_unwrapping + let promoCode = AppLinkUtility.appInvitePromotionCode(from: url) + XCTAssertNotNil(promoCode) + XCTAssertEqual(promoCode, "PROMOWORKS") + } + + func testIsMatchURLScheme() { + let bundleDict = [ + "CFBundleURLTypes": [ + [ + "CFBundleURLSchemes": ["fb123"] + ] + ] + ] + + let fakeBundle = FakeBundle(dictionary: bundleDict) + stubMainBundle(with: fakeBundle) + + XCTAssertTrue(AppLinkUtility.isMatchURLScheme("fb123")) + XCTAssertFalse(AppLinkUtility.isMatchURLScheme("not_in_url_schemes")) + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 21d5f8989f..d01b167f56 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -17,3 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import + +#import "FBSDKTestCase.h" +#import "FakeBundle.h" From 34f895cf5d2a114c8d74f1ac40fe9f82ae94abf7 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Mon, 9 Nov 2020 16:12:06 -0800 Subject: [PATCH 087/227] Convert the SampleAppEvents test helper to Swift Summary: Converted the SampleAppEvents test helper to Swift Reviewed By: joesus Differential Revision: D24811441 fbshipit-source-id: 5b2f81474c898c5c31d4c4827c0df190acfca836 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +++--- .../AppEvents/FBSDKAppEventsStateTests.m | 1 - .../Internal/Helpers/SampleAppEvents.h | 32 ------------------- ...ampleAppEvents.m => SampleAppEvents.swift} | 25 ++++++--------- 4 files changed, 13 insertions(+), 55 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{SampleAppEvents.m => SampleAppEvents.swift} (79%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 2c045a8fb3..2f33866c43 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -906,7 +906,7 @@ F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */; }; F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */; }; F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; - F496E58F24E49DBC006231A2 /* SampleAppEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.m */; }; + F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */; }; F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.m */; }; F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */; }; @@ -1556,8 +1556,7 @@ F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDefaultsSpy.h; sourceTree = ""; }; F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainStoreSpy.m; sourceTree = ""; }; F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; - F496E58D24E49DBC006231A2 /* SampleAppEvents.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SampleAppEvents.h; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h; sourceTree = SOURCE_ROOT; }; - F496E58E24E49DBC006231A2 /* SampleAppEvents.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SampleAppEvents.m; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m; sourceTree = SOURCE_ROOT; }; + F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; F496E5FC24E5D0D5006231A2 /* FakeAccessTokenCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeAccessTokenCache.h; sourceTree = ""; }; F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeAccessTokenCache.m; sourceTree = ""; }; F496E60D24E5D195006231A2 /* SampleAccessToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleAccessToken.h; sourceTree = ""; }; @@ -2645,8 +2644,7 @@ F4CD7CDA243E2CF7004C27F1 /* Helpers */ = { isa = PBXGroup; children = ( - F496E58D24E49DBC006231A2 /* SampleAppEvents.h */, - F496E58E24E49DBC006231A2 /* SampleAppEvents.m */, + F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */, F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */, F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */, F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */, @@ -4097,7 +4095,7 @@ F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */, 7E55573C1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m in Sources */, 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */, - F496E58F24E49DBC006231A2 /* SampleAppEvents.m in Sources */, + F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */, 9D18A8DB1A95405A00A41042 /* FBSDKAppEventsStateTests.m in Sources */, F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */, F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m index 33cf86b2e3..ac5359b0f8 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsStateTests.m @@ -23,7 +23,6 @@ #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKInternalUtility.h" #import "FBSDKTestCase.h" -#import "SampleAppEvents.h" #define FBSDK_APPEVENTSSTATE_MAX_EVENTS 1000 diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h deleted file mode 100644 index 260816864a..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.h +++ /dev/null @@ -1,32 +0,0 @@ -// 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 - -NS_ASSUME_NONNULL_BEGIN - -@interface SampleAppEvents : NSObject - -@property (class, readonly, copy) NSDictionary *invalidEvent; -@property (class, readonly, copy) NSDictionary *validEvent; - -+ (NSDictionary *)validEventWithName:(NSString *)name; - -@end - -NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift similarity index 79% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift index 324bd98553..84f9e223ec 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift @@ -16,23 +16,16 @@ // 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 "SampleAppEvents.h" +import Foundation -@implementation SampleAppEvents +@objcMembers +public class SampleAppEvents: NSObject { -+ (id)invalidEvent -{ - return @1; -} - -+ (NSDictionary *)validEvent -{ - return @{ @"_eventName" : @"event1" }; -} + public static var validEvent: [String: String] { + return ["_eventName": "event1"] + } -+ (NSDictionary *)validEventWithName:(NSString *)name -{ - return @{ @"_eventName" : name }; + public static func validEvent(withName name: String) -> [String: String] { + return ["_eventName": name] + } } - -@end From f3685be157d310868757bfef21e21d0d858e338f Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Mon, 9 Nov 2020 20:20:55 -0800 Subject: [PATCH 088/227] Fix warnings: "nil returned from a method that is expected to return a non-null value" Summary: Fixed the warnings Reviewed By: joesus Differential Revision: D24814470 fbshipit-source-id: e40d4656912d69f138cb88c168a3c8c7671c760e --- FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h | 2 +- FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h index 67783a7cb5..05ab81a451 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.h @@ -43,7 +43,7 @@ NS_SWIFT_NAME(ReferralCode) A code is valid if it is non-empty and contains only alphanumeric characters. @param string the raw string referral code */ -+ (instancetype)initWithString:(NSString *)string; ++ (nullable instancetype)initWithString:(NSString *)string; @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m index 50feb792d6..5375d5997d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKReferralCode.m @@ -26,7 +26,7 @@ @implementation FBSDKReferralCode -+ (instancetype)initWithString:(NSString *)string ++ (nullable instancetype)initWithString:(NSString *)string { if (string.length == 0) { return nil; From 8d9f9e49bb7a2a5bff5435c8572f5b4138906412 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 10 Nov 2020 12:46:05 -0800 Subject: [PATCH 089/227] Unit test hardening - FBSDKInternalUtility 2/n Summary: Adding more tests. Also moving away from dispatch_once in favor of global static vars since otherwise a lot of this is genuinely untestable. Reviewed By: jawwad Differential Revision: D24836226 fbshipit-source-id: 9f6a4de5022078a492377ed6346189018fc41c9b --- .../Internal/FBSDKInternalUtility.m | 73 ++++- .../Internal/FBSDKInternalUtilityTests.m | 288 +++++++++++++++++- .../Internal/Helpers/FBSDKTestCase.h | 3 + .../Internal/Helpers/FBSDKTestCase.m | 9 + .../Internal/Helpers/FakeBundle.h | 3 + .../Internal/Helpers/FakeBundle.m | 10 + 6 files changed, 369 insertions(+), 17 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index c44940849d..16a4b6dafb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -40,6 +40,13 @@ typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionShift) { @implementation FBSDKInternalUtility +// These are stored at the class level so that they can be reset in unit tests +static dispatch_once_t *fetchApplicationQuerySchemesToken; +static dispatch_once_t *checkIfFacebookAppInstalledToken; +static dispatch_once_t *checkIfMessengerAppInstalledToken; +static dispatch_once_t *checkIfMSQRDPlayerAppInstalledToken; +static dispatch_once_t *checkRegisteredCanOpenUrlSchemesToken; + static BOOL ShouldOverrideHostWithGamingDomain(NSString *hostPrefix) { return @@ -372,8 +379,9 @@ + (UIViewController *)viewControllerForView:(UIView *)view + (BOOL)isFacebookAppInstalled { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ + static dispatch_once_t once_token; + checkIfFacebookAppInstalledToken = &once_token; + dispatch_once(&once_token, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; }); return [self _canOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; @@ -381,8 +389,9 @@ + (BOOL)isFacebookAppInstalled + (BOOL)isMessengerAppInstalled { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ + static dispatch_once_t once_token; + checkIfMessengerAppInstalledToken = &once_token; + dispatch_once(&once_token, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MESSENGER]; }); return [self _canOpenURLScheme:FBSDK_CANOPENURL_MESSENGER]; @@ -390,8 +399,9 @@ + (BOOL)isMessengerAppInstalled + (BOOL)isMSQRDPlayerAppInstalled { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ + static dispatch_once_t once_token; + checkIfMSQRDPlayerAppInstalledToken = &once_token; + dispatch_once(&once_token, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MSQRD_PLAYER]; }); return [self _canOpenURLScheme:FBSDK_CANOPENURL_MSQRD_PLAYER]; @@ -593,10 +603,11 @@ + (BOOL)isRegisteredURLScheme:(NSString *)urlScheme + (void)checkRegisteredCanOpenURLScheme:(NSString *)urlScheme { - static dispatch_once_t initCheckedSchemesOnce; static NSMutableSet *checkedSchemes = nil; - dispatch_once(&initCheckedSchemesOnce, ^{ + static dispatch_once_t once_token; + checkRegisteredCanOpenUrlSchemesToken = &once_token; + dispatch_once(&once_token, ^{ checkedSchemes = [NSMutableSet set]; }); @@ -616,10 +627,11 @@ + (void)checkRegisteredCanOpenURLScheme:(NSString *)urlScheme + (BOOL)isRegisteredCanOpenURLScheme:(NSString *)urlScheme { - static dispatch_once_t fetchBundleOnce; static NSArray *schemes = nil; - dispatch_once(&fetchBundleOnce, ^{ + static dispatch_once_t once_token; + fetchApplicationQuerySchemesToken = &once_token; + dispatch_once(&once_token, ^{ schemes = [[NSBundle mainBundle].infoDictionary valueForKey:@"LSApplicationQueriesSchemes"]; }); @@ -644,4 +656,45 @@ + (BOOL)isUnity return NO; } +#pragma mark - Testability + +#if DEBUG + ++ (void)resetQuerySchemesCache +{ + if (fetchApplicationQuerySchemesToken) { + *fetchApplicationQuerySchemesToken = 0; + } +} + ++ (void)resetDidCheckRegisteredCanOpenUrlSchemes +{ + if (checkRegisteredCanOpenUrlSchemesToken) { + *checkRegisteredCanOpenUrlSchemesToken = 0; + } +} + ++ (void)resetIsFacebookAppInstalledCache +{ + if (checkIfFacebookAppInstalledToken) { + *checkIfFacebookAppInstalledToken = 0; + } +} + ++ (void)resetDidCheckIfMessengerAppInstalledCache +{ + if (checkIfMessengerAppInstalledToken) { + *checkIfMessengerAppInstalledToken = 0; + } +} + ++ (void)resetDidCheckIfMSQRDAppInstalledCache +{ + if (checkIfMSQRDPlayerAppInstalledToken) { + *checkIfMSQRDPlayerAppInstalledToken = 0; + } +} + +#endif + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m index ea41ad5af0..6b97b73781 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m @@ -24,10 +24,16 @@ #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKInternalUtility.h" #import "FBSDKTestCase.h" +#import "FakeBundle.h" @interface FBSDKInternalUtility (Testing) + (BOOL)_canOpenURLScheme:(NSString *)scheme; ++ (void)resetQuerySchemesCache; ++ (void)resetDidCheckRegisteredCanOpenUrlSchemes; ++ (void)resetIsFacebookAppInstalledCache; ++ (void)resetDidCheckIfMessengerAppInstalledCache; ++ (void)resetDidCheckIfMSQRDAppInstalledCache; @end @@ -45,6 +51,11 @@ - (void)setUp [self resetCachedSettings]; + [FBSDKInternalUtility resetQuerySchemesCache]; + [FBSDKInternalUtility resetIsFacebookAppInstalledCache]; + [FBSDKInternalUtility resetDidCheckIfMessengerAppInstalledCache]; + [FBSDKInternalUtility resetDidCheckIfMSQRDAppInstalledCache]; + [FBSDKInternalUtility resetDidCheckRegisteredCanOpenUrlSchemes]; [FBSDKInternalUtility deleteFacebookCookies]; } @@ -422,7 +433,7 @@ - (void)testAppUrlWithEmptyHost [self stubAppID:self.appID]; [self stubAppUrlSchemeSuffixWith:@"foo"]; - NSURL *url = [FBSDKInternalUtility appURLWithHost:@"" path:self.validPath queryParameters:self.validParameters error:nil]; + NSURL *url = [FBSDKInternalUtility appURLWithHost:@"" path:validPath queryParameters:self.validParameters error:nil]; XCTAssertNil(url.host, "Should not set an empty host."); } @@ -432,7 +443,7 @@ - (void)testAppUrlWithValidHost [self stubAppID:self.appID]; [self stubAppUrlSchemeSuffixWith:@"foo"]; - NSURL *url = [FBSDKInternalUtility appURLWithHost:@"facebook" path:self.validPath queryParameters:self.validParameters error:nil]; + NSURL *url = [FBSDKInternalUtility appURLWithHost:@"facebook" path:validPath queryParameters:self.validParameters error:nil]; XCTAssertEqualObjects(url.host, @"facebook", "Should set the expected host."); } @@ -601,6 +612,269 @@ - (void)testDeletingMixOfCookies ); } +// MARK: - App Installation + +- (void)testIsRegisteredCanOpenURLSchemeWithMissingScheme +{ + NSArray *querySchemes = @[]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse( + [FBSDKInternalUtility isRegisteredCanOpenURLScheme:self.name], + "Should not be consider a scheme to be registered if it's missing from the application query schemes" + ); +} + +- (void)testIsRegisteredCanOpenURLSchemeWithScheme +{ + NSArray *querySchemes = @[self.name]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue( + [FBSDKInternalUtility isRegisteredCanOpenURLScheme:self.name], + "Should consider a scheme to be registered if it exists in the application query schemes" + ); +} + +- (void)testIsRegisteredCanOpenURLSchemeCache +{ + NSArray *querySchemes = @[self.name]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue([FBSDKInternalUtility isRegisteredCanOpenURLScheme:self.name], "Sanity check"); + + [bundle setInfoDictionary:@{}]; + + XCTAssertTrue([FBSDKInternalUtility isRegisteredCanOpenURLScheme:self.name], "Should return the cached value of the main bundle and not the updated values"); +} + +- (void)testFacebookAppInstalledMissingQuerySchemes +{ + id bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isFacebookAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:facebookUrlSchemeMissingMessage]); +} + +- (void)testFacebookAppInstalledEmptyQuerySchemes +{ + NSArray *querySchemes = @[]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isFacebookAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:facebookUrlSchemeMissingMessage]); +} + +- (void)testFacebookAppInstalledMissingQueryScheme +{ + NSArray *querySchemes = @[@"Foo"]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isFacebookAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:facebookUrlSchemeMissingMessage]); +} + +- (void)testFacebookAppInstalledValidQueryScheme +{ + NSArray *querySchemes = @[@"fbauth2"]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + + [FBSDKInternalUtility isFacebookAppInstalled]; +} + +- (void)testFacebookAppInstalledCache +{ + id bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isFacebookAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:facebookUrlSchemeMissingMessage]); + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + + [FBSDKInternalUtility isFacebookAppInstalled]; +} + +- (void)testMessengerAppInstalledMissingQuerySchemes +{ + id bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMessengerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:messengerUrlSchemeMissingMessage]); +} + +- (void)testMessengerAppInstalledEmptyQuerySchemes +{ + NSArray *querySchemes = @[]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMessengerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:messengerUrlSchemeMissingMessage]); +} + +- (void)testMessengerAppInstalledMissingQueryScheme +{ + NSArray *querySchemes = @[@"Foo"]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMessengerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:messengerUrlSchemeMissingMessage]); +} + +- (void)testMessengerAppInstalledValidQueryScheme +{ + NSArray *querySchemes = @[@"fb-messenger-share-api"]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + + [FBSDKInternalUtility isMessengerAppInstalled]; +} + +- (void)testMessengerAppInstalledCache +{ + id bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMessengerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:messengerUrlSchemeMissingMessage]); + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + + [FBSDKInternalUtility isMessengerAppInstalled]; +} + +- (void)testMSQRDPlayerAppInstalledMissingQuerySchemes +{ + id bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMSQRDPlayerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:msqrdPlayerUrlSchemeMissingMessage]); +} + +- (void)testMSQRDPlayerAppInstalledEmptyQuerySchemes +{ + NSArray *querySchemes = @[]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMSQRDPlayerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:msqrdPlayerUrlSchemeMissingMessage]); +} + +- (void)testMSQRDPlayerAppInstalledMissingQueryScheme +{ + NSArray *querySchemes = @[@"Foo"]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMSQRDPlayerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:msqrdPlayerUrlSchemeMissingMessage]); +} + +- (void)testMSQRDPlayerAppInstalledValidQueryScheme +{ + NSArray *querySchemes = @[@"msqrdplayer"]; + id bundle = [FakeBundle bundleWithDictionary:@{@"LSApplicationQueriesSchemes" : querySchemes}]; + [self stubMainBundleWith:bundle]; + + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + + [FBSDKInternalUtility isMSQRDPlayerAppInstalled]; +} + +- (void)testMSQRDPlayerAppInstalledCache +{ + id bundle = [FakeBundle bundleWithDictionary:@{}]; + [self stubMainBundleWith:bundle]; + + [FBSDKInternalUtility isMSQRDPlayerAppInstalled]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:msqrdPlayerUrlSchemeMissingMessage]); + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + + [FBSDKInternalUtility isMSQRDPlayerAppInstalled]; +} + +// MARK: - Random Utility Methods + +- (void)testIsBrowserURLWithNonBrowserURL +{ + NSArray *urls = @[ + [NSURL URLWithString:@"file://foo"], + [NSURL URLWithString:@"example://bar"] + ]; + + for (NSURL *url in urls) { + XCTAssertFalse([FBSDKInternalUtility isBrowserURL:url], "%@ should not be considered a browser url", url.absoluteString); + } +} + +- (void)testIsBrowserURLWithBrowserURL +{ + NSArray *urls = @[ + [NSURL URLWithString:@"HTTPS://example.com"], + [NSURL URLWithString:@"HTTP://example.com"], + [NSURL URLWithString:@"https://example.com"], + [NSURL URLWithString:@"http://example.com"], + ]; + + for (NSURL *url in urls) { + XCTAssertTrue([FBSDKInternalUtility isBrowserURL:url], "%@ should be considered a browser url", url.absoluteString); + } +} + +- (void)testIsFacebookBundleIdentifierWithInvalidIdentifiers +{ + NSArray *identifiers = @[ + @"", + @"foo", + @"com.foo.bar", + @"com.facebook" + ]; + + for (NSString *identifier in identifiers) { + XCTAssertFalse([FBSDKInternalUtility isFacebookBundleIdentifier:identifier], "%@ should not be considered a facebook bundle indentifier", identifier); + } +} + +- (void)testIsFacebookBundleIdentifierWithValidIdentifiers +{ + NSArray *identifiers = @[ + @"com.facebook.", + @"com.facebook.foo", + @".com.facebook.", + @".com.facebook.foo" + ]; + + for (NSString *identifier in identifiers) { + XCTAssertTrue([FBSDKInternalUtility isFacebookBundleIdentifier:identifier], "%@ should be considered a facebook bundle indentifier", identifier); + } +} + // MARK: - Helpers - (NSURL *)dialogUrl @@ -634,14 +908,14 @@ - (NSHTTPCookie *)cookieForUrl:(NSURL *)url return [self cookieForUrl:url name:@"MyCookie"]; } -- (NSString *)validPath -{ - return @"example"; -} - - (NSDictionary *)validParameters { return @{@"foo" : @"bar"}; } +NSString *const validPath = @"example"; +NSString *const facebookUrlSchemeMissingMessage = @"fbauth2 is missing from your Info.plist under LSApplicationQueriesSchemes and is required."; +NSString *const messengerUrlSchemeMissingMessage = @"fb-messenger-share-api is missing from your Info.plist under LSApplicationQueriesSchemes and is required."; +NSString *const msqrdPlayerUrlSchemeMissingMessage = @"msqrdplayer is missing from your Info.plist under LSApplicationQueriesSchemes and is required."; + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 60b9949753..6b717fbafd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -133,6 +133,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `UIApplication.sharedApplication` mock between tests @property (nullable, nonatomic, assign) id sharedApplicationMock; +/// Used for sharing a `FBSDKLogger` class mock between tests +@property (nullable, nonatomic, assign) id loggerClassMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 747f13ec9d..f4b323ceb9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -103,6 +103,7 @@ - (void)setUp [self setUpCrashShieldClassMock]; [self setUpNSDateClassMock]; [self setUpSharedApplicationMock]; + [self setUpLoggerClassMock]; } - (void)tearDown @@ -186,6 +187,9 @@ - (void)tearDown [_sharedApplicationMock stopMocking]; _sharedApplicationMock = nil; + + [_loggerClassMock stopMocking]; + _loggerClassMock = nil; } - (void)setUpSettingsMock @@ -320,6 +324,11 @@ - (void)setUpSharedApplicationMock OCMStub(ClassMethod([_sharedApplicationMock sharedApplication])).andReturn(_sharedApplicationMock); } +- (void)setUpLoggerClassMock +{ + self.loggerClassMock = OCMClassMock(FBSDKLogger.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h index 6282247bd2..9cf0d08ca6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.h @@ -26,6 +26,9 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)bundleWithDictionary:(NSDictionary *)dictionary; +/// Overrides the current value set for the `infoDictionary` property with the new value +- (void)setInfoDictionary:(NSDictionary *)newValue; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m index ae214110df..0bc93096c6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBundle.m @@ -39,6 +39,16 @@ + (instancetype)bundleWithDictionary:(NSDictionary *)dictionary return [[FakeBundle alloc] initWithDictionary:dictionary]; } +- (NSDictionary *)infoDictionary +{ + return [_dictionary copy]; +} + +- (void)setInfoDictionary:(NSDictionary *)newValue +{ + _dictionary = newValue; +} + - (id)objectForInfoDictionaryKey:(NSString *)key { if (!_capturedKeys) { From df8c6addd20d2e47b9ed8bab96c773013ad091f9 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 10 Nov 2020 12:46:05 -0800 Subject: [PATCH 090/227] Unit test hardening - FBSDKInternalUtility 3/n Summary: Simplifies os version checking since the minimum supported version is 9.0. The removed code was a workaround for pre-8.0. Removed: `getMajorVersionFromFullLibraryVersion` `isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version` Additionally adds more unit tests around internal utility. Just arbitrarily trying to break this into digestible chunks. Reviewed By: jawwad Differential Revision: D24846033 fbshipit-source-id: 1df9658d168566e58922b80eb22dffc6395cfb09 --- .../GraphAPI/FBSDKGraphRequestConnection.m | 2 +- .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 4 +- .../Internal/FBSDKInternalUtility.h | 7 - .../Internal/FBSDKInternalUtility.m | 91 ++---- .../Internal/FBSDKInternalUtilityTests.m | 306 ++++++++++++++++++ .../Internal/Helpers/FBSDKTestCase.h | 3 + .../Internal/Helpers/FBSDKTestCase.m | 5 + .../Internal/FBSDKVideoUploader.m | 2 +- .../Internal/FBSDKLoginManagerLogger.m | 2 +- .../FBSDKShareKit/FBSDKShareDialog.m | 14 +- .../FBSDKShareDialogTests.m | 18 -- 11 files changed, 349 insertions(+), 105 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m index f95b6a86e3..4540173ad1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m @@ -1033,7 +1033,7 @@ - (void)_taskDidCompleteWithError:(NSError *)error @try { if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == kCFURLErrorSecureConnectionFailed) { NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; - if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]) { + if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS9Version]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"WARNING: FBSDK secure network request failed. Please verify you have configured your " "app for Application Transport Security compatibility described at https://developers.facebook.com/docs/ios/ios9"]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 0cc83ae657..dbe36b528d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -260,7 +260,7 @@ - (void)openURL:(NSURL *)url sender:(id)sender handler:(FBSDKSu dispatch_async(dispatch_get_main_queue(), ^{ // Dispatch openURL calls to prevent hangs if we're inside the current app delegate's openURL flow already NSOperatingSystemVersion iOS10Version = { .majorVersion = 10, .minorVersion = 0, .patchVersion = 0 }; - if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS10Version]) { + if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS10Version]) { if (@available(iOS 10.0, *)) { [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) { handler(success, nil); @@ -271,7 +271,7 @@ - (void)openURL:(NSURL *)url sender:(id)sender handler:(FBSDKSu if ([url.scheme hasPrefix:@"http"] && !opened) { NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; - if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { + if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS8Version]) { // Safari openURL calls can wrongly return NO on iOS 7 so manually overwrite that case to YES. // Otherwise we would rather trust in the actual result of openURL opened = YES; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h index a4e72d9a9d..2a3bd210cc 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h @@ -138,13 +138,6 @@ NS_SWIFT_NAME(InternalUtility) */ + (BOOL)isFacebookBundleIdentifier:(NSString *)bundleIdentifier; -/** - Tests whether the operating system is at least the specified version. - @param version The version to test against. - @return YES if the operating system is greater than or equal to the specified version, otherwise NO. - */ -+ (BOOL)isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version; - /** Tests whether the supplied bundle identifier references the Safari app. @param bundleIdentifier The bundle identifier to test. diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 16a4b6dafb..594f264bf7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -46,6 +46,8 @@ @implementation FBSDKInternalUtility static dispatch_once_t *checkIfMessengerAppInstalledToken; static dispatch_once_t *checkIfMSQRDPlayerAppInstalledToken; static dispatch_once_t *checkRegisteredCanOpenUrlSchemesToken; +static dispatch_once_t *checkOperatingSystemVersionToken; +static dispatch_once_t *fetchUrlSchemesToken; static BOOL ShouldOverrideHostWithGamingDomain(NSString *hostPrefix) { @@ -212,30 +214,12 @@ + (BOOL)isFacebookBundleIdentifier:(NSString *)bundleIdentifier || [bundleIdentifier hasPrefix:@".com.facebook."]); } -+ (BOOL)isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version -{ - return ([self _compareOperatingSystemVersion:[self operatingSystemVersion] toVersion:version] != NSOrderedAscending); -} - + (BOOL)isSafariBundleIdentifier:(NSString *)bundleIdentifier { return ([bundleIdentifier isEqualToString:@"com.apple.mobilesafari"] || [bundleIdentifier isEqualToString:@"com.apple.SafariViewService"]); } -+ (int32_t)getMajorVersionFromFullLibraryVersion:(int32_t)version -{ - // Negative values returned by NSVersionOfRunTimeLibrary/NSVersionOfLinkTimeLibrary - // are still valid version numbers, as long as it's not -1. - // After bitshift by 16, the negatives become valid positive major version number. - // We ran into this first time with iOS 12. - if (version != -1) { - return ((version & FBSDKInternalUtilityMajorVersionMask) >> FBSDKInternalUtilityMajorVersionShift); - } else { - return 0; - } -} - + (BOOL)object:(id)object isEqualToObject:(id)other { if (object == other) { @@ -254,25 +238,10 @@ + (NSOperatingSystemVersion)operatingSystemVersion .minorVersion = 0, .patchVersion = 0, }; - static dispatch_once_t getVersionOnce; - dispatch_once(&getVersionOnce, ^{ - if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) { - operatingSystemVersion = [NSProcessInfo processInfo].operatingSystemVersion; - } else { - NSArray *components = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; - switch (components.count) { - default: - case 3: - operatingSystemVersion.patchVersion = [[FBSDKTypeUtility array:components objectAtIndex:2] integerValue]; - // fall through - case 2: - operatingSystemVersion.minorVersion = [[FBSDKTypeUtility array:components objectAtIndex:1] integerValue]; - // fall through - case 1: - operatingSystemVersion.majorVersion = [[FBSDKTypeUtility array:components objectAtIndex:0] integerValue]; - break; - } - } + static dispatch_once_t once_token; + checkOperatingSystemVersionToken = &once_token; + dispatch_once(&once_token, ^{ + operatingSystemVersion = [NSProcessInfo processInfo].operatingSystemVersion; }); return operatingSystemVersion; } @@ -290,9 +259,12 @@ + (NSURL *)URLWithScheme:(NSString *)scheme NSString *queryString = nil; if (queryParameters.count) { NSError *queryStringError; - queryString = [@"?" stringByAppendingString:[FBSDKBasicUtility queryStringWithDictionary:queryParameters - error:&queryStringError - invalidObjectHandler:NULL]]; + NSString *queryStringFromParams = [FBSDKBasicUtility queryStringWithDictionary:queryParameters + error:&queryStringError + invalidObjectHandler:NULL]; + if (queryStringFromParams) { + queryString = [@"?" stringByAppendingString:queryStringFromParams]; + } if (!queryString) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"queryParameters" @@ -409,26 +381,6 @@ + (BOOL)isMSQRDPlayerAppInstalled #pragma mark - Helper Methods -+ (NSComparisonResult)_compareOperatingSystemVersion:(NSOperatingSystemVersion)version1 - toVersion:(NSOperatingSystemVersion)version2 -{ - if (version1.majorVersion < version2.majorVersion) { - return NSOrderedAscending; - } else if (version1.majorVersion > version2.majorVersion) { - return NSOrderedDescending; - } else if (version1.minorVersion < version2.minorVersion) { - return NSOrderedAscending; - } else if (version1.minorVersion > version2.minorVersion) { - return NSOrderedDescending; - } else if (version1.patchVersion < version2.patchVersion) { - return NSOrderedAscending; - } else if (version1.patchVersion > version2.patchVersion) { - return NSOrderedDescending; - } else { - return NSOrderedSame; - } -} - + (BOOL)_canOpenURLScheme:(NSString *)scheme { scheme = [FBSDKTypeUtility stringValue:scheme]; @@ -586,10 +538,11 @@ + (NSString *)hexadecimalStringFromData:(NSData *)data + (BOOL)isRegisteredURLScheme:(NSString *)urlScheme { - static dispatch_once_t fetchBundleOnce; static NSArray *urlTypes = nil; - dispatch_once(&fetchBundleOnce, ^{ + static dispatch_once_t once_token; + fetchUrlSchemesToken = &once_token; + dispatch_once(&once_token, ^{ urlTypes = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleURLTypes"]; }); for (NSDictionary *urlType in urlTypes) { @@ -695,6 +648,20 @@ + (void)resetDidCheckIfMSQRDAppInstalledCache } } ++ (void)resetDidCheckOperatingSystemVersion +{ + if (checkOperatingSystemVersionToken) { + *checkOperatingSystemVersionToken = 0; + } +} + ++ (void)resetFetchingUrlSchemes +{ + if (fetchUrlSchemesToken) { + *fetchUrlSchemesToken = 0; + } +} + #endif @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m index 6b97b73781..82a4d2b0db 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKInternalUtilityTests.m @@ -34,6 +34,8 @@ + (void)resetDidCheckRegisteredCanOpenUrlSchemes; + (void)resetIsFacebookAppInstalledCache; + (void)resetDidCheckIfMessengerAppInstalledCache; + (void)resetDidCheckIfMSQRDAppInstalledCache; ++ (void)resetDidCheckOperatingSystemVersion; ++ (void)resetFetchingUrlSchemes; @end @@ -56,6 +58,8 @@ - (void)setUp [FBSDKInternalUtility resetDidCheckIfMessengerAppInstalledCache]; [FBSDKInternalUtility resetDidCheckIfMSQRDAppInstalledCache]; [FBSDKInternalUtility resetDidCheckRegisteredCanOpenUrlSchemes]; + [FBSDKInternalUtility resetDidCheckOperatingSystemVersion]; + [FBSDKInternalUtility resetFetchingUrlSchemes]; [FBSDKInternalUtility deleteFacebookCookies]; } @@ -875,6 +879,299 @@ - (void)testIsFacebookBundleIdentifierWithValidIdentifiers } } +- (void)testNonSafariBundleIdentifiers +{ + NSArray *identifiers = @[ + @"", + @" ", + @"com.foo" + ]; + + for (NSString *identifier in identifiers) { + XCTAssertFalse( + [FBSDKInternalUtility isSafariBundleIdentifier:identifier], + "%@ should not be considered a safari bundle identifier", + identifier + ); + } +} + +- (void)testSafariBundleIdentifiers +{ + NSArray *identifiers = @[ + @"com.apple.mobilesafari", + @"com.apple.SafariViewService", + ]; + + for (NSString *identifier in identifiers) { + XCTAssertTrue( + [FBSDKInternalUtility isSafariBundleIdentifier:identifier], + "%@ should be considered a safari bundle identifier", + identifier + ); + } +} + +- (void)testValidatingAppID +{ + [self stubAppID:nil]; + + XCTAssertThrows([FBSDKInternalUtility validateAppID]); +} + +- (void)testValidateClientAccessTokenWithoutClientTokenWithoutAppID +{ + [self stubAppID:nil]; + [self stubClientTokenWith:nil]; + + XCTAssertThrows([FBSDKInternalUtility validateRequiredClientAccessToken]); +} + +- (void)testValidateClientAccessTokenWithClientTokenWithoutAppID +{ + [self stubAppID:nil]; + [self stubClientTokenWith:@"client123"]; + + XCTAssertEqualObjects( + [FBSDKInternalUtility validateRequiredClientAccessToken], + @"(null)|client123", + "A valid client-access token should include the app identifier and the client token" + ); +} + +- (void)testValidateClientAccessTokenWithClientTokenWithAppID +{ + [self stubAppID:self.appID]; + [self stubClientTokenWith:@"client123"]; + + XCTAssertEqualObjects( + [FBSDKInternalUtility validateRequiredClientAccessToken], + @"appid|client123", + "A valid client-access token should include the app identifier and the client token" + ); +} + +- (void)testValidateClientAccessTokenWithoutClientTokenWithAppID +{ + [self stubAppID:self.appID]; + [self stubClientTokenWith:nil]; + + XCTAssertThrows([FBSDKInternalUtility validateRequiredClientAccessToken]); +} + +- (void)testIsRegisteredUrlSchemeWithRegisteredScheme +{ + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"com.foo.bar"]]; + [self stubMainBundleWith:bundle]; + + XCTAssertTrue([FBSDKInternalUtility isRegisteredURLScheme:@"com.foo.bar"], "Schemes in the bundle should be considered registered"); +} + +- (void)testIsRegisteredUrlSchemeWithoutRegisteredScheme +{ + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"com.foo.bar"]]; + [self stubMainBundleWith:bundle]; + + XCTAssertFalse([FBSDKInternalUtility isRegisteredURLScheme:@"com.facebook"], "Schemes absent from the bundle should not be considered registered"); +} + +- (void)testIsRegisteredUrlSchemeCaching +{ + // Should fetch bundle + [FBSDKInternalUtility isRegisteredURLScheme:@"com.facebook"]; + + OCMVerify(ClassMethod([self.nsBundleClassMock mainBundle])); + OCMReject(ClassMethod([self.nsBundleClassMock mainBundle])); + + // Should not fetch bundle + [FBSDKInternalUtility isRegisteredURLScheme:@"com.facebook"]; +} + +- (void)testValidatingUrlSchemesWithoutAppID +{ + [self stubAppID:nil]; + + XCTAssertThrows( + [FBSDKInternalUtility validateURLSchemes], + "Cannot validate url schemes without an app identifier" + ); +} + +- (void)testValidatingUrlSchemesWithAppIdMatchingBundleEntry +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:nil]; + + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"fbappid"]]; + [self stubMainBundleWith:bundle]; + + XCTAssertNoThrow( + [FBSDKInternalUtility validateURLSchemes], + "The registered app url scheme must match the app id and url scheme suffix prepended with 'fb'" + ); +} + +- (void)testValidatingUrlSchemesWithNonAppIdMatchingBundleEntry +{ + [self stubAppID:self.appID]; + [self stubAppUrlSchemeSuffixWith:nil]; + + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"fb123"]]; + [self stubMainBundleWith:bundle]; + + XCTAssertThrows( + [FBSDKInternalUtility validateURLSchemes], + "The registered app url scheme must match the app id and url scheme suffix prepended with 'fb'" + ); +} + +// We can't loop through these because of how stubbing works. +- (void)testValidatingFacebookUrlSchemes_auth +{ + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"fbauth2"]]; + [self stubMainBundleWith:bundle]; + XCTAssertThrows([FBSDKInternalUtility validateFacebookReservedURLSchemes], "Should throw an error if fbauth2 is present in the bundle url schemes"); +} + +// We can't loop through these because of how stubbing works. +- (void)testValidatingFacebookUrlSchemes_api +{ + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"fbapi"]]; + [self stubMainBundleWith:bundle]; + XCTAssertThrows([FBSDKInternalUtility validateFacebookReservedURLSchemes], "Should throw an error if fbapi is present in the bundle url schemes"); +} + +// We can't loop through these because of how stubbing works. +- (void)testValidatingFacebookUrlSchemes_messenger +{ + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"fb-messenger-share-api"]]; + [self stubMainBundleWith:bundle]; + XCTAssertThrows([FBSDKInternalUtility validateFacebookReservedURLSchemes], "Should throw an error if fb-messenger-share-api is present in the bundle url schemes"); +} + +// We can't loop through these because of how stubbing works. +- (void)testValidatingFacebookUrlSchemes_shareextension +{ + FakeBundle *bundle = [self bundleWithRegisteredUrlSchemes:@[@"fbshareextension"]]; + [self stubMainBundleWith:bundle]; + XCTAssertThrows([FBSDKInternalUtility validateFacebookReservedURLSchemes], "Should throw an error if fbshareextension is present in the bundle url schemes"); +} + +- (void)testIsPublishPermission +{ + NSArray *publishPermissions = @[ + @"publish", + @"publishSomething", + @"manage", + @"manageSomething", + @"ads_management", + @"create_event", + @"rsvp_event" + ]; + for (NSString *permission in publishPermissions) { + XCTAssertTrue([FBSDKInternalUtility isPublishPermission:permission]); + } + + NSArray *nonPublishPermissions = @[ + @"", + @"email", + @"_publish" + ]; + for (NSString *permission in nonPublishPermissions) { + XCTAssertFalse([FBSDKInternalUtility isPublishPermission:permission]); + } +} + +- (void)testIsUnityWithMissingSuffix +{ + [self stubUserAgentSuffixWith:nil]; + XCTAssertFalse([FBSDKInternalUtility isUnity], "User agent should determine whether an app is Unity"); +} + +- (void)testIsUnityWithNonUnitySuffix +{ + [self stubUserAgentSuffixWith:@"Foo"]; + XCTAssertFalse([FBSDKInternalUtility isUnity], "User agent should determine whether an app is Unity"); +} + +- (void)testIsUnityWithUnitySuffix +{ + [self stubUserAgentSuffixWith:@"__Unity__"]; + XCTAssertTrue([FBSDKInternalUtility isUnity], "User agent should determine whether an app is Unity"); +} + +- (void)testHexadecimalStringFromData +{ + XCTAssertNil([FBSDKInternalUtility hexadecimalStringFromData:NSData.data]); + + NSString *foo = @"foo"; + NSData *stringData = [foo dataUsingEncoding:NSUTF8StringEncoding]; + NSString *expected = @"666f6f"; + + XCTAssertEqualObjects([FBSDKInternalUtility hexadecimalStringFromData:stringData], expected); +} + +- (void)testObjectIsEqualToObject +{ + id obj1 = @"foo"; + id obj2 = @"foo"; + id obj3 = @"bar"; + + XCTAssertTrue([FBSDKInternalUtility object:obj1 isEqualToObject:obj1]); + XCTAssertTrue([FBSDKInternalUtility object:obj1 isEqualToObject:obj2]); + XCTAssertFalse([FBSDKInternalUtility object:obj1 isEqualToObject:obj3]); + + obj1 = nil; + XCTAssertFalse([FBSDKInternalUtility object:obj1 isEqualToObject:obj2]); + XCTAssertFalse([FBSDKInternalUtility object:obj2 isEqualToObject:obj1]); +} + +- (void)testCreatingUrlWithUnknownError // InvalidQueryString +{ + NSError *error = [NSError errorWithDomain:@"test" code:1 userInfo:nil]; + + [FBSDKInternalUtility URLWithScheme:@"https" host:@"example" path:@"/foo" queryParameters:@{@"a date" : NSDate.date} error:&error]; + + XCTAssertEqualObjects( + error.domain, + @"com.facebook.sdk.core", + "Creating a url with an error reference should repopulate the error domain correctly" + ); + XCTAssertEqual( + error.code, + 3, + "Creating a url with an error reference should repopulate the error code correctly" + ); + XCTAssertEqualObjects( + [error.userInfo objectForKey:FBSDKErrorDeveloperMessageKey], + @"Unknown error building URL.", + "Creating a url with an error reference should repopulate the error message correctly" + ); +} + +- (void)testCreatingUrlWithInvalidQueryString +{ + NSError *error = [NSError errorWithDomain:@"test" code:1 userInfo:nil]; + + [FBSDKInternalUtility URLWithScheme:@"https" host:@"example" path:@"/foo" queryParameters:@{@[] : @"foo"} error:&error]; + + XCTAssertEqualObjects( + error.domain, + @"com.facebook.sdk.core", + "Creating a url with invalid parameters should repopulate the error domain correctly" + ); + XCTAssertEqual( + error.code, + 2, + "Creating a url with invalid parameters should repopulate the error code correctly" + ); + + XCTAssertTrue( + [[error.userInfo objectForKey:FBSDKErrorDeveloperMessageKey] hasPrefix:@"Invalid value for queryParameters:"], + "Creating a url with invalid parameters should repopulate the error message correctly" + ); +} + // MARK: - Helpers - (NSURL *)dialogUrl @@ -918,4 +1215,13 @@ - (NSDictionary *)validParameters NSString *const messengerUrlSchemeMissingMessage = @"fb-messenger-share-api is missing from your Info.plist under LSApplicationQueriesSchemes and is required."; NSString *const msqrdPlayerUrlSchemeMissingMessage = @"msqrdplayer is missing from your Info.plist under LSApplicationQueriesSchemes and is required."; +- (FakeBundle *)bundleWithRegisteredUrlSchemes:(NSArray *)schemes +{ + return [FakeBundle bundleWithDictionary:@{ + @"CFBundleURLTypes" : @[ + @{ @"CFBundleURLSchemes" : schemes } + ] + }]; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 6b717fbafd..6f04eb97e2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -266,6 +266,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Resets cached properties in `FBSDKSettings` - (void)resetCachedSettings; +/// Stubs `FBSDKSettings.userAgentSuffix` and returns the provided value +- (void)stubUserAgentSuffixWith:(nullable NSString *)suffix; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index f4b323ceb9..f39d4d063b 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -542,6 +542,11 @@ - (void)stubAppUrlSchemeSuffixWith:(NSString *)suffix OCMStub(ClassMethod([_settingsClassMock appURLSchemeSuffix])).andReturn(suffix); } +- (void)stubUserAgentSuffixWith:(nullable NSString *)suffix +{ + OCMStub(ClassMethod([self.settingsClassMock userAgentSuffix])).andReturn(suffix); +} + // MARK: - Helpers - (void)resetCachedSettings diff --git a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m index 5199abc732..24579b2e5f 100644 --- a/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m +++ b/FBSDKGamingServicesKit/FBSDKGamingServicesKit/Internal/FBSDKVideoUploader.m @@ -125,7 +125,7 @@ - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictiona { dispatch_queue_t dataQueue; NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; - if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { + if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS8Version]) { dataQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0); } else { dataQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m index 524ff57157..a345eab3ef 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m @@ -186,7 +186,7 @@ - (void)willAttemptAppSwitchingBehavior - (void)logNativeAppDialogResult:(BOOL)result dialogDuration:(NSTimeInterval)dialogDuration { NSOperatingSystemVersion iOS10Version = { .majorVersion = 10, .minorVersion = 0, .patchVersion = 0 }; - if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS10Version]) { + if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS10Version]) { [FBSDKTypeUtility dictionary:_extras setObject:@(dialogDuration) forKey:@"native_app_login_dialog_duration"]; [FBSDKTypeUtility dictionary:_extras setObject:@(result) forKey:@"native_app_login_dialog_result"]; [self logEvent:FBSDKAppEventNameFBSessionFASLoginDialogResult params:[self _parametersForNewEvent]]; diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m index 6a3168d3f5..881cac690e 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m @@ -336,7 +336,7 @@ - (BOOL)_canShowShareSheet // iOS 11 returns NO for `isAvailableForServiceType` but it will still work NSString *facebookServiceType = fbsdkdfl_SLServiceTypeFacebook(); NSOperatingSystemVersion iOS11Version = { .majorVersion = 11, .minorVersion = 0, .patchVersion = 0 }; - if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS11Version] && ![composeViewControllerClass isAvailableForServiceType:facebookServiceType]) { + if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS11Version] && ![composeViewControllerClass isAvailableForServiceType:facebookServiceType]) { return NO; } return YES; @@ -344,10 +344,6 @@ - (BOOL)_canShowShareSheet - (BOOL)_canAttributeThroughShareSheet { - NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; - if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { - return NO; - } FBSDKShareDialogValidateAPISchemeRegisteredForCanOpenUrl(); NSString *scheme = FBSDK_CANOPENURL_FBAPI; NSString *minimumVersion = FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION; @@ -360,10 +356,6 @@ - (BOOL)_canAttributeThroughShareSheet - (BOOL)_canUseFBShareSheet { - NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; - if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { - return NO; - } FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanOpenUrl(); NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = FBSDK_CANOPENURL_SHARE_EXTENSION; @@ -383,10 +375,6 @@ - (BOOL)_canUseMMPInShareSheet - (BOOL)_supportsShareSheetMinimumVersion:(NSString *)minimumVersion { - NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; - if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { - return NO; - } FBSDKShareDialogValidateAPISchemeRegisteredForCanOpenUrl(); NSString *scheme = FBSDK_CANOPENURL_FBAPI; NSURLComponents *components = [[NSURLComponents alloc] init]; diff --git a/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m b/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m index 6871241227..85902a3caa 100644 --- a/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m +++ b/FBSDKShareKit/FBSDKShareKitTests/FBSDKShareDialogTests.m @@ -428,7 +428,6 @@ - (void)testThatInitialTextIsSetCorrectlyWhenShareExtensionIsAvailable NSDictionary *expectedJSON = @{@"app_id" : @"appID", @"hashtags" : @[@"#hashtag"], @"quotes" : @[@"a quote"]}; [self _showDialog:dialog appID:@"appID" - shareSheetAvailable:YES expectedPreJSONtext:@"fb-app-id:appID #hashtag" expectedJSON:expectedJSON]; } @@ -510,18 +509,6 @@ - (void)testShowCameraShareToFBWhenPlayerNotInstalled #pragma mark - FullyCompatible Validation -- (void)testThatInitialTextIsSetCorrectlyWhenShareExtensionIsNOTAvailable -{ - FBSDKShareDialog *const dialog = [[FBSDKShareDialog alloc] init]; - FBSDKShareLinkContent *content = [FBSDKShareModelTestUtility linkContentWithoutQuote]; - content.hashtag = [FBSDKHashtag hashtagWithString:@"#hashtag"]; - dialog.shareContent = content; - [self _showDialog:dialog - appID:@"appID" - shareSheetAvailable:NO - expectedPreJSONtext:@"#hashtag" expectedJSON:nil]; -} - - (void)testThatValidateWithErrorReturnsNOForLinkQuoteIfAValidShareExtensionVersionIsNotAvailable { [self _testValidateShareContent:[FBSDKShareModelTestUtility linkContent] @@ -580,9 +567,7 @@ - (void)_testValidateShareContent:(id)shareContent [[[mockApplication stub] andReturnValue:@YES] canOpenURL:[OCMArg checkWithBlock:^BOOL (NSURL *url) { return ![url.absoluteString isEqualToString:nonSupportedScheme]; }]]; - NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; id mockInternalUtility = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[mockInternalUtility stub] andReturnValue:@YES] isOSRunTimeVersionAtLeast:iOS8Version]; id mockSLController = [OCMockObject niceMockForClass:[fbsdkdfl_SLComposeViewControllerClass() class]]; [[[mockSLController stub] andReturn:mockSLController] composeViewControllerForServiceType:OCMOCK_ANY]; [[[mockSLController stub] andReturnValue:@YES] isAvailableForServiceType:OCMOCK_ANY]; @@ -609,16 +594,13 @@ - (void)_testValidateShareContent:(id)shareContent - (void) _showDialog:(FBSDKShareDialog *)dialog appID:(NSString *)appID - shareSheetAvailable:(BOOL)shareSheetAvailable expectedPreJSONtext:(NSString *)expectedPreJSONText expectedJSON:(NSDictionary *)expectedJSON { id mockApplication = [OCMockObject niceMockForClass:[UIApplication class]]; [[[mockApplication stub] andReturn:mockApplication] sharedApplication]; [[[mockApplication stub] andReturnValue:@YES] canOpenURL:OCMOCK_ANY]; - NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; id mockInternalUtility = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[mockInternalUtility stub] andReturnValue:@(shareSheetAvailable)] isOSRunTimeVersionAtLeast:iOS8Version]; id settingsClassMock = [OCMockObject niceMockForClass:[FBSDKSettings class]]; [[[settingsClassMock stub] andReturn:appID] appID]; id mockSLController = [OCMockObject niceMockForClass:[fbsdkdfl_SLComposeViewControllerClass() class]]; From cf5e425fa5a757e48f46bccbbae090573aa37965 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Tue, 10 Nov 2020 14:55:18 -0800 Subject: [PATCH 091/227] Convert the FakeAccessTokenCache test helper to Swift (#1572) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1572 Converted FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m/h to Swift Reviewed By: joesus Differential Revision: D24848401 fbshipit-source-id: b004cdcc1774edc2b9d0d90175122e2e36a03d0f --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 ++-- FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m | 2 +- .../FBSDKApplicationDelegateTests.m | 1 + .../Internal/Helpers/FBSDKTestCase.h | 3 +- .../Internal/Helpers/FakeAccessTokenCache.m | 49 ------------------- ...okenCache.h => FakeAccessTokenCache.swift} | 21 ++++---- 6 files changed, 19 insertions(+), 67 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{FakeAccessTokenCache.h => FakeAccessTokenCache.swift} (80%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 2f33866c43..9da5006e32 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -907,7 +907,7 @@ F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */; }; F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; - F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */; }; + F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */; }; F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.m */; }; F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */; }; F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */; }; @@ -1557,8 +1557,7 @@ F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainStoreSpy.m; sourceTree = ""; }; F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; - F496E5FC24E5D0D5006231A2 /* FakeAccessTokenCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeAccessTokenCache.h; sourceTree = ""; }; - F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeAccessTokenCache.m; sourceTree = ""; }; + F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAccessTokenCache.swift; sourceTree = ""; }; F496E60D24E5D195006231A2 /* SampleAccessToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleAccessToken.h; sourceTree = ""; }; F496E60E24E5D195006231A2 /* SampleAccessToken.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAccessToken.m; sourceTree = ""; }; F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegateObserverFake.h; sourceTree = ""; }; @@ -2657,8 +2656,7 @@ F40B24C124732DD90059351C /* Fuzzer.swift */, F4DE31F424DB695100297C18 /* FBSDKTestCase.h */, F4DE31F524DB695100297C18 /* FBSDKTestCase.m */, - F496E5FC24E5D0D5006231A2 /* FakeAccessTokenCache.h */, - F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.m */, + F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */, F496E60D24E5D195006231A2 /* SampleAccessToken.h */, F496E60E24E5D195006231A2 /* SampleAccessToken.m */, F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */, @@ -4149,7 +4147,7 @@ F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, E493252D23F7C60E0000B63A /* FBSDKModelParserTests.mm in Sources */, - F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.m in Sources */, + F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */, F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */, 5D68D7D822BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m in Sources */, 9D3AF4661A9ED47900EEF724 /* FBSDKGraphRequestConnectionTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m index b8c50da038..cd18a7c825 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m @@ -133,7 +133,7 @@ + (void)setCurrentAccessToken:(FBSDKAccessToken *)token [FBSDKAccessToken setCurrentAccessToken:token shouldDispatchNotif:YES]; } -+ (void)setCurrentAccessToken:(FBSDKAccessToken *)token ++ (void)setCurrentAccessToken:(nullable FBSDKAccessToken *)token shouldDispatchNotif:(BOOL)shouldDispatchNotif { if (token != g_currentAccessToken) { diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index c9beddc51c..f1458b217c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -24,6 +24,7 @@ #import "AppDelegateObserverFake.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "SampleAccessToken.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 6f04eb97e2..029db81aba 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -28,7 +28,8 @@ #import "FBSDKProfile+Internal.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" -#import "FakeAccessTokenCache.h" + +@class FakeAccessTokenCache; NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m deleted file mode 100644 index 5722a06261..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.m +++ /dev/null @@ -1,49 +0,0 @@ -// 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 "FakeAccessTokenCache.h" - -@implementation FakeAccessTokenCache -{ - FBSDKAccessToken *_accessToken; -} - -- (instancetype)initWithToken:(FBSDKAccessToken *__nullable)token -{ - if ((self = [super init])) { - _accessToken = token; - } - return self; -} - -- (FBSDKAccessToken *)accessToken -{ - return _accessToken; -} - -- (void)setAccessToken:(FBSDKAccessToken *)token -{ - _accessToken = token; -} - -- (void)clearCache -{ - // noop for now -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.swift similarity index 80% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.swift index 996cf6f25e..f168912843 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.swift @@ -16,16 +16,17 @@ // 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 FBSDKCoreKit -#import "FBSDKAccessTokenCaching.h" +@objcMembers +public class FakeAccessTokenCache: NSObject, AccessTokenCaching { + public var accessToken: AccessToken? -NS_ASSUME_NONNULL_BEGIN + public init(token: AccessToken?) { + accessToken = token + } -@interface FakeAccessTokenCache : NSObject - -- (instancetype)initWithToken:(FBSDKAccessToken *__nullable)token; - -@end - -NS_ASSUME_NONNULL_END + public func clearCache() { + // noop for now + } +} From 18acb8ea5d8c749ebaedfd93bc525f7b10c40c5f Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Tue, 10 Nov 2020 14:55:18 -0800 Subject: [PATCH 092/227] Convert the SampleAccessToken test helper to Swift (#1573) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1573 Converted the SampleAccessToken test helper to Swift Reviewed By: joesus Differential Revision: D24848733 fbshipit-source-id: 0500cc8213840347edd925b8ab7c4150c312f68d --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 ++- .../FBSDKApplicationDelegateTests.m | 1 - .../FBSDKCoreKitTests/FBSDKProfileTests.m | 1 - .../Internal/AppEvents/FBSDKAppEventsTests.m | 2 +- .../Internal/Helpers/SampleAccessToken.h | 35 ---------- .../Internal/Helpers/SampleAccessToken.m | 64 ------------------ .../Internal/Helpers/SampleAccessToken.swift | 67 +++++++++++++++++++ .../FBSDKGraphRequestPiggybackManagerTests.m | 1 - 8 files changed, 72 insertions(+), 109 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 9da5006e32..ee0c62b71a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -908,7 +908,7 @@ F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */; }; - F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.m */; }; + F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.swift */; }; F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */; }; F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */; }; F4A52AFE242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A52AFC242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h */; }; @@ -1558,8 +1558,7 @@ F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAccessTokenCache.swift; sourceTree = ""; }; - F496E60D24E5D195006231A2 /* SampleAccessToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleAccessToken.h; sourceTree = ""; }; - F496E60E24E5D195006231A2 /* SampleAccessToken.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAccessToken.m; sourceTree = ""; }; + F496E60E24E5D195006231A2 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegateObserverFake.h; sourceTree = ""; }; F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegateObserverFake.m; sourceTree = ""; }; F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTypeUtility.h; sourceTree = ""; }; @@ -2657,8 +2656,7 @@ F4DE31F424DB695100297C18 /* FBSDKTestCase.h */, F4DE31F524DB695100297C18 /* FBSDKTestCase.m */, F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */, - F496E60D24E5D195006231A2 /* SampleAccessToken.h */, - F496E60E24E5D195006231A2 /* SampleAccessToken.m */, + F496E60E24E5D195006231A2 /* SampleAccessToken.swift */, F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */, F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */, F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */, @@ -4112,7 +4110,7 @@ F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */, 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */, F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */, - F496E60F24E5D195006231A2 /* SampleAccessToken.m in Sources */, + F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */, 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift in Sources */, F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */, 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index f1458b217c..d636d1585c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -27,7 +27,6 @@ #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" -#import "SampleAccessToken.h" #import "UserDefaultsSpy.h" @interface FBSDKApplicationDelegate (Testing) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index 1b4cb2bcdf..803de7a3f8 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -24,7 +24,6 @@ #import "FBSDKProfile.h" #import "FBSDKProfile+Internal.h" #import "FBSDKTestCase.h" -#import "SampleAccessToken.h" @interface FBSDKSettings (Testing) + (void)resetFacebookClientTokenCache; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index 2a06647c8f..4a6ad276d2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -28,6 +28,7 @@ #import "FBSDKAppEventsUtility.h" #import "FBSDKApplicationDelegate.h" #import "FBSDKConstants.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKGateKeeperManager.h" #import "FBSDKGraphRequest.h" #import "FBSDKGraphRequest+Internal.h" @@ -37,7 +38,6 @@ #import "FBSDKSettings.h" #import "FBSDKTestCase.h" #import "FBSDKUtility.h" -#import "SampleAccessToken.h" #import "UserDefaultsSpy.h" static NSString *const _mockAppID = @"mockAppID"; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h deleted file mode 100644 index b359f50abd..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.h +++ /dev/null @@ -1,35 +0,0 @@ -// 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 "FBSDKAccessToken.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface SampleAccessToken : NSObject - -+ (FBSDKAccessToken *)validToken; -+ (FBSDKAccessToken *)validTokenWithPermissions:(NSArray *)permissions - declinedPermissions:(NSArray *)declinedPermissions - expiredPermissions:(NSArray *)expiredPermissions; -+ (FBSDKAccessToken *)validWithRefreshDate:(NSDate *)date; - -@end - -NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m deleted file mode 100644 index fde86d8502..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.m +++ /dev/null @@ -1,64 +0,0 @@ -// 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 "SampleAccessToken.h" - -@implementation SampleAccessToken - -+ (FBSDKAccessToken *)validToken -{ - return [[FBSDKAccessToken alloc] initWithTokenString:@"123" - permissions:@[] - declinedPermissions:@[] - expiredPermissions:@[] - appID:@"123" - userID:@"user123" - expirationDate:nil - refreshDate:nil - dataAccessExpirationDate:nil]; -} - -+ (FBSDKAccessToken *)validWithRefreshDate:(NSDate *)date -{ - return [[FBSDKAccessToken alloc] initWithTokenString:@"123" - permissions:@[] - declinedPermissions:@[] - expiredPermissions:@[] - appID:@"123" - userID:@"user123" - expirationDate:nil - refreshDate:date - dataAccessExpirationDate:nil]; -} - -+ (FBSDKAccessToken *)validTokenWithPermissions:(NSArray *)permissions - declinedPermissions:(NSArray *)declinedPermissions - expiredPermissions:(NSArray *)expiredPermissions -{ - return [[FBSDKAccessToken alloc] initWithTokenString:@"123" - permissions:permissions - declinedPermissions:declinedPermissions - expiredPermissions:expiredPermissions - appID:@"123" - userID:@"user123" - expirationDate:nil - refreshDate:nil - dataAccessExpirationDate:nil]; -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift new file mode 100644 index 0000000000..0cd7fe2f16 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift @@ -0,0 +1,67 @@ +// 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. + +@objcMembers +public class SampleAccessToken: NSObject { + + public static var validToken: AccessToken { + return AccessToken( + tokenString: "123", + permissions: [], + declinedPermissions: [], + expiredPermissions: [], + appID: "123", + userID: "user123", + expirationDate: nil, + refreshDate: nil, + dataAccessExpirationDate: nil + ) + } + + public static func valid(withRefreshDate date: Date?) -> AccessToken { + return AccessToken( + tokenString: "123", + permissions: [], + declinedPermissions: [], + expiredPermissions: [], + appID: "123", + userID: "user123", + expirationDate: nil, + refreshDate: date, + dataAccessExpirationDate: nil + ) + } + + public static func validToken( + withPermissions permissions: [String], + declinedPermissions: [String], + expiredPermissions: [String] + ) -> AccessToken { + return AccessToken( + tokenString: "123", + permissions: permissions, + declinedPermissions: declinedPermissions, + expiredPermissions: expiredPermissions, + appID: "123", + userID: "user123", + expirationDate: nil, + refreshDate: nil, + dataAccessExpirationDate: nil + ) + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m index e2130445b5..1dac43590e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestPiggybackManagerTests.m @@ -23,7 +23,6 @@ #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" -#import "SampleAccessToken.h" @interface FBSDKAccessToken (Testing) + (void)resetCurrentAccessTokenCache; From 5a5222ab0bb55b16befcdd959630a0daac806381 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Wed, 11 Nov 2020 14:38:08 -0800 Subject: [PATCH 093/227] Bump Version: 8.2.0 Summary: As title Reviewed By: joesus Differential Revision: D24867556 fbshipit-source-id: 98f47c4cb87149295539b69acae5b6116d044c41 --- CHANGELOG.md | 11 ++++++++++- Configurations/Version.xcconfig | 2 +- FBSDKCoreKit.podspec | 2 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 2 +- FBSDKGamingServicesKit.podspec | 2 +- FBSDKLoginKit.podspec | 2 +- FBSDKShareKit.podspec | 2 +- FBSDKTVOSKit.podspec | 2 +- FacebookSDK.podspec | 2 +- Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 2 +- 10 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a0a50d3e..7cd45dd56a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Important -[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.1.0...HEAD) +[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.2.0...HEAD) + +## 8.2.0 + +### Changed +- Remove SignalHandler to avoid hiding root cause of crashes caused by fatal signals. +- Expose functions in `FBSDKUserDataStore` as public for apps using [Audience Network SDK](https://developers.facebook.com/docs/audience-network) only to use advanced matching. + +[2020-11-10](https://github.com/facebook/facebook-ios-sdk/releases/tag/v8.2.0) | +[Full Changelog](https://github.com/facebook/facebook-ios-sdk/compare/v8.1.0...v8.2.0) ## 8.1.0 diff --git a/Configurations/Version.xcconfig b/Configurations/Version.xcconfig index 70aaa27827..d1d10addd8 100644 --- a/Configurations/Version.xcconfig +++ b/Configurations/Version.xcconfig @@ -17,6 +17,6 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // The versions for FBSDK and Messenger SDK. -FBSDK_PROJECT_VERSION=8.1.0 +FBSDK_PROJECT_VERSION=8.2.0 MNSDK_PROJECT_VERSION=TODO_SUPPORT_MNSDK diff --git a/FBSDKCoreKit.podspec b/FBSDKCoreKit.podspec index 89442bf543..4460533659 100644 --- a/FBSDKCoreKit.podspec +++ b/FBSDKCoreKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKCoreKit' - s.version = '8.1.0' + s.version = '8.2.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform core features' s.description = <<-DESC diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 70cb07f361..1fc9b542d5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -100,5 +100,5 @@ #endif -#define FBSDK_VERSION_STRING @"8.1.0" +#define FBSDK_VERSION_STRING @"8.2.0" #define FBSDK_TARGET_PLATFORM_VERSION @"v8.0" diff --git a/FBSDKGamingServicesKit.podspec b/FBSDKGamingServicesKit.podspec index 0eeb0217a7..88e4d5ac0a 100644 --- a/FBSDKGamingServicesKit.podspec +++ b/FBSDKGamingServicesKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKGamingServicesKit' - s.version = '8.1.0' + s.version = '8.2.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Gaming Services' s.description = <<-DESC diff --git a/FBSDKLoginKit.podspec b/FBSDKLoginKit.podspec index a6fbaa8922..b314a6600b 100644 --- a/FBSDKLoginKit.podspec +++ b/FBSDKLoginKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKLoginKit' - s.version = '8.1.0' + s.version = '8.2.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 diff --git a/FBSDKShareKit.podspec b/FBSDKShareKit.podspec index bd7c2fa453..f7d4c38691 100644 --- a/FBSDKShareKit.podspec +++ b/FBSDKShareKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKShareKit' - s.version = '8.1.0' + s.version = '8.2.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform Sharing Features' s.description = <<-DESC diff --git a/FBSDKTVOSKit.podspec b/FBSDKTVOSKit.podspec index f73b45b298..feec9370b9 100644 --- a/FBSDKTVOSKit.podspec +++ b/FBSDKTVOSKit.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FBSDKTVOSKit' - s.version = '8.1.0' + s.version = '8.2.0' s.summary = 'Official Facebook SDK for tvOS to access Facebook Platform with features like Login and Graph API.' s.description = <<-DESC diff --git a/FacebookSDK.podspec b/FacebookSDK.podspec index 773317701a..bc7384d6db 100644 --- a/FacebookSDK.podspec +++ b/FacebookSDK.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.name = 'FacebookSDK' - s.version = '8.1.0' + s.version = '8.2.0' s.summary = 'Official Facebook SDK for iOS to access Facebook Platform' s.description = <<-DESC diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index ee430c43af..c33becb7c4 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -28,7 +28,7 @@ #define FBSDK_MAX_CRASH_LOGS 5 #define FBSDK_CRASH_PATH_NAME @"instrument" #ifndef FBSDK_VERSION_STRING - #define FBSDK_VERSION_STRING @"8.1.0" + #define FBSDK_VERSION_STRING @"8.2.0" #endif static NSUncaughtExceptionHandler *previousExceptionHandler = NULL; From 28a2aa293b8d630cd41135dd1f89068692fac41e Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Wed, 11 Nov 2020 14:55:22 -0800 Subject: [PATCH 094/227] Convert FBSDKEventDeactivationTests.m to Swift Summary: Converted FBSDKEventDeactivationTests.m to Swift Reviewed By: joesus Differential Revision: D24876214 fbshipit-source-id: a74411252d9cf30a540a9758043f2da440441403 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 +-- .../FBSDKCoreKitTests-Bridging-Header.h | 2 + .../FBSDKEventDeactivationTests.m | 62 ------------------ .../FBSDKEventDeactivationTests.swift | 63 +++++++++++++++++++ 4 files changed, 69 insertions(+), 66 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index ee0c62b71a..4fa24cbc48 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -168,7 +168,7 @@ 5D90CDE82343D4D200AF326A /* FBSDKCrashShield.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */; }; 5D90CDE92343D4D200AF326A /* FBSDKCrashShield.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */; }; 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB01F023A1831A005495FB /* FBSDKCrashObserverTests.m */; }; - 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.m */; }; + 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.swift */; }; 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB612A723593AB600150851 /* FBSDKCrashShieldTests.m */; }; 5DB7B07C230363190012E8CB /* FBSDKInstrumentManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB7B07B230363190012E8CB /* FBSDKInstrumentManager.h */; }; 5DB7B07D230363190012E8CB /* FBSDKInstrumentManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DB7B07B230363190012E8CB /* FBSDKInstrumentManager.h */; }; @@ -1253,7 +1253,7 @@ 5D90CDDE2343D4BD00AF326A /* FBSDKCrashShield.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashShield.m; sourceTree = ""; }; 5D90CDE52343D4D200AF326A /* FBSDKCrashShield.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKCrashShield.h; sourceTree = ""; }; 5DAB01F023A1831A005495FB /* FBSDKCrashObserverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashObserverTests.m; sourceTree = ""; }; - 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKEventDeactivationTests.m; sourceTree = ""; }; + 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKEventDeactivationTests.swift; sourceTree = ""; }; 5DB612A723593AB600150851 /* FBSDKCrashShieldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKCrashShieldTests.m; sourceTree = ""; }; 5DB7B07B230363190012E8CB /* FBSDKInstrumentManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKInstrumentManager.h; sourceTree = ""; }; 5DB7B08D2303632E0012E8CB /* FBSDKInstrumentManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKInstrumentManager.m; sourceTree = ""; }; @@ -1777,7 +1777,7 @@ 5DAB023A23A1B9FC005495FB /* EventDeactivation */ = { isa = PBXGroup; children = ( - 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.m */, + 5DAB023B23A1BA17005495FB /* FBSDKEventDeactivationTests.swift */, ); path = EventDeactivation; sourceTree = ""; @@ -4098,7 +4098,7 @@ E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */, F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */, BF5D97C3242EC2D10096D7AA /* FBSDKFeatureExtractorTests.m in Sources */, - 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.m in Sources */, + 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.swift in Sources */, 7E253D831A8EB76500CCCFE7 /* FBSDKCoreKitTestUtility.m in Sources */, 5D59BFFD23A705010008CA5A /* FBSDKCrashHandlerTests.m in Sources */, F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index d01b167f56..e4d639b8fd 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -18,5 +18,7 @@ #import +#import "FBSDKEventDeactivationManager.h" +#import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m deleted file mode 100644 index 1461080d1c..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.m +++ /dev/null @@ -1,62 +0,0 @@ -// 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 "FBSDKEventDeactivationManager.h" -#import "FBSDKRestrictiveDataFilterManager.h" -#import "FBSDKServerConfigurationFixtures.h" -#import "FBSDKTestCase.h" - -@interface FBSDKEventDeactivationTests : FBSDKTestCase -@end - -@implementation FBSDKEventDeactivationTests - -- (void)setUp -{ - [super setUp]; - - NSDictionary *events = @{ - @"fb_mobile_catalog_update" : @{ @"restrictive_param" : @{@"first_name" : @"6"}}, - @"manual_initiated_checkout" : @{ @"deprecated_param" : @[@"deprecated_3"]}, - }; - - FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationFixtures configWithDictionary:@{@"restrictiveParams" : events}]; - [self stubCachedServerConfigurationWithServerConfiguration:serverConfiguration]; - - [FBSDKEventDeactivationManager enable]; -} - -- (void)testProcessParameters -{ - NSDictionary *parameters = @{@"_ui" : @"UITabBarController", - @"_logTime" : @1576109848, - @"_session_id" : @"30AF582C-0225-40A4-B3EE-2A571AB926F3", - @"fb_mobile_launch_source" : @"Unclassified", - @"deprecated_3" : @"test", }; - NSDictionary *result = [FBSDKEventDeactivationManager processParameters:parameters eventName:@"manual_initiated_checkout"]; - XCTAssertNil(result[@"deprecated_3"]); - XCTAssertNotNil(result[@"_ui"]); - XCTAssertNotNil(result[@"_logTime"]); - XCTAssertNotNil(result[@"_session_id"]); - XCTAssertNotNil(result[@"fb_mobile_launch_source"]); -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.swift new file mode 100644 index 0000000000..f18d4d8aa3 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/EventDeactivation/FBSDKEventDeactivationTests.swift @@ -0,0 +1,63 @@ +// 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 XCTest + +class FBSDKEventDeactivationTests: FBSDKTestCase { + override func setUp() { + super.setUp() + + let events = [ + "fb_mobile_catalog_update": [ + "restrictive_param": ["first_name": "6"] + ], + "manual_initiated_checkout": [ + "deprecated_param": ["deprecated_3"] + ] + ] + + let serverConfiguration = FBSDKServerConfigurationFixtures.config(with: ["restrictiveParams": events]) + stubCachedServerConfiguration(with: serverConfiguration) + + FBSDKEventDeactivationManager.enable() + } + + func testProcessParameters() { + let parameters: [String: Any] = [ + "_ui": "UITabBarController", + "_logTime": 1_576_109_848, + "_session_id": "30AF582C-0225-40A4-B3EE-2A571AB926F3", + "fb_mobile_launch_source": "Unclassified", + "deprecated_3": "test", + ] + + guard let result = FBSDKEventDeactivationManager.processParameters( + parameters, + eventName: "manual_initiated_checkout" + ) else { + XCTFail("Result must not be nil") + return + } + + XCTAssertNil(result["deprecated_3"]) + XCTAssertNotNil(result["_ui"]) + XCTAssertNotNil(result["_logTime"]) + XCTAssertNotNil(result["_session_id"]) + XCTAssertNotNil(result["fb_mobile_launch_source"]) + } +} From cec98f40bac0d17dc9a3a29071eb7e1d5c5fd0d4 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 11 Nov 2020 21:25:50 -0800 Subject: [PATCH 095/227] FBSDKBridgeAPI Unit Tests 1/n Summary: The main point of interest here is probably that I created a separate header to declare some types that are only declared in `FBSDKBridgeAPI.m`. This seemed preferable to creating an internal header in the main project since it's only needed for tests. Normally would put these in the test file itself but it was becoming crowded. Reviewed By: jawwad Differential Revision: D24875594 fbshipit-source-id: 1ad072942e0487e31ceca56df6bd47feaf59334c --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 + .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 33 +++- .../FBSDKCoreKitTests-Bridging-Header.h | 1 + .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 178 ++++++++++++++++++ .../Helpers/AuthenticationSessionSpy.swift | 54 ++++++ .../Internal/Helpers/FBSDKBridgeAPI+Testing.h | 67 +++++++ 6 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AuthenticationSessionSpy.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 4fa24cbc48..6391a22691 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -788,6 +788,8 @@ E4416C1623F61917009CCBFA /* FBSDKModelParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4416C0023F61902009CCBFA /* FBSDKModelParser.mm */; }; E493252D23F7C60E0000B63A /* FBSDKModelParserTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = E493252C23F7C60E0000B63A /* FBSDKModelParserTests.mm */; }; E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4C2B97923867327002335A4 /* FBSDKModelRuntimeTests.mm */; }; + F402AFC8255B49A500473083 /* FBSDKBridgeAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */; }; + F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */; }; F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */; }; F40B24C224732DD90059351C /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24C124732DD90059351C /* Fuzzer.swift */; }; F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */; }; @@ -1516,6 +1518,9 @@ E4416C0023F61902009CCBFA /* FBSDKModelParser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FBSDKModelParser.mm; sourceTree = ""; }; E493252C23F7C60E0000B63A /* FBSDKModelParserTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FBSDKModelParserTests.mm; sourceTree = ""; }; E4C2B97923867327002335A4 /* FBSDKModelRuntimeTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FBSDKModelRuntimeTests.mm; sourceTree = ""; }; + F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBridgeAPITests.m; sourceTree = ""; }; + F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKBridgeAPI+Testing.h"; sourceTree = ""; }; + F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationSessionSpy.swift; sourceTree = ""; }; F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawServerConfigurationResponseFixtures.swift; sourceTree = ""; }; F40B24C124732DD90059351C /* Fuzzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntryTests.m; sourceTree = ""; }; @@ -2092,6 +2097,7 @@ isa = PBXGroup; children = ( 894C0B351A702DDD009137EF /* ProtocolVersions */, + F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */, ); path = BridgeAPI; sourceTree = ""; @@ -2642,6 +2648,7 @@ F4CD7CDA243E2CF7004C27F1 /* Helpers */ = { isa = PBXGroup; children = ( + F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */, F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */, F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */, F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */, @@ -2667,6 +2674,7 @@ F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */, F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */, 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */, + F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */, ); path = Helpers; sourceTree = ""; @@ -4102,6 +4110,7 @@ 7E253D831A8EB76500CCCFE7 /* FBSDKCoreKitTestUtility.m in Sources */, 5D59BFFD23A705010008CA5A /* FBSDKCrashHandlerTests.m in Sources */, F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */, + F402AFC8255B49A500473083 /* FBSDKBridgeAPITests.m in Sources */, C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */, F4E50155243648A100C99262 /* FBSDKServerConfigurationFixtures.m in Sources */, F4D8D8FA242293ED00C28384 /* FBSDKMonitorNetworkerTests.m in Sources */, @@ -4156,6 +4165,7 @@ F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */, F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m in Sources */, F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */, + F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */, F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */, F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */, ); diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index dbe36b528d..1a9a8be090 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -112,7 +112,9 @@ - (void)applicationDidBecomeActive:(UIApplication *)application errorDomain = @"com.apple.SafariServices.Authentication"; } NSError *error = [FBSDKError errorWithDomain:errorDomain code:1 message:nil]; - _authenticationSessionCompletionHandler(nil, error); + if (_authenticationSessionCompletionHandler) { + _authenticationSessionCompletionHandler(nil, error); + } isRequestingWebAuthenticationSession = [self _isRequestingWebAuthenticationSession]; } } @@ -530,6 +532,35 @@ - (UIWindow *)presentationAnchorForWebAuthenticationSession:(id)authenticationSession +{ + return _authenticationSession; +} + +- (void)setAuthenticationSession:(id)session +{ + _authenticationSession = session; +} + +- (FBSDKAuthenticationSession)authenticationSessionState +{ + return _authenticationSessionState; +} + +- (void)setAuthenticationSessionState:(FBSDKAuthenticationSession)state +{ + _authenticationSessionState = state; +} + +- (void)setAuthenticationSessionCompletionHandler:(FBSDKAuthenticationCompletionHandler)handler +{ + _authenticationSessionCompletionHandler = handler; +} + + #endif + @end #endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index e4d639b8fd..fc0528fa56 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -20,5 +20,6 @@ #import "FBSDKEventDeactivationManager.h" #import "FBSDKServerConfigurationFixtures.h" +#import "FBSDKBridgeAPI+Testing.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m new file mode 100644 index 0000000000..8afa5a62c8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -0,0 +1,178 @@ +// 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 + +#import "FBSDKBridgeAPI+Testing.h" +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" + +@interface FBSDKBridgeAPITests : FBSDKTestCase +@end + +@implementation FBSDKBridgeAPITests + +// MARK: - Lifecycle Methods + +- (void)testWillResignActiveWithoutAuthSessionWithoutAuthSessionState +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + [api applicationWillResignActive:UIApplication.sharedApplication]; + + XCTAssertEqual( + api.authenticationSessionState, + FBSDKAuthenticationSessionNone, + "Should not modify the auth session state if there is no auth session" + ); +} + +- (void)testWillResignActiveWithAuthSessionWithoutAuthSessionState +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + + [api applicationWillResignActive:UIApplication.sharedApplication]; + + XCTAssertEqual( + api.authenticationSessionState, + FBSDKAuthenticationSessionNone, + "Should not modify the auth session state unless the current state is 'started'" + ); +} + +- (void)testWillResignActiveWithAuthSessionWithNonStartedAuthSessionState +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + + NSArray *states = @[ + @(FBSDKAuthenticationSessionNone), + @(FBSDKAuthenticationSessionShowAlert), + @(FBSDKAuthenticationSessionShowWebBrowser), + @(FBSDKAuthenticationSessionCanceledBySystem) + ]; + + for (NSNumber *state in states) { + api.authenticationSessionState = state.intValue; + [api applicationWillResignActive:UIApplication.sharedApplication]; + XCTAssertEqual( + api.authenticationSessionState, + state.intValue, + "Should not modify the auth session state unless the current state is 'started'" + ); + } +} + +- (void)testWillResignActiveWithAuthSessionWithStartedAuthSessionState +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + + api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + [api applicationWillResignActive:UIApplication.sharedApplication]; + XCTAssertEqual( + api.authenticationSessionState, + FBSDKAuthenticationSessionShowAlert, + "Should change the auth state from 'started' to 'alert' before resigning activity" + ); +} + +- (void)testUpdatingShowAlertStateForDidBecomeActiveWithoutAuthSession +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + NSArray *states = @[ + @(FBSDKAuthenticationSessionNone), + @(FBSDKAuthenticationSessionStarted), + @(FBSDKAuthenticationSessionShowAlert), + @(FBSDKAuthenticationSessionShowWebBrowser), + @(FBSDKAuthenticationSessionCanceledBySystem) + ]; + + for (NSNumber *state in states) { + api.authenticationSessionState = state.intValue; + [api applicationDidBecomeActive:UIApplication.sharedApplication]; + XCTAssertEqual( + api.authenticationSessionState, + state.intValue, + "Should not modify the auth session state if there is no auth session" + ); + } +} + +- (void)testUpdatingShowAlertStateForDidBecomeActive +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; + api.authenticationSession = spy; + api.authenticationSessionState = FBSDKAuthenticationSessionShowAlert; + + [api applicationDidBecomeActive:UIApplication.sharedApplication]; + + XCTAssertEqual( + api.authenticationSessionState, + FBSDKAuthenticationSessionShowWebBrowser, + "Becoming active when the state is 'showAlert' should set the state to be 'showWebBrowser'" + ); + XCTAssertEqual(spy.cancelCallCount, 0, "Becoming active when the state is 'showAlert' should not cancel the session"); + XCTAssertNotNil(api.authenticationSession, "Becoming active when the state is 'showAlert' should not destroy the session"); +} + +- (void)testUpdatingCancelledBySystemStateForDidBecomeActive +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; + api.authenticationSession = spy; + api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; + + [api applicationDidBecomeActive:UIApplication.sharedApplication]; + + XCTAssertEqual( + api.authenticationSessionState, + FBSDKAuthenticationSessionCanceledBySystem, + "Becoming active when the state is 'canceledBySystem' should not change the state" + ); + XCTAssertNil( + api.authenticationSession, + "Becoming active when the state is 'canceledBySystem' should destroy the session" + ); + XCTAssertEqual(spy.cancelCallCount, 1, "Becoming active when the state is 'canceledBySystem' should cancel the session"); +} + +- (void)testCompletingWithCancelledBySystemStateForDidBecomeActive +{ + FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; + AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; + api.authenticationSession = spy; + api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; + api.authenticationSessionCompletionHandler = ^(NSURL *callbackURL, NSError *error) { + XCTAssertNil(callbackURL, "A completion triggered by becoming active in a canceled state should not have a callback URL"); + XCTAssertEqualObjects( + error.domain, + @"com.apple.AuthenticationServices.WebAuthenticationSession", + "A completion triggered by becoming active in a canceled state should include an error" + ); + }; + + [api applicationDidBecomeActive:UIApplication.sharedApplication]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AuthenticationSessionSpy.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AuthenticationSessionSpy.swift new file mode 100644 index 0000000000..95907f3e7a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AuthenticationSessionSpy.swift @@ -0,0 +1,54 @@ +// 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 Foundation + +@objcMembers +public class AuthenticationSessionSpy: NSObject, AuthenticationSessionHandling { + + public var capturedUrl: URL + public var capturedCallbackUrlScheme: String? + public var capturedCompletionHandler: FBSDKAuthenticationCompletionHandler? + public var startCallCount = 0 + public var cancelCallCount = 0 + + public static var makeDefaultSpy: AuthenticationSessionSpy { + guard let url = URL(string: "http://example.com") else { fatalError("Url creation failed") } + + return AuthenticationSessionSpy(url: url, callbackURLScheme: nil) { _, _ in } + } + + public required init( + url: URL, + callbackURLScheme: String?, + completionHandler: @escaping FBSDKAuthenticationCompletionHandler + ) { + capturedUrl = url + capturedCallbackUrlScheme = callbackURLScheme + capturedCompletionHandler = completionHandler + } + + public func start() -> Bool { + startCallCount += 1 + return true + } + + public func cancel() { + cancelCallCount += 1 + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h new file mode 100644 index 0000000000..a9fa44fcaf --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h @@ -0,0 +1,67 @@ +// 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 "FBSDKBridgeAPI.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); + +NS_SWIFT_NAME(AuthenticationSessionHandling) +@protocol FBSDKAuthenticationSession + +- (instancetype)initWithURL:(NSURL *)URL callbackURLScheme:(nullable NSString *)callbackURLScheme completionHandler:(FBSDKAuthenticationCompletionHandler)completionHandler; +- (BOOL)start; +- (void)cancel; +@optional +- (void)setPresentationContextProvider:(id)presentationContextProvider; + +@end + +/** + Specifies state of FBSDKAuthenticationSession (SFAuthenticationSession (iOS 11) and ASWebAuthenticationSession (iOS 12+)) + */ +typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { + /** There is no active authentication session*/ + FBSDKAuthenticationSessionNone, + /** The authentication session has started*/ + FBSDKAuthenticationSessionStarted, + /** System dialog ("app wants to use facebook.com to sign in") to access facebook.com was presented to the user*/ + FBSDKAuthenticationSessionShowAlert, + /** Web browser with log in to authentication was presented to the user*/ + FBSDKAuthenticationSessionShowWebBrowser, + /** Authentication session was canceled by system. It happens when app goes to background while alert requesting access to facebook.com is presented*/ + FBSDKAuthenticationSessionCanceledBySystem, +}; + +@interface FBSDKBridgeAPI (Testing) + +- (id)authenticationSession; +- (FBSDKAuthenticationSession)authenticationSessionState; + +- (void)applicationWillResignActive:(UIApplication *)application; +- (void)applicationDidBecomeActive:(UIApplication *)application; + +- (void)setAuthenticationSession:(id)session; +- (void)setAuthenticationSessionState:(FBSDKAuthenticationSession)state; +- (void)setAuthenticationSessionCompletionHandler:(FBSDKAuthenticationCompletionHandler)handler; + +@end + +NS_ASSUME_NONNULL_END From e2d9dd20b09fe9f548c047144bb2ecbc73785300 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 11 Nov 2020 21:25:50 -0800 Subject: [PATCH 096/227] FBSDKBridgeAPI Unit Tests 2/n Summary: Adding coverage for application lifecycle methods. Reviewed By: jawwad Differential Revision: D24894139 fbshipit-source-id: 6b38cf1b04a0bd52bb4da94e40cbb915c2e47fae --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 6 + .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 15 ++ .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 208 ++++++++++++++---- .../Internal/Helpers/FBSDKBridgeAPI+Testing.h | 6 + .../Internal/Helpers/FakeLoginManager.h | 39 ++++ .../Internal/Helpers/FakeLoginManager.m | 73 ++++++ 6 files changed, 309 insertions(+), 38 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 6391a22691..c0acf98bc6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -790,6 +790,7 @@ E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4C2B97923867327002335A4 /* FBSDKModelRuntimeTests.mm */; }; F402AFC8255B49A500473083 /* FBSDKBridgeAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */; }; F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */; }; + F402B062255C645600473083 /* FakeLoginManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F402B061255C645600473083 /* FakeLoginManager.m */; }; F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */; }; F40B24C224732DD90059351C /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24C124732DD90059351C /* Fuzzer.swift */; }; F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */; }; @@ -1521,6 +1522,8 @@ F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBridgeAPITests.m; sourceTree = ""; }; F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKBridgeAPI+Testing.h"; sourceTree = ""; }; F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationSessionSpy.swift; sourceTree = ""; }; + F402B060255C645600473083 /* FakeLoginManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeLoginManager.h; sourceTree = ""; }; + F402B061255C645600473083 /* FakeLoginManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeLoginManager.m; sourceTree = ""; }; F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawServerConfigurationResponseFixtures.swift; sourceTree = ""; }; F40B24C124732DD90059351C /* Fuzzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntryTests.m; sourceTree = ""; }; @@ -2675,6 +2678,8 @@ F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */, 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */, F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */, + F402B060255C645600473083 /* FakeLoginManager.h */, + F402B061255C645600473083 /* FakeLoginManager.m */, ); path = Helpers; sourceTree = ""; @@ -4149,6 +4154,7 @@ F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, + F402B062255C645600473083 /* FakeLoginManager.m in Sources */, F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */, 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 1a9a8be090..2c1465fa0d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -559,6 +559,21 @@ - (void)setAuthenticationSessionCompletionHandler:(FBSDKAuthenticationCompletion _authenticationSessionCompletionHandler = handler; } +- (void)setActive:(BOOL)isActive +{ + _active = isActive; +} + +- (BOOL)expectingBackground +{ + return _expectingBackground; +} + +- (void)setExpectingBackground:(BOOL)isExpectingBackground +{ + _expectingBackground = isExpectingBackground; +} + #endif @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m index 8afa5a62c8..44d795e28e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -18,6 +18,7 @@ #import #import +#import #import #import @@ -25,21 +26,42 @@ #import "FBSDKBridgeAPI+Testing.h" #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKTestCase.h" +#import "FakeLoginManager.h" @interface FBSDKBridgeAPITests : FBSDKTestCase + +@property FBSDKBridgeAPI *api; + @end @implementation FBSDKBridgeAPITests +- (void)setUp +{ + [super setUp]; + + [FBSDKLoginManager resetTestEvidence]; + _api = [FBSDKBridgeAPI new]; +} + +- (void)tearDown +{ + _api = nil; + [FBSDKLoginManager resetTestEvidence]; + + [super tearDown]; +} + // MARK: - Lifecycle Methods +// MARK: Will Resign Active + - (void)testWillResignActiveWithoutAuthSessionWithoutAuthSessionState { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; - [api applicationWillResignActive:UIApplication.sharedApplication]; + [self.api applicationWillResignActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, FBSDKAuthenticationSessionNone, "Should not modify the auth session state if there is no auth session" ); @@ -47,13 +69,12 @@ - (void)testWillResignActiveWithoutAuthSessionWithoutAuthSessionState - (void)testWillResignActiveWithAuthSessionWithoutAuthSessionState { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; - api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; - [api applicationWillResignActive:UIApplication.sharedApplication]; + [self.api applicationWillResignActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, FBSDKAuthenticationSessionNone, "Should not modify the auth session state unless the current state is 'started'" ); @@ -61,8 +82,7 @@ - (void)testWillResignActiveWithAuthSessionWithoutAuthSessionState - (void)testWillResignActiveWithAuthSessionWithNonStartedAuthSessionState { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; - api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; NSArray *states = @[ @(FBSDKAuthenticationSessionNone), @@ -72,10 +92,10 @@ - (void)testWillResignActiveWithAuthSessionWithNonStartedAuthSessionState ]; for (NSNumber *state in states) { - api.authenticationSessionState = state.intValue; - [api applicationWillResignActive:UIApplication.sharedApplication]; + self.api.authenticationSessionState = state.intValue; + [self.api applicationWillResignActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, state.intValue, "Should not modify the auth session state unless the current state is 'started'" ); @@ -84,21 +104,21 @@ - (void)testWillResignActiveWithAuthSessionWithNonStartedAuthSessionState - (void)testWillResignActiveWithAuthSessionWithStartedAuthSessionState { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; - api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; - api.authenticationSessionState = FBSDKAuthenticationSessionStarted; - [api applicationWillResignActive:UIApplication.sharedApplication]; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + [self.api applicationWillResignActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, FBSDKAuthenticationSessionShowAlert, "Should change the auth state from 'started' to 'alert' before resigning activity" ); } +// MARK: Did Become Active + - (void)testUpdatingShowAlertStateForDidBecomeActiveWithoutAuthSession { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; NSArray *states = @[ @(FBSDKAuthenticationSessionNone), @(FBSDKAuthenticationSessionStarted), @@ -108,10 +128,10 @@ - (void)testUpdatingShowAlertStateForDidBecomeActiveWithoutAuthSession ]; for (NSNumber *state in states) { - api.authenticationSessionState = state.intValue; - [api applicationDidBecomeActive:UIApplication.sharedApplication]; + self.api.authenticationSessionState = state.intValue; + [self.api applicationDidBecomeActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, state.intValue, "Should not modify the auth session state if there is no auth session" ); @@ -120,38 +140,36 @@ - (void)testUpdatingShowAlertStateForDidBecomeActiveWithoutAuthSession - (void)testUpdatingShowAlertStateForDidBecomeActive { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; - api.authenticationSession = spy; - api.authenticationSessionState = FBSDKAuthenticationSessionShowAlert; + self.api.authenticationSession = spy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionShowAlert; - [api applicationDidBecomeActive:UIApplication.sharedApplication]; + [self.api applicationDidBecomeActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, FBSDKAuthenticationSessionShowWebBrowser, "Becoming active when the state is 'showAlert' should set the state to be 'showWebBrowser'" ); XCTAssertEqual(spy.cancelCallCount, 0, "Becoming active when the state is 'showAlert' should not cancel the session"); - XCTAssertNotNil(api.authenticationSession, "Becoming active when the state is 'showAlert' should not destroy the session"); + XCTAssertNotNil(self.api.authenticationSession, "Becoming active when the state is 'showAlert' should not destroy the session"); } - (void)testUpdatingCancelledBySystemStateForDidBecomeActive { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; - api.authenticationSession = spy; - api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; + self.api.authenticationSession = spy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; - [api applicationDidBecomeActive:UIApplication.sharedApplication]; + [self.api applicationDidBecomeActive:UIApplication.sharedApplication]; XCTAssertEqual( - api.authenticationSessionState, + self.api.authenticationSessionState, FBSDKAuthenticationSessionCanceledBySystem, "Becoming active when the state is 'canceledBySystem' should not change the state" ); XCTAssertNil( - api.authenticationSession, + self.api.authenticationSession, "Becoming active when the state is 'canceledBySystem' should destroy the session" ); XCTAssertEqual(spy.cancelCallCount, 1, "Becoming active when the state is 'canceledBySystem' should cancel the session"); @@ -159,11 +177,10 @@ - (void)testUpdatingCancelledBySystemStateForDidBecomeActive - (void)testCompletingWithCancelledBySystemStateForDidBecomeActive { - FBSDKBridgeAPI *api = [FBSDKBridgeAPI new]; AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; - api.authenticationSession = spy; - api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; - api.authenticationSessionCompletionHandler = ^(NSURL *callbackURL, NSError *error) { + self.api.authenticationSession = spy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; + self.api.authenticationSessionCompletionHandler = ^(NSURL *callbackURL, NSError *error) { XCTAssertNil(callbackURL, "A completion triggered by becoming active in a canceled state should not have a callback URL"); XCTAssertEqualObjects( error.domain, @@ -172,7 +189,122 @@ - (void)testCompletingWithCancelledBySystemStateForDidBecomeActive ); }; - [api applicationDidBecomeActive:UIApplication.sharedApplication]; + [self.api applicationDidBecomeActive:UIApplication.sharedApplication]; +} + +// MARK: Did Enter Background + +- (void)testDidEnterBackgroundWithoutAuthSession +{ + self.api.active = YES; + self.api.expectingBackground = YES; + + NSArray *states = @[ + @(FBSDKAuthenticationSessionNone), + @(FBSDKAuthenticationSessionStarted), + @(FBSDKAuthenticationSessionShowAlert), + @(FBSDKAuthenticationSessionShowWebBrowser), + @(FBSDKAuthenticationSessionCanceledBySystem) + ]; + + for (NSNumber *state in states) { + self.api.authenticationSessionState = state.intValue; + [self.api applicationDidEnterBackground:UIApplication.sharedApplication]; + XCTAssertFalse( + self.api.active, + "Should mark a bridge api inactive when entering the background" + ); + XCTAssertFalse( + self.api.expectingBackground, + "Should mark a bridge api as not expecting backgrounding when entering the background" + ); + } +} + +- (void)testDidEnterBackgroundInShowAlertState +{ + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionShowAlert; + + [self.api applicationDidEnterBackground:UIApplication.sharedApplication]; + XCTAssertEqual( + self.api.authenticationSessionState, + FBSDKAuthenticationSessionCanceledBySystem, + "Should cancel the session when entering the background while showing an alert" + ); +} + +- (void)testDidEnterBackgroundInNonShowAlertState +{ + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + + NSArray *states = @[ + @(FBSDKAuthenticationSessionNone), + @(FBSDKAuthenticationSessionStarted), + @(FBSDKAuthenticationSessionShowWebBrowser), + @(FBSDKAuthenticationSessionCanceledBySystem) + ]; + + for (NSNumber *state in states) { + self.api.authenticationSessionState = state.intValue; + [self.api applicationDidEnterBackground:UIApplication.sharedApplication]; + XCTAssertEqual( + self.api.authenticationSessionState, + state.intValue, + "Should only modify the auth session state on backgrounding if it is showing an alert" + ); + } +} + +// MARK: Did Finish Launching With Options + +- (void)testDidFinishLaunchingWithoutLaunchedUrlWithoutSourceApplication +{ + XCTAssertFalse( + [self.api application:UIApplication.sharedApplication didFinishLaunchingWithOptions:@{}], + "Should not consider it a successful launch if there is no launch url or source application" + ); +} + +- (void)testDidFinishLaunchingWithoutLaunchedUrlWithSourceApplication +{ + NSDictionary *options = @{ UIApplicationLaunchOptionsSourceApplicationKey : @"com.example" }; + XCTAssertFalse( + [self.api application:UIApplication.sharedApplication didFinishLaunchingWithOptions:options], + "Should not consider it a successful launch if there is no launch url" + ); +} + +- (void)testDidFinishLaunchingWithLaunchedUrlWithoutSourceApplication +{ + NSDictionary *options = @{ UIApplicationLaunchOptionsURLKey : [NSURL URLWithString:@"http://example.com"] }; + XCTAssertFalse( + [self.api application:UIApplication.sharedApplication didFinishLaunchingWithOptions:options], + "Should not consider it a successful launch if there is no source application" + ); +} + +- (void)testDidFinishLaunchingWithLaunchedUrlWithSourceApplication +{ + NSURL *url = [NSURL URLWithString:@"http://example.com"]; + NSString *source = @"com.example"; + NSString *annotation = @"foo"; + NSDictionary *options = @{ + UIApplicationLaunchOptionsURLKey : url, + UIApplicationLaunchOptionsSourceApplicationKey : source, + UIApplicationLaunchOptionsAnnotationKey : annotation + }; + + FBSDKLoginManager.stubbedOpenUrlSuccess = YES; + + XCTAssertTrue( + [self.api application:UIApplication.sharedApplication didFinishLaunchingWithOptions:options], + "Should return the success value determined by the login manager's open url method" + ); + + XCTAssertEqualObjects(FBSDKLoginManager.capturedOpenUrl, url, "Should pass the launch url to the login manager"); + XCTAssertEqualObjects(FBSDKLoginManager.capturedSourceApplication, source, "Should pass the source application to the login manager"); + XCTAssertEqualObjects(FBSDKLoginManager.capturedAnnotation, annotation, "Should pass the annotation to the login manager"); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h index a9fa44fcaf..b36b60c432 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h @@ -54,13 +54,19 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (id)authenticationSession; - (FBSDKAuthenticationSession)authenticationSessionState; +- (BOOL)expectingBackground; - (void)applicationWillResignActive:(UIApplication *)application; - (void)applicationDidBecomeActive:(UIApplication *)application; +- (void)applicationDidEnterBackground:(UIApplication *)application; +- (BOOL) application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; - (void)setAuthenticationSession:(id)session; - (void)setAuthenticationSessionState:(FBSDKAuthenticationSession)state; - (void)setAuthenticationSessionCompletionHandler:(FBSDKAuthenticationCompletionHandler)handler; +- (void)setActive:(BOOL)isActive; +- (void)setExpectingBackground:(BOOL)isExpectingBackground; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h new file mode 100644 index 0000000000..d0e7d427b8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h @@ -0,0 +1,39 @@ +// 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 "FBSDKURLOpening.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Duplicate minimal interface for `FBSDKLoginManager` that can fulfill the `FBSDKBridgeAPI`'s runtime requirement. +/// Used in the `FBSDKBridgeAPITests` as a spy since it will be discovered by the real class and used instead of the actual +/// `FBSDKLoginManager`. +@interface FBSDKLoginManager : NSObject + +@property (class, nullable, copy) NSURL *capturedOpenUrl; +@property (class, nullable, copy) NSString *capturedSourceApplication; +@property (class, nullable, copy) NSString *capturedAnnotation; +@property (class) BOOL stubbedOpenUrlSuccess; + ++ (void)resetTestEvidence; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m new file mode 100644 index 0000000000..c81385f9a5 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m @@ -0,0 +1,73 @@ +// 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 "FakeLoginManager.h" + +@implementation FBSDKLoginManager + +static NSURL *_capturedOpenUrl; +static NSString *_capturedSourceApplication; +static NSString *_capturedAnnotation; +static BOOL _stubbedOpenUrlSuccess; + ++ (NSURL *)capturedOpenUrl { return _capturedOpenUrl; } + ++ (NSString *)capturedSourceApplication { return _capturedSourceApplication; } + ++ (NSString *)capturedAnnotation { return _capturedAnnotation; } + ++ (void)setCapturedOpenUrl:(NSURL *)url { _capturedOpenUrl = url; } + ++ (void)setCapturedSourceApplication:(NSString *)source { _capturedSourceApplication = source; } + ++ (void)setCapturedAnnotation:(NSString *)annotation { _capturedAnnotation = annotation; } + ++ (BOOL)stubbedOpenUrlSuccess { return _stubbedOpenUrlSuccess; } + ++ (void)setStubbedOpenUrlSuccess:(BOOL)success { _stubbedOpenUrlSuccess = success; } + ++ (void)resetTestEvidence +{ + FBSDKLoginManager.capturedOpenUrl = nil; + FBSDKLoginManager.capturedSourceApplication = nil; + FBSDKLoginManager.capturedAnnotation = nil; + FBSDKLoginManager.stubbedOpenUrlSuccess = NO; +} + +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + FBSDKLoginManager.capturedOpenUrl = url; + FBSDKLoginManager.capturedSourceApplication = sourceApplication; + FBSDKLoginManager.capturedAnnotation = annotation; + + return FBSDKLoginManager.stubbedOpenUrlSuccess; +} + +- (void)applicationDidBecomeActive:(UIApplication *)application {} + +- (BOOL)canOpenURL:(NSURL *)url forApplication:(UIApplication *)application sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + return NO; +} + +- (BOOL)isAuthenticationURL:(NSURL *)url +{ + return NO; +} + +@end From 9d48c3313fd8104986fb35521ed4ed07b219dce1 Mon Sep 17 00:00:00 2001 From: Julie Yuan Date: Thu, 12 Nov 2020 10:02:36 -0800 Subject: [PATCH 097/227] Add method to overwrite default content type for POST requests Reviewed By: joesus Differential Revision: D24807075 fbshipit-source-id: 8923502442fe852689b39f9f72857d03e7e640a2 --- .../Internal/Network/FBSDKGraphRequestBody.h | 6 ++ .../Internal/Network/FBSDKGraphRequestBody.m | 18 ++-- .../Network/FBSDKGraphRequestBodyTests.m | 91 +++++++++++++++++++ 3 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestBodyTests.m diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.h index 37bf777e45..c08f9cb364 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.h @@ -27,6 +27,12 @@ NS_SWIFT_NAME(GraphRequestBody) @property (nonatomic, retain, readonly) NSData *data; +/** + Determines whether to use multipart/form-data or application/json as the Content-Type. + If binary attachments are added, this will default to YES. + */ +@property (nonatomic, assign) BOOL requiresMultipartDataFormat; + - (void)appendWithKey:(NSString *)key formValue:(NSString *)value logger:(FBSDKLogger *)logger; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.m index c0c80858e5..b2d1e64844 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.m @@ -40,6 +40,7 @@ - (instancetype)init _stringBoundary = [FBSDKCrypto randomString:32]; _data = [[NSMutableData alloc] init]; _json = [NSMutableDictionary dictionary]; + _requiresMultipartDataFormat = NO; } return self; @@ -47,10 +48,10 @@ - (instancetype)init - (NSString *)mimeContentType { - if (_json) { - return @"application/json"; - } else { + if (self.requiresMultipartDataFormat) { return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", _stringBoundary]; + } else { + return @"application/json"; } } @@ -86,7 +87,7 @@ - (void)appendWithKey:(NSString *)key [self _appendWithKey:key filename:key contentType:@"image/jpeg" contentBlock:^{ [self->_data appendData:data]; }]; - _json = nil; + self.requiresMultipartDataFormat = YES; [logger appendFormat:@"\n %@:\t", key, (unsigned long)(data.length / 1024)]; } @@ -97,7 +98,7 @@ - (void)appendWithKey:(NSString *)key [self _appendWithKey:key filename:key contentType:@"content/unknown" contentBlock:^{ [self->_data appendData:data]; }]; - _json = nil; + self.requiresMultipartDataFormat = YES; [logger appendFormat:@"\n %@:\t", key, (unsigned long)(data.length / 1024)]; } @@ -111,13 +112,15 @@ - (void)appendWithKey:(NSString *)key [self _appendWithKey:key filename:filename contentType:contentType contentBlock:^{ [self->_data appendData:data]; }]; - _json = nil; + self.requiresMultipartDataFormat = YES; [logger appendFormat:@"\n %@:\t", key, (unsigned long)(data.length / 1024)]; } - (NSData *)data { - if (_json) { + if (self.requiresMultipartDataFormat) { + return [_data copy]; + } else { NSData *jsonData; if (_json.allKeys.count > 0) { jsonData = [FBSDKTypeUtility dataWithJSONObject:_json options:0 error:nil]; @@ -127,7 +130,6 @@ - (NSData *)data return jsonData; } - return [_data copy]; } - (void)_appendWithKey:(NSString *)key diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestBodyTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestBodyTests.m new file mode 100644 index 0000000000..ea5443fb1a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Network/FBSDKGraphRequestBodyTests.m @@ -0,0 +1,91 @@ +// 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 "FBSDKGraphRequestBody.h" +#import "FBSDKGraphRequestDataAttachment.h" + +@interface FBSDKGraphRequestBodyTests : XCTestCase +@end + +@implementation FBSDKGraphRequestBodyTests + +- (void)testBodyCreationWithFormValue +{ + FBSDKGraphRequestBody *body = [FBSDKGraphRequestBody new]; + [body appendWithKey:@"first_key" formValue:@"first_value" logger:nil]; + [body appendWithKey:@"second_key" formValue:@"second_value" logger:nil]; + + NSString *decodedData = [[NSString alloc] initWithData:body.data encoding:NSUTF8StringEncoding]; + + XCTAssertEqualObjects(body.mimeContentType, @"application/json"); + XCTAssertTrue([decodedData containsString:@"\"first_key\":\"first_value\""]); + XCTAssertTrue([decodedData containsString:@"\"second_key\":\"second_value\""]); +} + +- (void)testBodyCreationWithFormValueWithMultipartType +{ + FBSDKGraphRequestBody *body = [FBSDKGraphRequestBody new]; + [body appendWithKey:@"first_key" formValue:@"first_value" logger:nil]; + [body appendWithKey:@"second_key" formValue:@"second_value" logger:nil]; + body.requiresMultipartDataFormat = YES; + + NSString *decodedData = [[NSString alloc] initWithData:body.data encoding:NSUTF8StringEncoding]; + + XCTAssertTrue([body.mimeContentType containsString:@"multipart/form-data"]); + XCTAssertTrue([decodedData containsString:@"Content-Disposition: form-data"]); + XCTAssertTrue([decodedData containsString:@"name=\"first_key\"\r\n\r\nfirst_value\r\n"]); + XCTAssertTrue([decodedData containsString:@"name=\"second_key\"\r\n\r\nsecond_value\r\n"]); +} + +- (void)testBodyCreationWithImageValue +{ + FBSDKGraphRequestBody *body = [FBSDKGraphRequestBody new]; + [body appendWithKey:@"image_key" imageValue:[UIImage new] logger:nil]; + + NSString *decodedData = [[NSString alloc] initWithData:body.data encoding:NSUTF8StringEncoding]; + XCTAssertTrue([body.mimeContentType containsString:@"multipart/form-data"]); + XCTAssertTrue([decodedData containsString:@"Content-Type: image/jpeg"]); +} + +- (void)testBodyCreationWithDataValue +{ + FBSDKGraphRequestBody *body = [FBSDKGraphRequestBody new]; + [body appendWithKey:@"data_key" dataValue:[NSData data] logger:nil]; + + NSString *decodedData = [[NSString alloc] initWithData:body.data encoding:NSUTF8StringEncoding]; + XCTAssertTrue([body.mimeContentType containsString:@"multipart/form-data"]); + XCTAssertTrue([decodedData containsString:@"Content-Type: content/unknown"]); +} + +- (void)testBodyCreationWithAttachmentValue +{ + FBSDKGraphRequestBody *body = [FBSDKGraphRequestBody new]; + FBSDKGraphRequestDataAttachment *attachment = [[FBSDKGraphRequestDataAttachment alloc] initWithData:[NSData data] + filename:@"test_filename" + contentType:@"test_content_type"]; + [body appendWithKey:@"attachment_key" dataAttachmentValue:attachment logger:nil]; + + NSString *decodedData = [[NSString alloc] initWithData:body.data encoding:NSUTF8StringEncoding]; + XCTAssertTrue([body.mimeContentType containsString:@"multipart/form-data"]); + XCTAssertTrue([decodedData containsString:@"filename=\"test_filename\""]); + XCTAssertTrue([decodedData containsString:@"Content-Type: test_content_type"]); +} + +@end From 58a9f53e9a40695395398f6ae4e40607931a978f Mon Sep 17 00:00:00 2001 From: Julie Yuan Date: Thu, 12 Nov 2020 10:02:36 -0800 Subject: [PATCH 098/227] Add separate method for appending body to NSURLRequest Reviewed By: joesus Differential Revision: D24685989 fbshipit-source-id: 7bbe5e9b5db1dbe9ec1b8b2d086a6b3bb1ff561d --- .../GraphAPI/FBSDKGraphRequestConnection.m | 17 ++++++-- .../Internal/FBSDKCoreKit+Internal.h | 2 + .../FBSDKGraphRequestConnection+Internal.h | 8 ++++ .../FBSDKGraphRequestConnectionTests.m | 41 +++++++++++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m index 4540173ad1..81440ed262 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphRequestConnection.m @@ -497,10 +497,8 @@ - (NSMutableURLRequest *)requestWithBatch:(NSArray *)requests request.HTTPMethod = @"POST"; } - NSData *compressedData; - if ([request.HTTPMethod isEqualToString:@"POST"] && (compressedData = [body compressedData])) { - request.HTTPBody = compressedData; - [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + if ([request.HTTPMethod isEqualToString:@"POST"]) { + [self addBody:body toPostRequest:request]; } else { request.HTTPBody = body.data; } @@ -513,6 +511,17 @@ - (NSMutableURLRequest *)requestWithBatch:(NSArray *)requests return request; } +- (void)addBody:(FBSDKGraphRequestBody *)body toPostRequest:(NSMutableURLRequest *)request +{ + NSData *compressedData; + if ((compressedData = [body compressedData])) { + request.HTTPBody = compressedData; + [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + } else { + request.HTTPBody = body.data; + } +} + // // Generates a URL for a batch containing only a single request, // and names all attachments that need to go in the body of the diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index a3c00a6257..92cc9bf72b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -81,6 +81,7 @@ #import "FBSDKErrorRecoveryAttempter.h" #import "FBSDKGateKeeperManager.h" #import "FBSDKGraphRequest+Internal.h" + #import "FBSDKGraphRequestBody.h" #import "FBSDKGraphRequestConnection+Internal.h" #import "FBSDKGraphRequestMetadata.h" #import "FBSDKGraphRequestPiggybackManager.h" @@ -160,6 +161,7 @@ #import "FBSDKSwizzler.h" #import "Monitoring/FBSDKMonitorHeaders.h" #import "Network/FBSDKGraphRequest+Internal.h" + #import "Network/FBSDKGraphRequestBody.h" #import "Network/FBSDKGraphRequestConnection+Internal.h" #import "Network/FBSDKGraphRequestMetadata.h" #import "Network/FBSDKGraphRequestPiggybackManager.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h index a07c20181c..fea0f90a82 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h @@ -16,6 +16,7 @@ // 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. +@class FBSDKGraphRequestBody; @class FBSDKURLSession; #if SWIFT_PACKAGE @@ -36,4 +37,11 @@ */ - (NSString *)urlStringForSingleRequest:(FBSDKGraphRequest *)request forBatch:(BOOL)forBatch; +/** + Add the specified body as the HTTPBody of the specified request. + @param body The FBSDKGraphRequestBody to attach to the request. + @param request The NSURLRequest to attach the body to. + */ +- (void)addBody:(FBSDKGraphRequestBody *)body toPostRequest:(NSMutableURLRequest *)request; + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m index f07fd959b2..ee5b267817 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m @@ -31,6 +31,13 @@ #import "FBSDKSettings+Internal.h" #import "FBSDKTestCase.h" +@interface FBSDKGraphRequestConnection (Testing) + +- (NSMutableURLRequest *)requestWithBatch:(NSArray *)requests + timeout:(NSTimeInterval)timeout; + +@end + @interface FBSDKGraphRequestConnectionTests : FBSDKTestCase @property (nonatomic, copy) void (^requestConnectionStartingCallback)(FBSDKGraphRequestConnection *connection); @@ -581,6 +588,40 @@ - (void)testNonDictionaryInError [mockPiggybackManager stopMocking]; } +- (void)testRequestWithBatchConstructionWithSingleGetRequest +{ + FBSDKGraphRequest *singleRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @"with_suffix"}]; + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [connection addRequest:singleRequest completionHandler:^(FBSDKGraphRequestConnection *_Nullable connection, id _Nullable result, NSError *_Nullable error) {}]; + NSURLRequest *request = [connection requestWithBatch:connection.requests timeout:0]; + + NSURLComponents *urlComponents = [NSURLComponents componentsWithString:request.URL.absoluteString]; + XCTAssertEqualObjects(urlComponents.host, @"graph.facebook.com"); + XCTAssertTrue([urlComponents.path containsString:@"me"]); + XCTAssertEqualObjects(request.HTTPMethod, @"GET"); + XCTAssertTrue(request.HTTPBody.length == 0); + XCTAssertEqualObjects([request valueForHTTPHeaderField:@"Content-Type"], @"application/json"); +} + +- (void)testRequestWithBatchConstructionWithSinglePostRequest +{ + NSDictionary *parameters = @{ + @"first_key" : @"first_value", + }; + FBSDKGraphRequest *singleRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"activities" parameters:parameters HTTPMethod:FBSDKHTTPMethodPOST]; + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [connection addRequest:singleRequest completionHandler:^(FBSDKGraphRequestConnection *_Nullable connection, id _Nullable result, NSError *_Nullable error) {}]; + NSURLRequest *request = [connection requestWithBatch:connection.requests timeout:0]; + + NSURLComponents *urlComponents = [NSURLComponents componentsWithString:request.URL.absoluteString]; + XCTAssertEqualObjects(urlComponents.host, @"graph.facebook.com"); + XCTAssertTrue([urlComponents.path containsString:@"activities"]); + XCTAssertEqualObjects(request.HTTPMethod, @"POST"); + XCTAssertTrue(request.HTTPBody.length > 0); + XCTAssertEqualObjects([request valueForHTTPHeaderField:@"Content-Encoding"], @"gzip"); + XCTAssertEqualObjects([request valueForHTTPHeaderField:@"Content-Type"], @"application/json"); +} + #pragma mark - Error recovery. // verify we do a single retry. From 81299b289aafd6860ab9258a67318579ab24aaee Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 12 Nov 2020 11:53:38 -0800 Subject: [PATCH 099/227] Convert FBSDKUtilityTests.m to Swift Summary: Converted FBSDKUtilityTests.m to Swift Reviewed By: joesus Differential Revision: D24874755 fbshipit-source-id: 3ab4e44bbd5085d0cb15c19f4e7e09f3f551b64d --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 +- .../FBSDKCoreKitTests/FBSDKUtilityTests.m | 87 ------------------- .../FBSDKCoreKitTests/FBSDKUtilityTests.swift | 69 +++++++++++++++ 3 files changed, 73 insertions(+), 91 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index c0acf98bc6..989be5d34f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -488,7 +488,7 @@ 899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3D011A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m */; }; 89C8B1991A8D7A15009B07F5 /* FBSDKUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 89C8B1971A8D7A15009B07F5 /* FBSDKUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 89C8B19A1A8D7A15009B07F5 /* FBSDKUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */; }; - 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.m */; }; + 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.swift */; }; 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 */; }; @@ -1360,7 +1360,7 @@ 899C3D011A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMaleSilhouetteIcon.m; sourceTree = ""; }; 89C8B1971A8D7A15009B07F5 /* FBSDKUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKUtility.h; sourceTree = ""; }; 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUtility.m; sourceTree = ""; }; - 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUtilityTests.m; sourceTree = ""; }; + 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBSDKUtilityTests.swift; sourceTree = ""; }; 89D05AA71AA1134000609300 /* FBSDKAudioResourceLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAudioResourceLoader.h; sourceTree = ""; }; 89D05AA81AA1134000609300 /* FBSDKAudioResourceLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAudioResourceLoader.m; sourceTree = ""; }; 89D4AE851A7FFEFC00DB8C72 /* FBSDKBridgeAPIRequest+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKBridgeAPIRequest+Private.h"; sourceTree = ""; }; @@ -2316,7 +2316,7 @@ C511229F20A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m */, 9D3AF4651A9ED47900EEF724 /* FBSDKGraphRequestConnectionTests.m */, F93680D4249D490600446E35 /* FBSDKSettingsTests.m */, - 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.m */, + 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.swift */, 893F44A41A644552001DB0B6 /* Internal */, 9D2697571A5DF40700143BFC /* Supporting Files */, 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift */, @@ -4144,7 +4144,7 @@ F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */, 5C49DF9E2554C9ED00E0FD91 /* SampleUserProfile.swift in Sources */, F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */, - 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.m in Sources */, + 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.swift in Sources */, F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */, C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.m in Sources */, F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m deleted file mode 100644 index e687f0a589..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.m +++ /dev/null @@ -1,87 +0,0 @@ -// 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 "FBSDKCoreKit+Internal.h" - -@interface FBSDKUtilityTests : XCTestCase - -@end - -@implementation FBSDKUtilityTests - -- (void)testSHA256Hash -{ - NSString *hashed = [FBSDKUtility SHA256Hash:@"facebook"]; - - XCTAssertEqualObjects(hashed, @"3d59f7548e1af2151b64135003ce63c0a484c26b9b8b166a7b1c1805ec34b00a"); -} - -- (void)testURLDecodeShouldNotModifyUnencodedUrlString -{ - NSString *unencoded = @"https://www.facebook.com/index.html?a=b&c=d"; - - XCTAssertEqualObjects(unencoded, [FBSDKUtility URLDecode:unencoded]); -} - -- (void)testURLEncode -{ - NSString *unencoded = @"https://www.facebook.com/index.html?a=b&c=d"; - NSString *encoded = @"https%3A%2F%2Fwww.facebook.com%2Findex.html%3Fa%3Db%26c%3Dd"; - - XCTAssertEqualObjects(encoded, [FBSDKUtility URLEncode:unencoded]); - XCTAssertEqualObjects(unencoded, [FBSDKUtility URLDecode:encoded]); -} - -- (void)testURLEncodeWithJSON -{ - NSString *url = @"https://m.facebook.com/v3.2/dialog/oauth?auth_type=rerequest&client_id=123456789&default_audience=friends&display=touch&e2e={\"init\":123456.1234567890}&fbapp_pres=0&redirect_uri=fb111111111111111://authorize/&response_type=token,signed_request&return_scopes=true&scope=&sdk=ios&sdk_version=4.39.0&state={\"challenge\":\"aBcDeFghiJKlmnOpQRS%tU\",\"0_auth_logger_id\":\"01234ABC-12AB-34DE-1234-ABCDEFG12345\",\"com.facebook.some_identifier\":true,\"3_method\":\"sfvc_auth\"}"; - NSString *encoded = @"https%3A%2F%2Fm.facebook.com%2Fv3.2%2Fdialog%2Foauth%3Fauth_type%3Drerequest%26client_id%3D123456789%26default_audience%3Dfriends%26display%3Dtouch%26e2e%3D%7B%22init%22%3A123456.1234567890%7D%26fbapp_pres%3D0%26redirect_uri%3Dfb111111111111111%3A%2F%2Fauthorize%2F%26response_type%3Dtoken%2Csigned_request%26return_scopes%3Dtrue%26scope%3D%26sdk%3Dios%26sdk_version%3D4.39.0%26state%3D%7B%22challenge%22%3A%22aBcDeFghiJKlmnOpQRS%25tU%22%2C%220_auth_logger_id%22%3A%2201234ABC-12AB-34DE-1234-ABCDEFG12345%22%2C%22com.facebook.some_identifier%22%3Atrue%2C%223_method%22%3A%22sfvc_auth%22%7D"; - - XCTAssertEqualObjects(encoded, [FBSDKUtility URLEncode:url]); - XCTAssertEqualObjects(url, [FBSDKUtility URLDecode:encoded]); -} - -- (void)testNewEncodeWorksLikeLegacy -{ - for (int i = 0; i < 256; i++) { - NSString *str = [NSString stringWithFormat:@"%c", (char)i]; - if ([str isEqualToString:@"{"] || [str isEqualToString:@"}"]) { - continue; // Curly braces were not included in legacy URL encode - } - XCTAssertEqualObjects([FBSDKUtility URLEncode:str], [self legacyURLEncode:str]); - } -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -- (NSString *)legacyURLEncode:(NSString *)value -{ - return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes( - NULL, - (CFStringRef)value, - NULL, // characters to leave unescaped - CFSTR(":!*();@/&?+$,='"), - kCFStringEncodingUTF8 - ); -} - -#pragma clang diagnostic pop - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.swift new file mode 100644 index 0000000000..18c2efe8ec --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKUtilityTests.swift @@ -0,0 +1,69 @@ +// 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 XCTest + +class FBSDKUtilityTests: XCTestCase { + func testSHA256Hash() { + let hashed = Utility.sha256Hash("facebook" as NSObject) + + XCTAssertEqual(hashed, "3d59f7548e1af2151b64135003ce63c0a484c26b9b8b166a7b1c1805ec34b00a") + } + + func testURLDecodeShouldNotModifyUnencodedUrlString() { + let unencoded = "https://www.facebook.com/index.html?a=b&c=d" + + XCTAssertEqual(unencoded, Utility.decode(urlString: unencoded)) + } + + func testURLEncode() { + let unencoded = "https://www.facebook.com/index.html?a=b&c=d" + let encoded = "https%3A%2F%2Fwww.facebook.com%2Findex.html%3Fa%3Db%26c%3Dd" + + XCTAssertEqual(encoded, Utility.encode(urlString: unencoded)) + XCTAssertEqual(unencoded, Utility.decode(urlString: encoded)) + } + + func testURLEncodeWithJSON() { + let url = "https://m.facebook.com/v3.2/dialog/oauth?auth_type=rerequest&client_id=123456789&default_audience=friends&display=touch&e2e={\"init\":123456.1234567890}&fbapp_pres=0&redirect_uri=fb111111111111111://authorize/&response_type=token,signed_request&return_scopes=true&scope=&sdk=ios&sdk_version=4.39.0&state={\"challenge\":\"aBcDeFghiJKlmnOpQRS%tU\",\"0_auth_logger_id\":\"01234ABC-12AB-34DE-1234-ABCDEFG12345\",\"com.facebook.some_identifier\":true,\"3_method\":\"sfvc_auth\"}" // swiftlint:disable:this line_length + let encoded = "https%3A%2F%2Fm.facebook.com%2Fv3.2%2Fdialog%2Foauth%3Fauth_type%3Drerequest%26client_id%3D123456789%26default_audience%3Dfriends%26display%3Dtouch%26e2e%3D%7B%22init%22%3A123456.1234567890%7D%26fbapp_pres%3D0%26redirect_uri%3Dfb111111111111111%3A%2F%2Fauthorize%2F%26response_type%3Dtoken%2Csigned_request%26return_scopes%3Dtrue%26scope%3D%26sdk%3Dios%26sdk_version%3D4.39.0%26state%3D%7B%22challenge%22%3A%22aBcDeFghiJKlmnOpQRS%25tU%22%2C%220_auth_logger_id%22%3A%2201234ABC-12AB-34DE-1234-ABCDEFG12345%22%2C%22com.facebook.some_identifier%22%3Atrue%2C%223_method%22%3A%22sfvc_auth%22%7D" // swiftlint:disable:this line_length + XCTAssertEqual(encoded, Utility.encode(urlString: url)) + XCTAssertEqual(url, Utility.decode(urlString: encoded)) + } + + @available(iOS, deprecated: 9.0) + func testNewEncodeWorksLikeLegacy() { + for num in 0..<256 { + let str = String(Character(UnicodeScalar(num)!)) // swiftlint:disable:this force_unwrapping + if str == "{" || str == "}" { + continue // Curly braces were not included in legacy URL encode + } + XCTAssertEqual(Utility.encode(urlString: str), legacyURLEncode(str)) + } + } + + @available(iOS, deprecated: 9.0) // Needed to disable warning on CFURLCreateStringByAddingPercentEscapes + func legacyURLEncode(_ value: String) -> String? { + return CFURLCreateStringByAddingPercentEscapes( + nil, + value as CFString, + nil, + ":!*();@/&?+$,='" as CFString, + CFStringBuiltInEncodings.UTF8.rawValue) as String + } +} From 77201211e59340cc5513377e0ec2ecb449ed699b Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 12 Nov 2020 12:04:05 -0800 Subject: [PATCH 100/227] Convert the NotificationCenterSpy test helper to Swift Summary: Converted the NotificationCenterSpy test helper to Swift Reviewed By: joesus Differential Revision: D24852701 fbshipit-source-id: fe7119fe83bc720e62419980a1afeb621a203a54 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +++---- .../FBSDKApplicationDelegateTests.m | 2 -- .../Internal/Helpers/NotificationCenterSpy.m | 28 ------------------- ...enterSpy.h => NotificationCenterSpy.swift} | 14 ++++------ 4 files changed, 10 insertions(+), 44 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{NotificationCenterSpy.h => NotificationCenterSpy.swift} (83%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 989be5d34f..3255d01a95 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -959,7 +959,7 @@ F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */; }; F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */; }; F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */; }; - F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */; }; + F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.swift */; }; F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; F4F98C5524CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */; }; @@ -1605,8 +1605,7 @@ F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleGraphRequestConnection.swift; sourceTree = ""; }; F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleGraphRequest.swift; sourceTree = ""; }; F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleRawRemotePermissions.swift; sourceTree = ""; }; - F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationCenterSpy.h; sourceTree = ""; }; - F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationCenterSpy.m; sourceTree = ""; }; + F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationCenterSpy.swift; sourceTree = ""; }; F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSafeCast.m; sourceTree = ""; }; F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValue.m; sourceTree = ""; }; F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkConversionConfigurationTests.m; sourceTree = ""; }; @@ -2669,8 +2668,7 @@ F496E60E24E5D195006231A2 /* SampleAccessToken.swift */, F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */, F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */, - F4ED90D924EDDC610048D283 /* NotificationCenterSpy.h */, - F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.m */, + F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.swift */, F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */, F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */, @@ -4106,7 +4104,7 @@ 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */, F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */, 9D18A8DB1A95405A00A41042 /* FBSDKAppEventsStateTests.m in Sources */, - F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.m in Sources */, + F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.swift in Sources */, F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */, E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */, F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index d636d1585c..32f9435ae9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -19,8 +19,6 @@ #import #import -#import "NotificationCenterSpy.h" - #import "AppDelegateObserverFake.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m deleted file mode 100644 index b94ffea12e..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.m +++ /dev/null @@ -1,28 +0,0 @@ -// 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 "NotificationCenterSpy.h" - -@implementation NotificationCenterSpy - -- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject -{ - // TODO: capture values -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift similarity index 83% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift index dd293456bc..d973494e86 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift @@ -16,12 +16,10 @@ // 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 Foundation -NS_ASSUME_NONNULL_BEGIN - -@interface NotificationCenterSpy : NSNotificationCenter - -@end - -NS_ASSUME_NONNULL_END +class NotificationCenterSpy: NotificationCenter { + override func addObserver(_ observer: Any, selector: Selector, name: NSNotification.Name?, object: Any?) { + // TODO: capture values + } +} From 76e5276bd54cfc43ac47bc30c347f430305becd9 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 12 Nov 2020 12:04:05 -0800 Subject: [PATCH 101/227] Convert the KeychainStoreSpy test helper to Swift Summary: Note: This file was added recently but is currently unused Reviewed By: joesus Differential Revision: D24864956 fbshipit-source-id: 9ad247e2bf56ddb1ceccc970a65b213afff371a0 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +++--- .../Internal/FBSDKSettingsTests.m | 1 - .../Internal/Helpers/KeychainStoreSpy.h | 27 --------------- ...chainStoreSpy.m => KeychainStoreSpy.swift} | 33 ++++++++----------- 4 files changed, 18 insertions(+), 53 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{KeychainStoreSpy.m => KeychainStoreSpy.swift} (64%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 3255d01a95..e66c355fcf 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -907,7 +907,7 @@ F4713D7D2375DA8200748692 /* FBSDKSuggestedEventsIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = BF247C812374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m */; }; F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */ = {isa = PBXBuildFile; fileRef = F47E55FB24E1EA8D001497C9 /* FakeBundle.m */; }; F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */; }; - F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */; }; + F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */; }; F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */; }; @@ -1560,9 +1560,8 @@ F487DBD9231EC293008416A9 /* AccessToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessToken.swift; sourceTree = ""; }; F48A6AEB24170D29002C6CA1 /* TestMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestMonitorEntry.h; sourceTree = ""; }; F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestMonitorEntry.m; sourceTree = ""; }; - F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainStoreSpy.h; sourceTree = ""; }; F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDefaultsSpy.h; sourceTree = ""; }; - F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainStoreSpy.m; sourceTree = ""; }; + F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainStoreSpy.swift; sourceTree = ""; }; F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAccessTokenCache.swift; sourceTree = ""; }; @@ -2652,8 +2651,7 @@ children = ( F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */, F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */, - F492C09024E1F5F600BA21F7 /* KeychainStoreSpy.h */, - F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.m */, + F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */, F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */, F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */, F47E560C24E1EA8D001497C9 /* FakeBundle.h */, @@ -4159,7 +4157,7 @@ 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, E493252D23F7C60E0000B63A /* FBSDKModelParserTests.mm in Sources */, F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */, - F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.m in Sources */, + F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.swift in Sources */, 5D68D7D822BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m in Sources */, 9D3AF4661A9ED47900EEF724 /* FBSDKGraphRequestConnectionTests.m in Sources */, BF1C64E624039AD50052C580 /* FBSDKViewHierarchyTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m index 470da19de6..5507ac8e5f 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m @@ -25,7 +25,6 @@ #import "FBSDKSettings+Internal.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" -#import "KeychainStoreSpy.h" #import "UserDefaultsSpy.h" @interface FBSDKSettings () diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h deleted file mode 100644 index 5a221e6502..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.h +++ /dev/null @@ -1,27 +0,0 @@ -// 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 "FBSDKKeychainStore.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface KeychainStoreSpy : FBSDKKeychainStore - -@end - -NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.swift similarity index 64% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.swift index a490ec0ad2..3638212c7e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/KeychainStoreSpy.swift @@ -16,26 +16,21 @@ // 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 "KeychainStoreSpy.h" +@objcMembers +class KeychainStoreSpy: KeychainStore { -@implementation KeychainStoreSpy + override func setData(_ value: Data, forKey key: String, accessibility: CFTypeRef) -> Bool { + // Right now just return true. Later will add actual spying + return true + } -- (BOOL)setData:(NSData *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility -{ - // Right now just return true. Later will add actual spying - return true; -} - -- (BOOL)setDictionary:(NSDictionary *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility -{ - // Right now just return true. Later will add actual spying - return true; -} + override func setDictionary(_ value: [AnyHashable: Any], forKey key: String, accessibility: CFTypeRef) -> Bool { + // Right now just return true. Later will add actual spying + return true + } -- (BOOL)setString:(NSString *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility -{ - // Right now just return true. Later will add actual spying - return true; + override func setString(_ value: String, forKey key: String, accessibility: CFTypeRef) -> Bool { + // Right now just return true. Later will add actual spying + return true + } } - -@end From eac8fcbed429bf17ee69e134186db11ae5554561 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 12 Nov 2020 13:52:55 -0800 Subject: [PATCH 102/227] Convert FBSDKBase64Tests.m to Swift Summary: Converted FBSDKBase64Tests.m to Swift Reviewed By: joesus Differential Revision: D24874867 fbshipit-source-id: 098541e43492e4e728452b709ff1f8cfdda124e0 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 +-- .../Internal/Base64/FBSDKBase64Tests.m | 68 ------------------- .../Internal/Base64/FBSDKBase64Tests.swift | 58 ++++++++++++++++ 3 files changed, 62 insertions(+), 72 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index e66c355fcf..97d2316cb3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -466,7 +466,7 @@ 894C0B111A7021F8009137EF /* FBSDKBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B0F1A7021F8009137EF /* FBSDKBase64.h */; }; 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 */; }; + 894C0B4A1A70524F009137EF /* FBSDKBase64Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B491A70524F009137EF /* FBSDKBase64Tests.swift */; }; 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, ); }; }; @@ -1338,7 +1338,7 @@ 894C0B0F1A7021F8009137EF /* FBSDKBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKBase64.h; sourceTree = ""; }; 894C0B101A7021F8009137EF /* FBSDKBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKBase64.m; sourceTree = ""; }; 894C0B391A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKBridgeAPIProtocolNativeV1Tests.m; sourceTree = ""; }; - 894C0B491A70524F009137EF /* FBSDKBase64Tests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKBase64Tests.m; sourceTree = ""; }; + 894C0B491A70524F009137EF /* FBSDKBase64Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBSDKBase64Tests.swift; sourceTree = ""; }; 894C0B5F1A7150AC009137EF /* FBSDKError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKError.h; sourceTree = ""; }; 894C0B601A7150AC009137EF /* FBSDKError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKError.m; sourceTree = ""; }; 894C0B661A7150CC009137EF /* FBSDKConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKConstants.h; sourceTree = ""; }; @@ -2114,7 +2114,7 @@ 894C0B481A705244009137EF /* Base64 */ = { isa = PBXGroup; children = ( - 894C0B491A70524F009137EF /* FBSDKBase64Tests.m */, + 894C0B491A70524F009137EF /* FBSDKBase64Tests.swift */, ); name = Base64; path = FBSDKCoreKitTests/Internal/Base64; @@ -4115,7 +4115,7 @@ C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */, F4E50155243648A100C99262 /* FBSDKServerConfigurationFixtures.m in Sources */, F4D8D8FA242293ED00C28384 /* FBSDKMonitorNetworkerTests.m in Sources */, - 894C0B4A1A70524F009137EF /* FBSDKBase64Tests.m in Sources */, + 894C0B4A1A70524F009137EF /* FBSDKBase64Tests.swift in Sources */, F420D1852433B73E00D4FA82 /* FBSDKMonitorConfigurationTests.m in Sources */, F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */, 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m deleted file mode 100644 index b1881e0b99..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.m +++ /dev/null @@ -1,68 +0,0 @@ -// 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 "FBSDKBase64.h" - -@interface FBSDKBase64Tests : XCTestCase - -@end - -@implementation FBSDKBase64Tests - -- (void)runTests:(NSDictionary *)tests -{ - [tests enumerateKeysAndObjectsUsingBlock:^(NSString *plainString, NSString *base64String, BOOL *stop) { - XCTAssertEqualObjects([FBSDKBase64 encodeString:plainString], base64String); - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:base64String], plainString); - }]; -} - -- (void)testRFC4648TestVectors -{ - [self runTests:@{ - @"" : @"", - @"f" : @"Zg==", - @"fo" : @"Zm8=", - @"foo" : @"Zm9v", - @"foob" : @"Zm9vYg==", - @"fooba" : @"Zm9vYmE=", - @"foobar" : @"Zm9vYmFy", - }]; -} - -- (void)testDecodeVariations -{ - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:@"aGVsbG8gd29ybGQh"], @"hello world!"); - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:@"a GVs\tb\r\nG8gd2\n9y\rbGQ h"], @"hello world!"); - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:@"aGVsbG8gd29ybGQh"], @"hello world!"); - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:@"aGVs#bG8*gd^29yb$GQh"], @"hello world!"); -} - -- (void)testEncodeDecode -{ - [self runTests:@{ - @"Hello World" : @"SGVsbG8gV29ybGQ=", - @"ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!%^&*(){}[]" : @"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoxMjM0NTY3ODkwISVeJiooKXt9W10=", - @"\n\t Line with control characters\r\n" : @"CgkgTGluZSB3aXRoIGNvbnRyb2wgY2hhcmFjdGVycw0K", - }]; -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift new file mode 100644 index 0000000000..75255b71fd --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift @@ -0,0 +1,58 @@ +// 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 XCTest + +class FBSDKBase64Tests: XCTestCase { + + func runTests(_ testsDict: [String: String]) { + for (plainString, base64String) in testsDict { + XCTAssertEqual(Base64.encode(plainString), base64String) + XCTAssertEqual(Base64.decode(as: base64String), plainString) + } + } + + func testRFC4648TestVectors() { + let testsDict = [ + "": "", + "f": "Zg==", + "fo": "Zm8=", + "foo": "Zm9v", + "foob": "Zm9vYg==", + "fooba": "Zm9vYmE=", + "foobar": "Zm9vYmFy", + ] + runTests(testsDict) + } + + func testDecodeVariations() { + XCTAssertEqual(Base64.decode(as: "aGVsbG8gd29ybGQh"), "hello world!") + XCTAssertEqual(Base64.decode(as: "a GVs\tb\r\nG8gd2\n9y\rbGQ h"), "hello world!") + XCTAssertEqual(Base64.decode(as: "aGVsbG8gd29ybGQh"), "hello world!") + XCTAssertEqual(Base64.decode(as: "aGVs#bG8*gd^29yb$GQh"), "hello world!") + } + + func testEncodeDecode() { + let testsDict = [ + "Hello World": "SGVsbG8gV29ybGQ=", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!%^&*(){}[]": "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoxMjM0NTY3ODkwISVeJiooKXt9W10=", // swiftlint:disable:this line_length + "\n\t Line with control characters\r\n": "CgkgTGluZSB3aXRoIGNvbnRyb2wgY2hhcmFjdGVycw0K", + ] + runTests(testsDict) + } +} From b518422e220c6bda1d2bb5ed43b1e424219688ea Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Thu, 12 Nov 2020 18:42:58 -0800 Subject: [PATCH 103/227] Enable code coverage in Xcode for the BuildAllKits scheme Summary: Let's turn on code coverage in Xcode for our main scheme Reviewed By: joesus Differential Revision: D24934436 fbshipit-source-id: ed6c73adaa8be399507af06b20df6db4f2ea05a4 --- .../xcshareddata/xcschemes/BuildAllKits.xcscheme | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme b/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme index affdd215b3..3befffa24d 100644 --- a/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme +++ b/FacebookSDK.xcworkspace/xcshareddata/xcschemes/BuildAllKits.xcscheme @@ -110,7 +110,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> From 749d92975b788fcf661990b04135dc4817c2399b Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Thu, 12 Nov 2020 18:44:27 -0800 Subject: [PATCH 104/227] Parse & decode ID Token from login Response Summary: For openid connect logins, the server should return login response as "id_token". The ID token will have the format `HEADER.PAYLOAD.SIGNATURE`, where the payload would contains the claims, i.e. informations about the authenticated user. For more information, refer to the OICD spec here: https://openid.net/specs/openid-connect-core-1_0.html#IDToken This diff parse id_token from login response, and add the utility function to decode the token to get the claims. Later diffs will add codes to verify the id token is valid. Reviewed By: joesus Differential Revision: D24662566 fbshipit-source-id: b510969f9bcb7e7da0f937832a8145ba060c6b20 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 16 ++++ .../FBSDKLoginKit/Internal/FBSDKIDToken.h | 52 ++++++++++++ .../FBSDKLoginKit/Internal/FBSDKIDToken.m | 85 +++++++++++++++++++ .../Internal/FBSDKLoginCompletion.m | 25 +++++- .../FBSDKLoginKitTests/FBSDKIDTokenTests.m | 66 ++++++++++++++ 5 files changed, 240 insertions(+), 4 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index bc06cd2244..e580b89d8a 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -135,6 +135,11 @@ C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; + C66FC2A72553748C00A7909C /* FBSDKIDTokenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC29D2553748C00A7909C /* FBSDKIDTokenTests.m */; }; + C66FC2FE255376D200A7909C /* FBSDKIDToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKIDToken.h */; }; + C66FC2FF255376D200A7909C /* FBSDKIDToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKIDToken.m */; }; + C66FC338255377BF00A7909C /* FBSDKIDToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKIDToken.h */; }; + C66FC340255377F400A7909C /* FBSDKIDToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKIDToken.m */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -368,6 +373,9 @@ 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; + C66FC29D2553748C00A7909C /* FBSDKIDTokenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKIDTokenTests.m; sourceTree = ""; }; + C66FC2FC255376D100A7909C /* FBSDKIDToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKIDToken.h; sourceTree = ""; }; + C66FC2FD255376D100A7909C /* FBSDKIDToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKIDToken.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -536,6 +544,8 @@ 9D03E8271A72DCA700207493 /* Internal */ = { isa = PBXGroup; children = ( + C66FC2FC255376D100A7909C /* FBSDKIDToken.h */, + C66FC2FD255376D100A7909C /* FBSDKIDToken.m */, C6CE2BC124EB732C00CF2EB6 /* FBSDKReferralManager+Internal.h */, 0B9DBEFD207C04FF00662776 /* FBSDKDeviceLoginCodeInfo+Internal.h */, 0B9DBEF7207C04FF00662776 /* FBSDKDeviceLoginManagerResult+Internal.h */, @@ -632,6 +642,7 @@ 9D9DB8E81A114E500086167B /* FBSDKLoginKitTests */ = { isa = PBXGroup; children = ( + C66FC29D2553748C00A7909C /* FBSDKIDTokenTests.m */, C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */, 6B6276321A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.h */, 6B6276331A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m */, @@ -705,6 +716,7 @@ 0B9DBF0F207C051800662776 /* FBSDKDeviceLoginManager.h in Headers */, 818EB4321D1A283100252851 /* _FBSDKLoginRecoveryAttempter.h in Headers */, C6CE2BC324EB73B500CF2EB6 /* FBSDKReferralManager.h in Headers */, + C66FC338255377BF00A7909C /* FBSDKIDToken.h in Headers */, C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */, 818EB4331D1A283100252851 /* FBSDKCoreKit+Internal.h in Headers */, 818EB4341D1A283100252851 /* FBSDKLoginConstants.h in Headers */, @@ -735,6 +747,7 @@ C6CE2BBF24EB72F200CF2EB6 /* FBSDKReferralManager.h in Headers */, 9DBC4C3C1A782E2000816FE8 /* FBSDKCoreKit+Internal.h in Headers */, 9D03E8341A72DF5800207493 /* FBSDKLoginConstants.h in Headers */, + C66FC2FE255376D200A7909C /* FBSDKIDToken.h in Headers */, 9D9DB8DF1A114E500086167B /* FBSDKLoginKit.h in Headers */, 9D03E8251A72D89100207493 /* FBSDKLoginManagerLoginResult.h in Headers */, F4ECC67923EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, @@ -1090,6 +1103,7 @@ 818EB4291D1A283100252851 /* FBSDKLoginManager.m in Sources */, C625B49C24F97DF0003DCE23 /* FBSDKReferralManagerLogger.m in Sources */, F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */, + C66FC340255377F400A7909C /* FBSDKIDToken.m in Sources */, 818EB42A1D1A283100252851 /* FBSDKLoginManagerLoginResult.m in Sources */, C681486F24F86806004EED1A /* FBSDKReferralCode.m in Sources */, 818EB42B1D1A283100252851 /* FBSDKLoginTooltipView.m in Sources */, @@ -1117,6 +1131,7 @@ 9D03E8221A72D7E700207493 /* FBSDKLoginManager.m in Sources */, C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */, F46FA65A245347580060C902 /* FBLoginButton.swift in Sources */, + C66FC2FF255376D200A7909C /* FBSDKIDToken.m in Sources */, 9D03E8261A72D89100207493 /* FBSDKLoginManagerLoginResult.m in Sources */, C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */, 9DBA6A2A1A80252F00B4DE6A /* FBSDKLoginTooltipView.m in Sources */, @@ -1136,6 +1151,7 @@ buildActionMask = 2147483647; files = ( 9D641F841A7B69160048F563 /* FBSDKLoginManagerTests.m in Sources */, + C66FC2A72553748C00A7909C /* FBSDKIDTokenTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h new file mode 100644 index 0000000000..8b0cd7d7c4 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h @@ -0,0 +1,52 @@ +// 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 + +/** + Represent an ID Token used for OpenID connect (OIDC) protocal +*/ +NS_SWIFT_NAME(IDToken) +@interface FBSDKIDToken : NSObject + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + The decoded header of the ID token + */ +@property (nonatomic, copy, readonly) NSDictionary *header; + +/** + The decoded claims of the ID token + */ +@property (nonatomic, copy, readonly) NSDictionary *claims; + +/** + The signature of the ID token + */ +@property (nonatomic, copy, readonly) NSString *signature; + +/** + Initializes a new instance if the ID token is valid. Otherwise returns nil. + An ID Token is verified based of the OpenID connect standard. + @param idTokenString the raw ID token string +*/ +- (instancetype)initWithTokenString:(NSString *)idTokenString; + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m new file mode 100644 index 0000000000..eac4bbeadc --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m @@ -0,0 +1,85 @@ +// 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 "FBSDKIDToken.h" + +#import + +#if SWIFT_PACKAGE +@import FBSDKCoreKit; +#else + #import +#endif + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +@implementation FBSDKIDToken + +- (instancetype)initWithTokenString:(NSString *)idTokenString +{ + if (!idTokenString || idTokenString.length == 0) { + return nil; + } + + NSArray *segments = [idTokenString componentsSeparatedByString:@"."]; + if (segments.count != 3) { + return nil; + } + + if (self = [super init]) { + NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; + + // TODO(T78739428): verify signature + + [self setClaimsWithEncodedString:encodedClaims]; + } + + return self; +} + +- (void)setClaimsWithEncodedString:(NSString *)encodedClaims +{ + NSError *error; + NSData *claimsData = [FBSDKBase64 decodeAsData:encodedClaims]; + + if (claimsData) { + NSDictionary *decodedClaims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; + if (!error) { + // TODO(T78739428): verify claims + + _claims = decodedClaims; + } + } +} + +#pragma mark - Test methods + +#if DEBUG + ++ (instancetype)emptyInstance +{ + return [super new]; +} + +#endif + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index a5a9fe19e0..18c2471b6e 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -28,6 +28,7 @@ #import #endif + #import "FBSDKIDToken.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" @@ -125,13 +126,17 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; - _parameters.accessTokenString = parameters[@"access_token"]; - _parameters.nonceString = parameters[@"nonce"]; + FBSDKIDToken *idToken = [[FBSDKIDToken alloc] initWithTokenString:parameters[@"id_token"]]; - if (_parameters.accessTokenString.length > 0 || _parameters.nonceString.length > 0) { + if ([parameters[@"access_token"] length] > 0 + || [parameters[@"nonce"] length] > 0 + || idToken) { [self setParametersWithDictionary:parameters appID:appID]; + + if (idToken) { + [self setParametersWithIDToken:idToken]; + } } else { - _parameters.accessTokenString = nil; [self setErrorWithDictionary:parameters]; } } @@ -162,6 +167,9 @@ - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString * NSString *signedRequest = parameters[@"signed_request"]; NSString *userID = parameters[@"user_id"]; + _parameters.accessTokenString = parameters[@"access_token"]; + _parameters.nonceString = parameters[@"nonce"]; + // check the string length so that we assign an empty set rather than a set with an empty string _parameters.permissions = (grantedPermissionsString.length > 0) ? [NSSet setWithArray:[grantedPermissionsString componentsSeparatedByString:@","]] @@ -269,6 +277,15 @@ - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)ha [connection start]; } +- (void)setParametersWithIDToken:(FBSDKIDToken *)idToken +{ + if (!idToken || !idToken.claims) { + return; + } + + // TODO(T78739549): populate parameters with data from claims +} + @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m new file mode 100644 index 0000000000..6bd8ec35d4 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m @@ -0,0 +1,66 @@ +// 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 "FBSDKCoreKit+Internal.h" +#import "FBSDKIDToken.h" + +@interface FBSDKIDToken (Testing) + +- (void)setClaimsWithEncodedString:(NSString *)encodedClaims; + ++ (instancetype)emptyInstance; + +@end + +@interface FBSDKIDTokenTests : XCTestCase + +@end + +@implementation FBSDKIDTokenTests + +- (void)testDecodeValidClaims +{ + NSDictionary *expectedClaims = @{ + @"sub" : @"1234", + @"name" : @"Test User", + @"iss" : @"https://facebook.com/dialog/oauth", + @"aud" : @"4321", + @"nonce" : @"some_nonce", + @"exp" : @1516259022, + @"email" : @"email@email.com", + @"picture" : @"https://www.facebook.com/some_picture", + @"iat" : @1516239022, + }; + NSData *expectedClaimsData = [FBSDKTypeUtility dataWithJSONObject:expectedClaims options:0 error:nil]; + NSString *encodedClaims = [FBSDKBase64 encodeData:expectedClaimsData]; + FBSDKIDToken *idToken = [FBSDKIDToken emptyInstance]; + + [idToken setClaimsWithEncodedString:encodedClaims]; + XCTAssertEqualObjects(idToken.claims, expectedClaims); +} + +- (void)testCreateWithInvalidFormatTokenShouldFail +{ + FBSDKIDToken *idToken = [[FBSDKIDToken alloc] initWithTokenString:@"invalid_id_token"]; + XCTAssertNil(idToken); +} + +@end From ad5ed20570038003c3404f4d7085188c16c541de Mon Sep 17 00:00:00 2001 From: generatedunixname89002005325678 Date: Fri, 13 Nov 2020 07:06:19 -0800 Subject: [PATCH 105/227] Daily `arc lint --take UNCRUSTIFY` Reviewed By: samishchandra Differential Revision: D24947096 fbshipit-source-id: 8687c869e3b71eaa0ca87bc5c6fc108c67783e76 --- .../FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index fc0528fa56..580595f207 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -18,8 +18,8 @@ #import +#import "FBSDKBridgeAPI+Testing.h" #import "FBSDKEventDeactivationManager.h" #import "FBSDKServerConfigurationFixtures.h" -#import "FBSDKBridgeAPI+Testing.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" From d8d4d8886834c90b9a225aa5fd14f29d6b33a970 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 13 Nov 2020 14:54:12 -0800 Subject: [PATCH 106/227] Fix Xcode warning/error: Declaration shadows a local variable Summary: It feels like this should have been a warning but its showing up as an error. Renamed the connection parameter in the closure to _connection to fix. Reviewed By: jvlyn Differential Revision: D24934706 fbshipit-source-id: b7d172ffdb7cd3164a1f8c4dbf54642d4c34c0b1 --- .../FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m index ee5b267817..9b5fbcd865 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m @@ -592,7 +592,7 @@ - (void)testRequestWithBatchConstructionWithSingleGetRequest { FBSDKGraphRequest *singleRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields" : @"with_suffix"}]; FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; - [connection addRequest:singleRequest completionHandler:^(FBSDKGraphRequestConnection *_Nullable connection, id _Nullable result, NSError *_Nullable error) {}]; + [connection addRequest:singleRequest completionHandler:^(FBSDKGraphRequestConnection *_Nullable _connection, id _Nullable result, NSError *_Nullable error) {}]; NSURLRequest *request = [connection requestWithBatch:connection.requests timeout:0]; NSURLComponents *urlComponents = [NSURLComponents componentsWithString:request.URL.absoluteString]; @@ -610,7 +610,7 @@ - (void)testRequestWithBatchConstructionWithSinglePostRequest }; FBSDKGraphRequest *singleRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"activities" parameters:parameters HTTPMethod:FBSDKHTTPMethodPOST]; FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; - [connection addRequest:singleRequest completionHandler:^(FBSDKGraphRequestConnection *_Nullable connection, id _Nullable result, NSError *_Nullable error) {}]; + [connection addRequest:singleRequest completionHandler:^(FBSDKGraphRequestConnection *_Nullable _connection, id _Nullable result, NSError *_Nullable error) {}]; NSURLRequest *request = [connection requestWithBatch:connection.requests timeout:0]; NSURLComponents *urlComponents = [NSURLComponents componentsWithString:request.URL.absoluteString]; From 478105bc2359b9227430599a6eb87ca5174d7f01 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 13 Nov 2020 15:15:07 -0800 Subject: [PATCH 107/227] Proof of concept for having a Swift extension on an existing Objective-C test class Summary: Allowing for Swift extenions on tests will allow us to partially convert existing test classes to Swift and start writing new tests in Swift. The only caveat is that for the original test to be visible to the Swift extentsion of the test, its header needs to be part of the bridging header. Since the interface declaration for an XCTest isn't in a separate .h file but included within the .m file for the test there isn't a header file that can be included. However the actual interface declaration can be copied to the briding header which feels like a cleaner solution than to create a new .h file for inclusion in both the header and the original test. Reviewed By: joesus Differential Revision: D24867053 fbshipit-source-id: 51ba16e45e7d492573e5985f7eb3a82effc30574 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 4 ++ .../FBSDKCoreKitTests-Bridging-Header.h | 4 ++ .../AppEvents/FBSDKAppEventsUtilityTests.m | 22 ---------- .../FBSDKAppEventsUtilityTests.swift | 43 +++++++++++++++++++ 4 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 97d2316cb3..259f0d3251 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -129,6 +129,7 @@ 52D4F0D41D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */; }; 52D4F0D51D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */; }; 5C49DF9E2554C9ED00E0FD91 /* SampleUserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */; }; + 5CD6DB3C255B1D07002C296F /* FBSDKAppEventsUtilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CD6DB3B255B1D07002C296F /* FBSDKAppEventsUtilityTests.swift */; }; 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */; }; 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */; }; 5D41131A229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D411318229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m */; }; @@ -1239,6 +1240,7 @@ 52963AAB2159A16E00C7B252 /* FBSDKMeasurementEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMeasurementEvent.m; sourceTree = ""; }; 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleUserProfile.swift; sourceTree = ""; }; 5C59531F25548690000D0A3C /* FBSDKCoreKitTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKCoreKitTests-Bridging-Header.h"; sourceTree = ""; }; + 5CD6DB3B255B1D07002C296F /* FBSDKAppEventsUtilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKAppEventsUtilityTests.swift; sourceTree = ""; }; 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsTests.m; sourceTree = ""; }; 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKGraphRequestTests.m; sourceTree = ""; }; 5D411318229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterManager.m; sourceTree = ""; }; @@ -2201,6 +2203,7 @@ C51121C720A27EF50041DC94 /* Codeless */, 9D18A8DA1A95405A00A41042 /* FBSDKAppEventsStateTests.m */, 9D18A8E81A95495D00A41042 /* FBSDKAppEventsUtilityTests.m */, + 5CD6DB3B255B1D07002C296F /* FBSDKAppEventsUtilityTests.swift */, C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */, 5D2165E022264453004952D8 /* FBSDKAppEventsTests.m */, 5D68D7D722BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m */, @@ -4095,6 +4098,7 @@ F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */, 9DF18BCB1A9F2517000F6748 /* FBSDKErrorConfigurationTests.m in Sources */, 9D18A8E91A95495D00A41042 /* FBSDKAppEventsUtilityTests.m in Sources */, + 5CD6DB3C255B1D07002C296F /* FBSDKAppEventsUtilityTests.swift in Sources */, F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */, F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m in Sources */, F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 580595f207..3d1997dc86 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -23,3 +23,7 @@ #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" + +// Interfaces for Swift extensions on Objective-C Test classes +@interface FBSDKAppEventsUtilityTests : FBSDKTestCase +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 0835631f55..07b105789c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -322,28 +322,6 @@ - (void)testSendAppEvent OCMVerify([mockAppEventsState addEvent:OCMArg.any isImplicit:NO]); } -- (void)testIsSensitiveUserData -{ - NSString *text = @"test@sample.com"; - XCTAssertTrue([FBSDKAppEventsUtility isSensitiveUserData:text]); - - text = @"4716 5255 0221 9085"; - XCTAssertTrue([FBSDKAppEventsUtility isSensitiveUserData:text]); - - text = @"4716525502219085"; - XCTAssertTrue([FBSDKAppEventsUtility isSensitiveUserData:text]); - - text = @"4716525502219086"; - XCTAssertFalse([FBSDKAppEventsUtility isSensitiveUserData:text]); - - text = @""; - XCTAssertFalse([FBSDKAppEventsUtility isSensitiveUserData:text]); - - // number of digits less than 9 will not be considered as credit card number - text = @"4716525"; - XCTAssertFalse([FBSDKAppEventsUtility isSensitiveUserData:text]); -} - - (void)testFlushReasonToString { NSString *result1 = [FBSDKAppEventsUtility flushReasonToString:FBSDKAppEventsFlushReasonExplicit]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.swift new file mode 100644 index 0000000000..da3f92b088 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.swift @@ -0,0 +1,43 @@ +// 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 Foundation + +extension FBSDKAppEventsUtilityTests { + + func testIsSensitiveUserData() { + var text = "test@sample.com" + XCTAssertTrue(AppEventsUtility.isSensitiveUserData(text)) + + text = "4716 5255 0221 9085" + XCTAssertTrue(AppEventsUtility.isSensitiveUserData(text)) + + text = "4716525502219085" + XCTAssertTrue(AppEventsUtility.isSensitiveUserData(text)) + + text = "4716525502219086" + XCTAssertFalse(AppEventsUtility.isSensitiveUserData(text)) + + text = "" + XCTAssertFalse(AppEventsUtility.isSensitiveUserData(text)) + + // number of digits less than 9 will not be considered as credit card number + text = "4716525" + XCTAssertFalse(AppEventsUtility.isSensitiveUserData(text)) + } +} From 15cd0f4a7fca2039f7e26baee5fcf0b1692bc82a Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 13 Nov 2020 15:24:23 -0800 Subject: [PATCH 108/227] Convert the FakeMonitorStore test helper to Swift Summary: Converted the FakeMonitorStore test helper to Swift Reviewed By: joesus Differential Revision: D24875574 fbshipit-source-id: 8efdeb18dfc753e0c0ddd58492338819d61ed33d --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 ++--- .../Internal/Monitoring/FBSDKMonitorTests.m | 2 +- .../Internal/Monitoring/FakeMonitorStore.h | 34 ----------------- ...eMonitorStore.m => FakeMonitorStore.swift} | 38 +++++++++---------- 4 files changed, 24 insertions(+), 60 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.h rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/{FakeMonitorStore.m => FakeMonitorStore.swift} (63%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 259f0d3251..802100cab0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -837,7 +837,7 @@ F4210E36241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */; }; - F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.m */; }; + F43960D02425513100C1868F /* FakeMonitorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.swift */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -1544,8 +1544,7 @@ F4210E2C241B00790061F56D /* FBSDKMethodUsageMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMethodUsageMonitor.h; sourceTree = ""; }; F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitor.m; sourceTree = ""; }; F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationManagerTests.m; sourceTree = ""; }; - F43960CE2425513100C1868F /* FakeMonitorStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeMonitorStore.h; sourceTree = ""; }; - F43960CF2425513100C1868F /* FakeMonitorStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeMonitorStore.m; sourceTree = ""; }; + F43960CF2425513100C1868F /* FakeMonitorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeMonitorStore.swift; sourceTree = ""; }; F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; @@ -2593,8 +2592,7 @@ F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */, F48A6AEB24170D29002C6CA1 /* TestMonitorEntry.h */, F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */, - F43960CE2425513100C1868F /* FakeMonitorStore.h */, - F43960CF2425513100C1868F /* FakeMonitorStore.m */, + F43960CF2425513100C1868F /* FakeMonitorStore.swift */, F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */, F4A52B0A242A99C8005F65CE /* FBSDKPerformanceMonitorTests.m */, F420D1842433B73E00D4FA82 /* FBSDKMonitorConfigurationTests.m */, @@ -4121,7 +4119,7 @@ F4D8D8FA242293ED00C28384 /* FBSDKMonitorNetworkerTests.m in Sources */, 894C0B4A1A70524F009137EF /* FBSDKBase64Tests.swift in Sources */, F420D1852433B73E00D4FA82 /* FBSDKMonitorConfigurationTests.m in Sources */, - F43960D02425513100C1868F /* FakeMonitorStore.m in Sources */, + F43960D02425513100C1868F /* FakeMonitorStore.swift in Sources */, 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */, F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */, F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m index 4602a4fbc7..8a7540e99b 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorTests.m @@ -20,8 +20,8 @@ #import #import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitTests-Swift.h" #import "FBSDKTestCase.h" -#import "FakeMonitorStore.h" #import "TestMonitorEntry.h" @interface FBSDKMonitor (Testing) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.h deleted file mode 100644 index 1cd5f69a27..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.h +++ /dev/null @@ -1,34 +0,0 @@ -// 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 "FBSDKCoreKit+Internal.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FakeMonitorStore : FBSDKMonitorStore - -@property (nonatomic) BOOL clearWasCalled; -@property (nonatomic) BOOL retrieveEntriesWasCalled; -@property (nonatomic) BOOL persistWasCalled; -@property (nonatomic, copy) NSArray> *capturedPersistedEntries; - -@end - -NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift similarity index 63% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift index e0614beebd..b54b6e2952 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift @@ -16,30 +16,30 @@ // 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 "FakeMonitorStore.h" +@objcMembers +public class FakeMonitorStore: FBSDKMonitorStore { -@implementation FakeMonitorStore + public var clearWasCalled = false + public var retrieveEntriesWasCalled = false + public var persistWasCalled = false + public var capturedPersistedEntries: [FBSDKMonitorEntry] = [] -- (void)persist:(NSArray> *)entries -{ - [super persist:entries]; + override public func persist(_ entries: [FBSDKMonitorEntry]) { + super.persist(entries) - self.persistWasCalled = true; - self.capturedPersistedEntries = entries; -} + persistWasCalled = true + capturedPersistedEntries = entries + } -- (NSArray> *)retrieveEntries -{ - self.retrieveEntriesWasCalled = true; + override public func retrieveEntries() -> [FBSDKMonitorEntry] { + retrieveEntriesWasCalled = true - return [super retrieveEntries]; -} + return super.retrieveEntries() + } -- (void)clear -{ - [super clear]; + override public func clear() { + super.clear() - self.clearWasCalled = true; + clearWasCalled = true + } } - -@end From df440630ab8e81535ba19b1a41825add18642368 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 13 Nov 2020 15:42:00 -0800 Subject: [PATCH 109/227] Convert the AppDelegateObserverFake.m test helper to Swift Summary: Converted the AppDelegateObserverFake.m test helper to Swift Reviewed By: joesus Differential Revision: D24930092 fbshipit-source-id: 3b3439927fb81c4bd6429fd48ee89784515355e4 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +++--- .../FBSDKApplicationDelegateTests.m | 1 - .../Helpers/AppDelegateObserverFake.h | 32 ------------------- ...erFake.m => AppDelegateObserverFake.swift} | 28 ++++++---------- 4 files changed, 13 insertions(+), 58 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{AppDelegateObserverFake.m => AppDelegateObserverFake.swift} (67%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 802100cab0..d48ff6e9f8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -913,7 +913,7 @@ F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */; }; F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.swift */; }; - F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */; }; + F496E61224E6049A006231A2 /* AppDelegateObserverFake.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */; }; F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */; }; F4A52AFE242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A52AFC242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h */; }; F4A52AFF242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = F4A52AFC242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h */; }; @@ -1567,8 +1567,7 @@ F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAccessTokenCache.swift; sourceTree = ""; }; F496E60E24E5D195006231A2 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; - F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegateObserverFake.h; sourceTree = ""; }; - F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegateObserverFake.m; sourceTree = ""; }; + F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegateObserverFake.swift; sourceTree = ""; }; F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTypeUtility.h; sourceTree = ""; }; F4A11B4924E36E5200D4C010 /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKURLSessionTask.h; sourceTree = ""; }; F4A11B4A24E36E5200D4C010 /* FBSDKSafeCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSafeCast.h; sourceTree = ""; }; @@ -2665,8 +2664,7 @@ F4DE31F524DB695100297C18 /* FBSDKTestCase.m */, F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */, F496E60E24E5D195006231A2 /* SampleAccessToken.swift */, - F496E61024E6049A006231A2 /* AppDelegateObserverFake.h */, - F496E61124E6049A006231A2 /* AppDelegateObserverFake.m */, + F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */, F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.swift */, F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */, F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, @@ -4107,7 +4105,7 @@ F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.swift in Sources */, F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */, E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */, - F496E61224E6049A006231A2 /* AppDelegateObserverFake.m in Sources */, + F496E61224E6049A006231A2 /* AppDelegateObserverFake.swift in Sources */, BF5D97C3242EC2D10096D7AA /* FBSDKFeatureExtractorTests.m in Sources */, 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.swift in Sources */, 7E253D831A8EB76500CCCFE7 /* FBSDKCoreKitTestUtility.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index 32f9435ae9..52c42d2640 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -19,7 +19,6 @@ #import #import -#import "AppDelegateObserverFake.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" #import "FBSDKCoreKitTests-Swift.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h deleted file mode 100644 index ac996c5f88..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.h +++ /dev/null @@ -1,32 +0,0 @@ -// 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 "FBSDKApplicationObserving.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface ApplicationDelegateObserverFake : NSObject - -@property (readonly, assign) int didFinishLaunchingCallCount; -@property (nullable, readonly, copy) NSDictionary *capturedLaunchOptions; - -@end - -NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift similarity index 67% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift index dba2a9027d..c3ea5c45c4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift @@ -16,25 +16,15 @@ // 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 "AppDelegateObserverFake.h" +@objcMembers +public class ApplicationDelegateObserverFake: NSObject, FBSDKApplicationObserving { + public private(set) var didFinishLaunchingCallCount = 0 + public private(set) var capturedLaunchOptions: [UIApplication.LaunchOptionsKey: Any]? -@implementation ApplicationDelegateObserverFake - -- (instancetype)init -{ - if (self = [super init]) { - _didFinishLaunchingCallCount = 0; - _capturedLaunchOptions = [NSDictionary dictionary]; + public func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { + didFinishLaunchingCallCount += 1 + capturedLaunchOptions = launchOptions + return true } - return self; } - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - _didFinishLaunchingCallCount++; - _capturedLaunchOptions = launchOptions; - - return true; -} - -@end From 2b4163c70fd7b2497802a2cfdf15362d1f3a8e42 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 13 Nov 2020 17:23:53 -0800 Subject: [PATCH 110/227] Convert FBSDKServerConfigurationManagerTests to Swift Summary: Converted FBSDKServerConfigurationManagerTests to Swift Reviewed By: joesus Differential Revision: D24930396 fbshipit-source-id: 5131adb1d0a4ef7d02c3afad7ce77b781de378dc --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 ++--- ...BSDKServerConfigurationManagerTests.swift} | 31 ++++--------------- 2 files changed, 10 insertions(+), 29 deletions(-) rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/{FBSDKServerConfigurationManagerTests.m => FBSDKServerConfigurationManagerTests.swift} (63%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index d48ff6e9f8..c51f45db4a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -836,8 +836,8 @@ F4210E35241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F4210E36241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; - F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */; }; F43960D02425513100C1868F /* FakeMonitorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.swift */; }; + F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -1543,8 +1543,8 @@ F4210E1D241AFF740061F56D /* FBSDKMethodUsageMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorTests.m; sourceTree = ""; }; F4210E2C241B00790061F56D /* FBSDKMethodUsageMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMethodUsageMonitor.h; sourceTree = ""; }; F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitor.m; sourceTree = ""; }; - F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKServerConfigurationManagerTests.m; sourceTree = ""; }; F43960CF2425513100C1868F /* FakeMonitorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeMonitorStore.swift; sourceTree = ""; }; + F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKServerConfigurationManagerTests.swift; sourceTree = ""; }; F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; @@ -2683,7 +2683,7 @@ isa = PBXGroup; children = ( F4E50154243648A100C99262 /* FBSDKServerConfigurationTests.m */, - F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m */, + F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */, F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */, ); path = ServerConfiguration; @@ -4130,7 +4130,7 @@ F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */, 5D497702244A3E6A00BD45C6 /* FBSDKIntegrityTests.m in Sources */, F4210E1E241AFF740061F56D /* FBSDKMethodUsageMonitorTests.m in Sources */, - F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.m in Sources */, + F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */, F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift similarity index 63% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift index 7865981db9..1366562986 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift @@ -16,31 +16,12 @@ // 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 XCTest -#import - -#import "FBSDKCoreKit+Internal.h" -#import "FBSDKCoreKitTests-Swift.h" - -@interface FBSDKServerConfigurationManager (Testing) - -+ (void)processLoadRequestResponse:(id)result error:(NSError *)error appID:(NSString *)appID; - -@end - -@interface FBSDKServerConfigurationManagerTests : XCTestCase - -@end - -@implementation FBSDKServerConfigurationManagerTests - -- (void)testParsingResponses -{ - for (int i = 0; i < 100; i++) { - [FBSDKServerConfigurationManager processLoadRequestResponse:RawServerConfigurationResponseFixtures.random error:nil appID:nil]; +class FBSDKServerConfigurationManagerTests: XCTestCase { + func testParsingResponses() { + for _ in 0..<100 { + ServerConfigurationManager.processLoadRequestResponse(RawServerConfigurationResponseFixtures.random, error: nil, appID: nil) + } } } - -@end From 03144c3d27f0287b0a0c743a44d64699aa7d4d4d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Sat, 14 Nov 2020 09:22:02 -0800 Subject: [PATCH 111/227] FBSDKBridgeAPI Unit Tests 3/n Summary: I should probably explain myself here. This is what I usually refer to as a scaffolding test. The idea is to capture the existing behavior of a method as accurately as possible so that it's easy to avoid side effects when refactoring. The `application:openURL:sourceApplication:annotation:` method on `FBSDKBridgeAPI` has side effects that depend on the following dependencies and pieces of Bridge API state: **Dependencies** * `_pendingURLOpen`'s `canOpenURL:forApplication:sourceApplication:annotation:` (Yes / No) * `_pendingURLOpen`'s `shouldStopPropagationOfURL:` (Yes / No) **State** * `_safariViewController` property (Nil / Not Nil) * `_isDismissingSafariViewController` property (Yes / No) * `_authenticationSessionCompletionHandler` property (Nil / Not Nil) * `_handleBridgeAPIResponseURL:sourceApplication:` return value (Yes / No) The tests in this diff capture the following side effects (state) for each of the above permutations: * Return value for entire method * `_authenticationSession`'s `cancel` method called? * `_authenticationSession` property nil'd out? * `_authenticationSessionCompletionHandler` invoked? With what args? * `_authenticationSessionCompletionHandler` property nil'd out? * `_pendingURLOpen` property nil'd out? * `_pendingURLOpen`'s `canOpenURL:forApplication:sourceApplication:annotation:` called? With what args? * `_pendingURLOpen`'s `application:openURL:sourceAnnotation:annotation:` called? With what args? * `_safariViewController` property nil'd out? * `_isDismissingSafariViewController` value? * `_pendingRequest` property nil'd out? * `_pendingRequestCompletionBlock` nil'd out? * `_pendingRequestCompletionBlock` invoked? With what args? * `_authenticationSessionState` changed? Reviewed By: jawwad Differential Revision: D24952670 fbshipit-source-id: 91598be7ac6c7c6a18980743d9b409395e4c93ef --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 + .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 63 +- .../BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m | 973 ++++++++++++++++++ .../Internal/BridgeAPI/FBSDKBridgeAPITests.h | 39 + .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 48 +- .../Internal/Helpers/FBSDKBridgeAPI+Testing.h | 20 +- .../Internal/Helpers/FakeLoginManager.h | 7 + .../Internal/Helpers/FakeLoginManager.m | 28 +- .../Internal/Helpers/ViewControllerSpy.swift | 42 + 9 files changed, 1199 insertions(+), 31 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index c51f45db4a..7d83dcd6e6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -792,6 +792,7 @@ F402AFC8255B49A500473083 /* FBSDKBridgeAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */; }; F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */; }; F402B062255C645600473083 /* FakeLoginManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F402B061255C645600473083 /* FakeLoginManager.m */; }; + F402B071255C740C00473083 /* ViewControllerSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F402B070255C740C00473083 /* ViewControllerSpy.swift */; }; F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */; }; F40B24C224732DD90059351C /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24C124732DD90059351C /* Fuzzer.swift */; }; F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */; }; @@ -803,6 +804,7 @@ F40F6568241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; F40F6569241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; F40F656A241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; + F41200D0255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41200CF255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m */; }; F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */; }; F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */; }; F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41979272475A20E003007CC /* FBSDKTypeUtilityTests.m */; }; @@ -1526,11 +1528,14 @@ F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationSessionSpy.swift; sourceTree = ""; }; F402B060255C645600473083 /* FakeLoginManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeLoginManager.h; sourceTree = ""; }; F402B061255C645600473083 /* FakeLoginManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeLoginManager.m; sourceTree = ""; }; + F402B070255C740C00473083 /* ViewControllerSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerSpy.swift; sourceTree = ""; }; F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawServerConfigurationResponseFixtures.swift; sourceTree = ""; }; F40B24C124732DD90059351C /* Fuzzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntryTests.m; sourceTree = ""; }; F40F655F241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMethodUsageMonitorEntry.h; sourceTree = ""; }; F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntry.m; sourceTree = ""; }; + F41200CF255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "FBSDKBridgeAPI+OpenUrlTests.m"; sourceTree = ""; }; + F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKBridgeAPITests.h; sourceTree = ""; }; F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCastTests.m; path = Internal/Basics/FBSDKSafeCastTests.m; sourceTree = ""; }; F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorTests.m; sourceTree = ""; }; F41979272475A20E003007CC /* FBSDKTypeUtilityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtilityTests.m; sourceTree = ""; }; @@ -2099,6 +2104,8 @@ children = ( 894C0B351A702DDD009137EF /* ProtocolVersions */, F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */, + F41200CF255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m */, + F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */, ); path = BridgeAPI; sourceTree = ""; @@ -2673,6 +2680,7 @@ F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */, 5C49DF8F2554C9ED00E0FD91 /* SampleUserProfile.swift */, F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */, + F402B070255C740C00473083 /* ViewControllerSpy.swift */, F402B060255C645600473083 /* FakeLoginManager.h */, F402B061255C645600473083 /* FakeLoginManager.m */, ); @@ -4124,6 +4132,7 @@ 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift in Sources */, F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */, 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */, + F402B071255C740C00473083 /* ViewControllerSpy.swift in Sources */, F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m in Sources */, 7E253D811A8EAEF500CCCFE7 /* FBSDKInternalUtilityTests.m in Sources */, C5F6EC861FA24FAF009EB258 /* FBSDKPaymentObserverTests.m in Sources */, @@ -4148,6 +4157,7 @@ 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */, F4EB317F2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m in Sources */, F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, + F41200D0255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, F402B062255C645600473083 /* FakeLoginManager.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 2c1465fa0d..b2a8df73a5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -188,8 +188,10 @@ - (BOOL)application:(UIApplication *)application initWithDomain:FBSDKErrorDomain code:FBSDKErrorBridgeAPIInterruption userInfo:@{FBSDKErrorLocalizedDescriptionKey : errorMessage}]; - _authenticationSessionCompletionHandler(url, loginError); - _authenticationSessionCompletionHandler = nil; + if (_authenticationSessionCompletionHandler) { + _authenticationSessionCompletionHandler(url, loginError); + _authenticationSessionCompletionHandler = nil; + } } } } @@ -532,6 +534,8 @@ - (UIWindow *)presentationAnchorForWebAuthenticationSession:(id)authenticationSession @@ -554,6 +558,11 @@ - (void)setAuthenticationSessionState:(FBSDKAuthenticationSession)state _authenticationSessionState = state; } +- (FBSDKAuthenticationCompletionHandler)authenticationSessionCompletionHandler +{ + return _authenticationSessionCompletionHandler; +} + - (void)setAuthenticationSessionCompletionHandler:(FBSDKAuthenticationCompletionHandler)handler { _authenticationSessionCompletionHandler = handler; @@ -574,6 +583,56 @@ - (void)setExpectingBackground:(BOOL)isExpectingBackground _expectingBackground = isExpectingBackground; } +- (id)pendingUrlOpen +{ + return _pendingURLOpen; +} + +- (void)setPendingUrlOpen:(id)opening +{ + _pendingURLOpen = opening; +} + +- (UIViewController *)safariViewController +{ + return _safariViewController; +} + +- (void)setSafariViewController:(nullable UIViewController *)controller +{ + _safariViewController = controller; +} + +- (BOOL)isDismissingSafariViewController +{ + return _isDismissingSafariViewController; +} + +- (void)setIsDismissingSafariViewController:(BOOL)isDismissing +{ + _isDismissingSafariViewController = isDismissing; +} + +- (FBSDKBridgeAPIRequest *)pendingRequest +{ + return _pendingRequest; +} + +- (void)setPendingRequest:(FBSDKBridgeAPIRequest *)newValue +{ + _pendingRequest = newValue; +} + +- (FBSDKBridgeAPIResponseBlock)pendingRequestCompletionBlock +{ + return _pendingRequestCompletionBlock; +} + +- (void)setPendingRequestCompletionBlock:(FBSDKBridgeAPIResponseBlock)newValue +{ + _pendingRequestCompletionBlock = newValue; +} + #endif @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m new file mode 100644 index 0000000000..ea00594e7a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m @@ -0,0 +1,973 @@ +// 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 "FBSDKBridgeAPITests.h" + +@implementation FBSDKBridgeAPITests (OpenURLTests) + +// MARK: - Url Opening + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:YES + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_ShouldStopPropagationPendingUrlCannotOpenUrlWithSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:YES + pendingUrlCanOpenUrl:NO + hasSafariViewController:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + hasSafariViewController:NO + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedAuthCancelCallCount:1 + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:NO]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCanOpenUrlWithSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenUrlWithPendingUrlCanOpenUrl:YES + isDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:YES + expectedAuthSessionCompletionExists:YES]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:NO]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:NO]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:YES + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:YES]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhileDismissingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:YES + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:NO]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:YES]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithoutAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:NO + authSessionCompletionHandlerExists:NO + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:NO]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerAbleToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:YES + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:YES]; +} + +- (void)testOpenUrl_PendingUrlCannotOpenUrlWithoutSafariVcWhilePresentingSafariVcWithAuthSessionCompletionHandlerUnableToHandleBridgeApiResponse +{ + [self verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:NO + authSessionCompletionHandlerExists:YES + canHandleBridgeApiResponse:NO + expectedIsDismissingSafariVc:NO + expectedAuthSessionCompletionExists:NO + expectedReturnValue:NO]; +} + +// MARK: - Helpers + +/// Assumes should not stop propagation of url +/// Assumes SafariViewController is not nil +- (void)verifyOpenUrlWithPendingUrlCanOpenUrl:(BOOL)pendingUrlCanOpenUrl + isDismissingSafariViewController:(BOOL)isDismissingSafariViewController + authSessionCompletionHandlerExists:(BOOL)authSessionCompletionHandlerExists + canHandleBridgeApiResponse:(BOOL)canHandleBridgeApiResponse + expectedIsDismissingSafariVc:(BOOL)expectedIsDismissingSafariVc + expectedAuthSessionCompletionExists:(BOOL)expectedAuthSessionCompletionExists +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:NO + pendingUrlCanOpenUrl:pendingUrlCanOpenUrl + hasSafariViewController:YES + isDismissingSafariViewController:isDismissingSafariViewController + authSessionCompletionHandlerExists:authSessionCompletionHandlerExists + canHandleBridgeApiResponse:canHandleBridgeApiResponse + expectedAuthSessionCompletionHandlerUrl:nil + expectedAuthSessionCompletionHandlerError:nil + expectAuthSessionCompletionHandlerInvoked:NO + expectedAuthCancelCallCount:0 + expectedAuthSessionExists:YES + expectedAuthSessionCompletionExists:expectedAuthSessionCompletionExists + expectedCanOpenUrlUrl:self.sampleUrl + expectedCanOpenUrlSource:sampleSource + expectedCanOpenUrlAnnotation:sampleAnnotation + expectedOpenUrlUrl:nil + expectedOpenUrlSource:nil + expectedOpenUrlAnnotation:nil + expectedPendingUrlOpenExists:YES + expectedIsDismissingSafariVc:expectedIsDismissingSafariVc + expectedSafariVcExists:NO + expectedReturnValue:YES]; +} + +/// Assumes should not stop propagation of url +/// Assumes Pending Url cannot open +/// Assumes SafariViewController is nil +- (void)verifyOpenURLWithoutSafariVcWhileDismissingSafariViewController:(BOOL)isDismissingSafariViewController + authSessionCompletionHandlerExists:(BOOL)authSessionCompletionHandlerExists + canHandleBridgeApiResponse:(BOOL)canHandleBridgeApiResponse + expectedIsDismissingSafariVc:(BOOL)expectedIsDismissingSafariVc + expectedAuthSessionCompletionExists:(BOOL)expectedAuthSessionCompletionExists + expectedReturnValue:(BOOL)expectedReturnValue +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:NO + pendingUrlCanOpenUrl:NO + hasSafariViewController:NO + isDismissingSafariViewController:isDismissingSafariViewController + authSessionCompletionHandlerExists:authSessionCompletionHandlerExists + canHandleBridgeApiResponse:canHandleBridgeApiResponse + expectedAuthSessionCompletionHandlerUrl:self.sampleUrl + expectedAuthSessionCompletionHandlerError:self.loginInterruptionError + expectAuthSessionCompletionHandlerInvoked:YES + expectedAuthCancelCallCount:1 + expectedAuthSessionExists:NO + expectedAuthSessionCompletionExists:expectedAuthSessionCompletionExists + expectedCanOpenUrlUrl:self.sampleUrl + expectedCanOpenUrlSource:sampleSource + expectedCanOpenUrlAnnotation:sampleAnnotation + expectedOpenUrlUrl:self.sampleUrl + expectedOpenUrlSource:sampleSource + expectedOpenUrlAnnotation:sampleAnnotation + expectedPendingUrlOpenExists:NO + expectedIsDismissingSafariVc:expectedIsDismissingSafariVc + expectedSafariVcExists:NO + expectedReturnValue:expectedReturnValue]; +} + +/// Assumes should not stop propagation of url +- (void)verifyOpenUrlWithPendingUrlCanOpenUrl:(BOOL)pendingUrlCanOpenUrl + hasSafariViewController:(BOOL)hasSafariViewController + isDismissingSafariViewController:(BOOL)isDismissingSafariViewController + authSessionCompletionHandlerExists:(BOOL)authSessionCompletionHandlerExists + canHandleBridgeApiResponse:(BOOL)canHandleBridgeApiResponse + expectedAuthCancelCallCount:(int)expectedAuthCancelCallCount + expectedIsDismissingSafariVc:(BOOL)expectedIsDismissingSafariVc + expectedAuthSessionCompletionExists:(BOOL)expectedAuthSessionCompletionExists +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:NO + pendingUrlCanOpenUrl:pendingUrlCanOpenUrl + hasSafariViewController:hasSafariViewController + isDismissingSafariViewController:isDismissingSafariViewController + authSessionCompletionHandlerExists:authSessionCompletionHandlerExists + canHandleBridgeApiResponse:canHandleBridgeApiResponse + expectedAuthSessionCompletionHandlerUrl:nil + expectedAuthSessionCompletionHandlerError:nil + expectAuthSessionCompletionHandlerInvoked:NO + expectedAuthCancelCallCount:expectedAuthCancelCallCount + expectedAuthSessionExists:NO + expectedAuthSessionCompletionExists:expectedAuthSessionCompletionExists + expectedCanOpenUrlUrl:self.sampleUrl + expectedCanOpenUrlSource:sampleSource + expectedCanOpenUrlAnnotation:sampleAnnotation + expectedOpenUrlUrl:self.sampleUrl + expectedOpenUrlSource:sampleSource + expectedOpenUrlAnnotation:sampleAnnotation + expectedPendingUrlOpenExists:NO + expectedIsDismissingSafariVc:expectedIsDismissingSafariVc + expectedSafariVcExists:hasSafariViewController + expectedReturnValue:YES]; +} + +- (void)verifyOpenUrlWithShouldStopPropagationOfUrl:(BOOL)shouldStopPropagationOfURL + pendingUrlCanOpenUrl:(BOOL)pendingUrlCanOpenUrl + hasSafariViewController:(BOOL)hasSafariViewController + isDismissingSafariViewController:(BOOL)isDismissingSafariViewController + authSessionCompletionHandlerExists:(BOOL)authSessionCompletionHandlerExists + canHandleBridgeApiResponse:(BOOL)canHandleBridgeApiResponse + expectedAuthSessionCompletionExists:(BOOL)expectedAuthSessionCompletionExists +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:shouldStopPropagationOfURL + pendingUrlCanOpenUrl:pendingUrlCanOpenUrl + hasSafariViewController:hasSafariViewController + isDismissingSafariViewController:isDismissingSafariViewController + authSessionCompletionHandlerExists:authSessionCompletionHandlerExists + canHandleBridgeApiResponse:canHandleBridgeApiResponse + expectedAuthSessionCompletionHandlerUrl:nil + expectedAuthSessionCompletionHandlerError:nil + expectAuthSessionCompletionHandlerInvoked:NO + expectedAuthCancelCallCount:0 + expectedAuthSessionExists:YES + expectedAuthSessionCompletionExists:expectedAuthSessionCompletionExists + expectedCanOpenUrlUrl:nil + expectedCanOpenUrlSource:nil + expectedCanOpenUrlAnnotation:nil + expectedOpenUrlUrl:nil + expectedOpenUrlSource:nil + expectedOpenUrlAnnotation:nil + expectedPendingUrlOpenExists:YES + expectedIsDismissingSafariVc:isDismissingSafariViewController // Should not change the value + expectedSafariVcExists:hasSafariViewController + expectedReturnValue:YES]; +} + +/// Assumes SafariViewController is nil +- (void)verifyOpenUrlWithShouldStopPropagationOfUrl:(BOOL)shouldStopPropagationOfURL + pendingUrlCanOpenUrl:(BOOL)pendingUrlCanOpenUrl + isDismissingSafariViewController:(BOOL)isDismissingSafariViewController + authSessionCompletionHandlerExists:(BOOL)authSessionCompletionHandlerExists + canHandleBridgeApiResponse:(BOOL)canHandleBridgeApiResponse + expectedAuthSessionCompletionExists:(BOOL)expectedAuthSessionCompletionExists +{ + [self verifyOpenUrlWithShouldStopPropagationOfUrl:shouldStopPropagationOfURL + pendingUrlCanOpenUrl:pendingUrlCanOpenUrl + hasSafariViewController:NO + isDismissingSafariViewController:isDismissingSafariViewController + authSessionCompletionHandlerExists:authSessionCompletionHandlerExists + canHandleBridgeApiResponse:canHandleBridgeApiResponse + expectedAuthSessionCompletionHandlerUrl:nil + expectedAuthSessionCompletionHandlerError:nil + expectAuthSessionCompletionHandlerInvoked:NO + expectedAuthCancelCallCount:0 + expectedAuthSessionExists:YES + expectedAuthSessionCompletionExists:expectedAuthSessionCompletionExists + expectedCanOpenUrlUrl:nil + expectedCanOpenUrlSource:nil + expectedCanOpenUrlAnnotation:nil + expectedOpenUrlUrl:nil + expectedOpenUrlSource:nil + expectedOpenUrlAnnotation:nil + expectedPendingUrlOpenExists:YES + expectedIsDismissingSafariVc:isDismissingSafariViewController // Should not change this value + expectedSafariVcExists:NO + expectedReturnValue:YES]; +} + +- (void)verifyOpenUrlWithShouldStopPropagationOfUrl:(BOOL)shouldStopPropagationOfURL + pendingUrlCanOpenUrl:(BOOL)pendingUrlCanOpenUrl + hasSafariViewController:(BOOL)hasSafariViewController + isDismissingSafariViewController:(BOOL)isDismissingSafariViewController + authSessionCompletionHandlerExists:(BOOL)authSessionCompletionHandlerExists + canHandleBridgeApiResponse:(BOOL)canHandleBridgeApiResponse + expectedAuthSessionCompletionHandlerUrl:(NSURL *)expectedAuthSessionCompletionHandlerUrl + expectedAuthSessionCompletionHandlerError:(NSError *)expectedAuthSessionCompletionHandlerError + expectAuthSessionCompletionHandlerInvoked:(BOOL)expectAuthSessionCompletionHandlerInvoked + expectedAuthCancelCallCount:(int)expectedAuthCancelCallCount + expectedAuthSessionExists:(BOOL)expectedAuthSessionExists + expectedAuthSessionCompletionExists:(BOOL)expectedAuthSessionCompletionExists + expectedCanOpenUrlUrl:(NSURL *)expectedCanOpenUrlCalledWithUrl + expectedCanOpenUrlSource:(NSString *)expectedCanOpenUrlSource + expectedCanOpenUrlAnnotation:(NSString *)expectedCanOpenUrlAnnotation + expectedOpenUrlUrl:(NSURL *)expectedOpenUrlUrl + expectedOpenUrlSource:(NSString *)expectedOpenUrlSource + expectedOpenUrlAnnotation:(NSString *)expectedOpenUrlAnnotation + expectedPendingUrlOpenExists:(BOOL)expectedPendingUrlOpenExists + expectedIsDismissingSafariVc:(BOOL)expectedIsDismissingSafariVc + expectedSafariVcExists:(BOOL)expectedSafariVcExists + expectedReturnValue:(BOOL)expectedReturnValue +{ + FBSDKLoginManager *urlOpener = [FBSDKLoginManager new]; + AuthenticationSessionSpy *authSessionSpy = [[AuthenticationSessionSpy alloc] initWithURL:self.sampleUrl + callbackURLScheme:nil + completionHandler:^(NSURL *_Nullable callbackURL, NSError *_Nullable error) { + XCTFail("Should not invoke the completion for the authentication session"); + }]; + [urlOpener stubShouldStopPropagationOfURL:self.sampleUrl withValue:shouldStopPropagationOfURL]; + urlOpener.stubbedCanOpenUrl = pendingUrlCanOpenUrl; + + self.api.pendingUrlOpen = urlOpener; + + if (hasSafariViewController) { + ViewControllerSpy *viewControllerSpy = ViewControllerSpy.makeDefaultSpy; + self.api.safariViewController = viewControllerSpy; + } + self.api.isDismissingSafariViewController = isDismissingSafariViewController; + self.api.authenticationSessionState = FBSDKAuthenticationSessionNone; + self.api.pendingRequest = self.sampleBridgeApiRequest; + self.api.authenticationSession = authSessionSpy; + if (authSessionCompletionHandlerExists) { + self.api.authenticationSessionCompletionHandler = ^(NSURL *callbackURL, NSError *error) { + if (!expectAuthSessionCompletionHandlerInvoked) { + XCTFail("Should not invoke the authentication session completion handler"); + } + XCTAssertEqualObjects( + callbackURL, + expectedAuthSessionCompletionHandlerUrl, + "Should invoke the authentication session completion handler with the expected URL" + ); + XCTAssertEqualObjects( + error, + expectedAuthSessionCompletionHandlerError, + "Should invoke the authentication session completion handler with the expected error" + ); + }; + } + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *response) { + XCTFail("Should not invoke the pending request completion block"); + }; + id mock = [self stubHandleBridgeApiResponseAndReturn:canHandleBridgeApiResponse]; + + BOOL returnValue = [self.api application:UIApplication.sharedApplication + openURL:self.sampleUrl + sourceApplication:sampleSource + annotation:sampleAnnotation]; + XCTAssertEqual( + returnValue, + expectedReturnValue, + "The return value for the overall method should be %@", + StringFromBool(expectedReturnValue) + ); + if (expectedAuthSessionExists) { + XCTAssertNotNil(self.api.authenticationSession, "The authentication session should not be nil"); + } else { + XCTAssertNil(self.api.authenticationSession, "The authentication session should be nil"); + } + if (expectedAuthSessionCompletionExists) { + XCTAssertNotNil( + self.api.authenticationSessionCompletionHandler, + "The authentication session completion handler should not be nil" + ); + } else { + XCTAssertNil( + self.api.authenticationSessionCompletionHandler, + "The authentication session completion handler should be nil" + ); + } + XCTAssertEqual( + authSessionSpy.cancelCallCount, + expectedAuthCancelCallCount, + "The authentication session should be cancelled the expected number of times" + ); + XCTAssertEqual( + self.api.authenticationSessionState, + FBSDKAuthenticationSessionNone, + "The authentication session state should not change" + ); + XCTAssertEqualObjects( + urlOpener.capturedCanOpenUrl, + expectedCanOpenUrlCalledWithUrl, + "The url opener's can open url method should be called with the expected URL" + ); + XCTAssertEqualObjects( + urlOpener.capturedCanOpenSourceApplication, + expectedCanOpenUrlSource, + "The url opener's can open url method should be called with the expected source application" + ); + XCTAssertEqualObjects( + urlOpener.capturedCanOpenAnnotation, + expectedCanOpenUrlAnnotation, + "The url opener's can open url method should be called with the expected annotation" + ); + + XCTAssertEqualObjects( + FBSDKLoginManager.capturedOpenUrl, + expectedOpenUrlUrl, + "The url opener's open url method should be called with the expected URL" + ); + XCTAssertEqualObjects( + FBSDKLoginManager.capturedSourceApplication, + expectedOpenUrlSource, + "The url opener's open url method should be called with the expected source application" + ); + XCTAssertEqualObjects( + FBSDKLoginManager.capturedAnnotation, + expectedOpenUrlAnnotation, + "The url opener's open url method should be called with the expected annotation" + ); + + XCTAssertNotNil(self.api.pendingRequest, "The pending request should not be nil"); + XCTAssertNotNil(self.api.pendingRequestCompletionBlock, "The pending request completion block should not be nil"); + if (expectedPendingUrlOpenExists) { + XCTAssertNotNil(self.api.pendingUrlOpen, "The reference to the url opener should not be nil"); + } else { + XCTAssertNil(self.api.pendingUrlOpen, "The reference to the url opener should be nil"); + } + if (expectedSafariVcExists) { + XCTAssertNotNil(self.api.safariViewController, "Safari view controller should not be nil"); + } else { + XCTAssertNil(self.api.safariViewController, "Safari view controller should be nil"); + } + XCTAssertEqual( + self.api.isDismissingSafariViewController, + expectedIsDismissingSafariVc, + "Should set isDismissingSafariViewController to the expected value" + ); + + [mock stopMocking]; + mock = nil; +} + +/// Stubs `FBSDKBridgeAPI`'s `_handleBridgeAPIResponseURL:sourceApplication:` method to return the provided value +/// @returns (id) the partial mock for bridge api so that it can be canceled. +- (id)stubHandleBridgeApiResponseAndReturn:(BOOL)value +{ + id mock = OCMPartialMock(self.api); + OCMStub([mock _handleBridgeAPIResponseURL:OCMArg.any sourceApplication:OCMArg.any]).andReturn(value); + return mock; +} + +- (FBSDKBridgeAPIRequest *)sampleBridgeApiRequest +{ + return [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb + scheme:@"https" + methodName:nil + methodVersion:nil + parameters:nil + userInfo:nil]; +} + +- (NSError *)loginInterruptionError +{ + NSString *errorMessage = [[NSString alloc] + initWithFormat:@"Login attempt cancelled by alternate call to openURL from: %@", + self.sampleUrl]; + return [[NSError alloc] + initWithDomain:FBSDKErrorDomain + code:FBSDKErrorBridgeAPIInterruption + userInfo:@{FBSDKErrorLocalizedDescriptionKey : errorMessage}]; +} + +static inline NSString *StringFromBool(BOOL value) +{ + return value ? @"YES" : @"NO"; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h new file mode 100644 index 0000000000..22482b7520 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h @@ -0,0 +1,39 @@ +// 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 + +#import + +#import "FBSDKBridgeAPI+Testing.h" +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" +#import "FakeLoginManager.h" + +@interface FBSDKBridgeAPITests : FBSDKTestCase + +@property FBSDKBridgeAPI *api; +@property (readonly) NSURL *sampleUrl; + +extern NSString *const sampleSource; +extern NSString *const sampleAnnotation; + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m index 44d795e28e..f3c630c5b3 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -16,23 +16,7 @@ // 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 - -#import - -#import "FBSDKBridgeAPI+Testing.h" -#import "FBSDKCoreKitTests-Swift.h" -#import "FBSDKTestCase.h" -#import "FakeLoginManager.h" - -@interface FBSDKBridgeAPITests : FBSDKTestCase - -@property FBSDKBridgeAPI *api; - -@end +#import "FBSDKBridgeAPITests.h" @implementation FBSDKBridgeAPITests @@ -277,7 +261,7 @@ - (void)testDidFinishLaunchingWithoutLaunchedUrlWithSourceApplication - (void)testDidFinishLaunchingWithLaunchedUrlWithoutSourceApplication { - NSDictionary *options = @{ UIApplicationLaunchOptionsURLKey : [NSURL URLWithString:@"http://example.com"] }; + NSDictionary *options = @{ UIApplicationLaunchOptionsURLKey : self.sampleUrl }; XCTAssertFalse( [self.api application:UIApplication.sharedApplication didFinishLaunchingWithOptions:options], "Should not consider it a successful launch if there is no source application" @@ -286,13 +270,10 @@ - (void)testDidFinishLaunchingWithLaunchedUrlWithoutSourceApplication - (void)testDidFinishLaunchingWithLaunchedUrlWithSourceApplication { - NSURL *url = [NSURL URLWithString:@"http://example.com"]; - NSString *source = @"com.example"; - NSString *annotation = @"foo"; NSDictionary *options = @{ - UIApplicationLaunchOptionsURLKey : url, - UIApplicationLaunchOptionsSourceApplicationKey : source, - UIApplicationLaunchOptionsAnnotationKey : annotation + UIApplicationLaunchOptionsURLKey : self.sampleUrl, + UIApplicationLaunchOptionsSourceApplicationKey : sampleSource, + UIApplicationLaunchOptionsAnnotationKey : sampleAnnotation }; FBSDKLoginManager.stubbedOpenUrlSuccess = YES; @@ -302,9 +283,22 @@ - (void)testDidFinishLaunchingWithLaunchedUrlWithSourceApplication "Should return the success value determined by the login manager's open url method" ); - XCTAssertEqualObjects(FBSDKLoginManager.capturedOpenUrl, url, "Should pass the launch url to the login manager"); - XCTAssertEqualObjects(FBSDKLoginManager.capturedSourceApplication, source, "Should pass the source application to the login manager"); - XCTAssertEqualObjects(FBSDKLoginManager.capturedAnnotation, annotation, "Should pass the annotation to the login manager"); + XCTAssertEqualObjects(FBSDKLoginManager.capturedOpenUrl, self.sampleUrl, "Should pass the launch url to the login manager"); + XCTAssertEqualObjects(FBSDKLoginManager.capturedSourceApplication, sampleSource, "Should pass the source application to the login manager"); + XCTAssertEqualObjects(FBSDKLoginManager.capturedAnnotation, sampleAnnotation, "Should pass the annotation to the login manager"); } +- (NSURL *)sampleUrl +{ + return [NSURL URLWithString:@"http://example.com"]; +} + +static inline NSString *StringFromBool(BOOL value) +{ + return value ? @"YES" : @"NO"; +} + +NSString *const sampleSource = @"com.example"; +NSString *const sampleAnnotation = @"foo"; + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h index b36b60c432..0d0ca6fd96 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h @@ -54,7 +54,13 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (id)authenticationSession; - (FBSDKAuthenticationSession)authenticationSessionState; +- (FBSDKAuthenticationCompletionHandler)authenticationSessionCompletionHandler; - (BOOL)expectingBackground; +- (id)pendingUrlOpen; +- (UIViewController *)safariViewController; +- (BOOL)isDismissingSafariViewController; +- (FBSDKBridgeAPIRequest *)pendingRequest; +- (FBSDKBridgeAPIResponseBlock)pendingRequestCompletionBlock; - (void)applicationWillResignActive:(UIApplication *)application; - (void)applicationDidBecomeActive:(UIApplication *)application; @@ -62,11 +68,23 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(nullable NSString *)sourceApplication + annotation:(nullable id)annotation; + - (void)setAuthenticationSession:(id)session; - (void)setAuthenticationSessionState:(FBSDKAuthenticationSession)state; -- (void)setAuthenticationSessionCompletionHandler:(FBSDKAuthenticationCompletionHandler)handler; +- (void)setAuthenticationSessionCompletionHandler:(nullable FBSDKAuthenticationCompletionHandler)handler; - (void)setActive:(BOOL)isActive; - (void)setExpectingBackground:(BOOL)isExpectingBackground; +- (void)setPendingUrlOpen:(id)opening; +- (void)setSafariViewController:(nullable UIViewController *)controller; +- (void)setIsDismissingSafariViewController:(BOOL)isDismissing; +- (void)setPendingRequest:(FBSDKBridgeAPIRequest *)newValue; +- (void)setPendingRequestCompletionBlock:(FBSDKBridgeAPIResponseBlock)newValue; + +- (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h index d0e7d427b8..91ea2636ba 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h @@ -31,9 +31,16 @@ NS_ASSUME_NONNULL_BEGIN @property (class, nullable, copy) NSString *capturedSourceApplication; @property (class, nullable, copy) NSString *capturedAnnotation; @property (class) BOOL stubbedOpenUrlSuccess; +@property (nullable, copy) NSURL *capturedCanOpenUrl; +@property (nullable, copy) NSString *capturedCanOpenSourceApplication; +@property (nullable, copy) NSString *capturedCanOpenAnnotation; +@property BOOL stubbedCanOpenUrl; + (void)resetTestEvidence; +- (void)stubShouldStopPropagationOfURL:(NSURL *)url withValue:(BOOL)shouldStop; +- (BOOL)shouldStopPropagationOfURL:(NSURL *)url; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m index c81385f9a5..cece7e745c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m @@ -19,6 +19,9 @@ #import "FakeLoginManager.h" @implementation FBSDKLoginManager +{ + NSMutableDictionary *_urlPropagationMap; +} static NSURL *_capturedOpenUrl; static NSString *_capturedSourceApplication; @@ -49,6 +52,25 @@ + (void)resetTestEvidence FBSDKLoginManager.stubbedOpenUrlSuccess = NO; } +- (void)stubShouldStopPropagationOfURL:(NSURL *)url withValue:(BOOL)shouldStop +{ + if (!_urlPropagationMap) { + _urlPropagationMap = [NSMutableDictionary dictionary]; + } + [_urlPropagationMap setObject:@(shouldStop) forKey:url.absoluteString]; +} + +- (BOOL)shouldStopPropagationOfURL:(NSURL *)url +{ + if (!_urlPropagationMap) { + return NO; + } + + return [[_urlPropagationMap objectForKey:url.absoluteString] boolValue]; +} + +// MARK: - FBSDKURLOpening + - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { FBSDKLoginManager.capturedOpenUrl = url; @@ -62,7 +84,11 @@ - (void)applicationDidBecomeActive:(UIApplication *)application {} - (BOOL)canOpenURL:(NSURL *)url forApplication:(UIApplication *)application sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - return NO; + _capturedCanOpenUrl = url; + _capturedCanOpenSourceApplication = sourceApplication; + _capturedCanOpenAnnotation = annotation; + + return _stubbedCanOpenUrl; } - (BOOL)isAuthenticationURL:(NSURL *)url diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift new file mode 100644 index 0000000000..0230181e64 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift @@ -0,0 +1,42 @@ +// 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 UIKit + +@objcMembers +public class ViewControllerSpy: UIViewController { + + public var capturedDismissCompletion: (() -> Void)? + public var dismissWasCalled = false + private lazy var presenting = { + ViewControllerSpy.makeDefaultSpy() + }() + + public override var presentingViewController: UIViewController? { + return presenting + } + + public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + dismissWasCalled = true + capturedDismissCompletion = completion + } + + public static func makeDefaultSpy() -> ViewControllerSpy { + return ViewControllerSpy() + } +} From 3c50d5844a4751afc02d34f9366f52be7e8cec9d Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Mon, 16 Nov 2020 09:53:23 -0800 Subject: [PATCH 112/227] Convert FBSDKSKAdNetworkEventTests.m to Swift Summary: Converted FBSDKSKAdNetworkEventTests.m to Swift Reviewed By: joesus Differential Revision: D24971238 fbshipit-source-id: fb571ea28363c1dc37226881de98d21ff23e083e --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 12 +- .../FBSDKCoreKitTests-Bridging-Header.h | 1 + .../SKAdNetwork/FBSDKSKAdNetworkEventTests.m | 103 ------------------ .../FBSDKSKAdNetworkEventTests.swift | 85 +++++++++++++++ 4 files changed, 92 insertions(+), 109 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 7d83dcd6e6..927cb7ff27 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -838,8 +838,8 @@ F4210E35241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F4210E36241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; - F43960D02425513100C1868F /* FakeMonitorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.swift */; }; F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */; }; + F43960D02425513100C1868F /* FakeMonitorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.swift */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -994,7 +994,7 @@ F943112224FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */; }; F943113124FB25A3002441F1 /* FBSDKSKAdNetworkEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = F943111F24FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h */; }; F943113224FB25A7002441F1 /* FBSDKSKAdNetworkEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */; }; - F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m */; }; + F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift */; }; F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; }; F952EA482339403900B20652 /* FBSDKMetadataIndexer.h in Headers */ = {isa = PBXBuildFile; fileRef = F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */; }; F952EA492339405D00B20652 /* FBSDKMetadataIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */; }; @@ -1548,8 +1548,8 @@ F4210E1D241AFF740061F56D /* FBSDKMethodUsageMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorTests.m; sourceTree = ""; }; F4210E2C241B00790061F56D /* FBSDKMethodUsageMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMethodUsageMonitor.h; sourceTree = ""; }; F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitor.m; sourceTree = ""; }; - F43960CF2425513100C1868F /* FakeMonitorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeMonitorStore.swift; sourceTree = ""; }; F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKServerConfigurationManagerTests.swift; sourceTree = ""; }; + F43960CF2425513100C1868F /* FakeMonitorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeMonitorStore.swift; sourceTree = ""; }; F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; @@ -1619,7 +1619,7 @@ F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkRule.m; sourceTree = ""; }; F943111F24FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkEvent.h; sourceTree = ""; }; F943112024FB1A54002441F1 /* FBSDKSKAdNetworkEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkEvent.m; sourceTree = ""; }; - F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkEventTests.m; sourceTree = ""; }; + F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKSKAdNetworkEventTests.swift; sourceTree = ""; }; F952EA452339403900B20652 /* FBSDKMetadataIndexer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMetadataIndexer.m; sourceTree = ""; }; F952EA462339403900B20652 /* FBSDKMetadataIndexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMetadataIndexer.h; sourceTree = ""; }; F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMetadataIndexerTests.m; sourceTree = ""; }; @@ -2711,7 +2711,7 @@ F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */, F9CEF1EA24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m */, F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */, - F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m */, + F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift */, ); path = SKAdNetwork; sourceTree = ""; @@ -4175,7 +4175,7 @@ C51121CB20A27EF50041DC94 /* FBSDKEventBindingTests.m in Sources */, F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */, F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */, - F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.m in Sources */, + F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift in Sources */, F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */, F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */, F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 3d1997dc86..f49a02586c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -20,6 +20,7 @@ #import "FBSDKBridgeAPI+Testing.h" #import "FBSDKEventDeactivationManager.h" +#import "FBSDKSKAdNetworkEvent.h" #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m deleted file mode 100644 index 9614273898..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.m +++ /dev/null @@ -1,103 +0,0 @@ -// 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 - -#if !TARGET_OS_TV - - #import "FBSDKCoreKit+Internal.h" - #import "FBSDKSKAdNetworkEvent.h" - #import "FBSDKTestCase.h" - -@interface FBSDKSKAdNetworkEventTests : FBSDKTestCase - -@end - -@implementation FBSDKSKAdNetworkEventTests - -- (void)setUp -{ - [super setUp]; -} - -- (void)tearDown -{ - [super tearDown]; -} - -- (void)testInit -{ - // Valid cases - FBSDKSKAdNetworkEvent *event = [[FBSDKSKAdNetworkEvent alloc] initWithJSON:@{@"event_name" : @"fb_mobile_purchase"}]; - XCTAssertTrue([event.eventName isEqualToString:@"fb_mobile_purchase"]); - XCTAssertNil(event.values); - event = [[FBSDKSKAdNetworkEvent alloc] initWithJSON:@{ - @"event_name" : @"fb_mobile_purchase", - @"values" : @[ - @{ - @"currency" : @"usd", - @"amount" : @(100) - }, - @{ - @"currency" : @"JPY", - @"amount" : @(1000) - } - ] - }]; - XCTAssertTrue([event.eventName isEqualToString:@"fb_mobile_purchase"]); - NSDictionary *expectedValues = @{@"USD" : @(100), @"JPY" : @(1000)}; - XCTAssertTrue([event.values isEqualToDictionary:expectedValues]); - - // Invalid cases - id invalidData = nil; - XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); - invalidData = @[]; - XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); - invalidData = @{ - @"values" : @[ - @{ - @"currency" : @"usd", - @"amount" : @(100) - }, - @{ - @"currency" : @"JPY", - @"amount" : @(1000) - } - ] - }; - XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); - invalidData = @{ - @"event_name" : @"fb_mobile_purchase", - @"values" : @[ - @{ - @"currency" : @(100), - @"amount" : @"usd" - }, - @{ - @"currency" : @(1000), - @"amount" : @"jpy" - } - ] - }; - XCTAssertNil([[FBSDKSKAdNetworkEvent alloc] initWithJSON:invalidData]); -} - -@end - -#endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.swift new file mode 100644 index 0000000000..475e10a399 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkEventTests.swift @@ -0,0 +1,85 @@ +// 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. + +#if !os(tvOS) + +import XCTest + +class FBSDKSKAdNetworkEventTests: FBSDKTestCase { + + func testValidCases() { + var event = FBSDKSKAdNetworkEvent(json: ["event_name": "fb_mobile_purchase"]) + XCTAssertTrue(event?.eventName == "fb_mobile_purchase") + XCTAssertNil(event?.values) + event = FBSDKSKAdNetworkEvent( + json: [ + "event_name": "fb_mobile_purchase", + "values": [ + [ + "currency": "usd", + "amount": 100 + ], + [ + "currency": "JPY", + "amount": 1000 + ] + ] + ] + ) + XCTAssertTrue(event?.eventName == "fb_mobile_purchase") + let expectedValues: [String: NSNumber] = [ + "USD": 100, + "JPY": 1000 + ] + XCTAssertTrue(event?.values == expectedValues) + } + + func testInvalidCases() { + var invalidData: [String: Any] = [:] + XCTAssertNil(FBSDKSKAdNetworkEvent(json: invalidData)) + invalidData = [ + "values": [ + [ + "currency": "usd", + "amount": 100 + ], + [ + "currency": "JPY", + "amount": 1000 + ] + ] + ] + XCTAssertNil(FBSDKSKAdNetworkEvent(json: invalidData)) + invalidData = [ + "event_name": "fb_mobile_purchase", + "values": [ + [ + "currency": 100, + "amount": "usd" + ], + [ + "currency": 1000, + "amount": "jpy" + ] + ] + ] + XCTAssertNil(FBSDKSKAdNetworkEvent(json: invalidData)) + } +} + +#endif From af1fbad94782c1286a2fe08ebf729023b276fa93 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Mon, 16 Nov 2020 10:02:39 -0800 Subject: [PATCH 113/227] Convert FBSDKAppEventsConfigurationTests.m to Swift Summary: One minor modification is that the Objective-C version of the test was setting the config to nil in the tearDown method, however this wasn't strictly necessary as it was alrady being reset in the setUp method. Also setting it to nil prevented this variable from being non-nullable so removed the tearDown method. Reviewed By: joesus Differential Revision: D24943362 fbshipit-source-id: 4293d179d4e44d40e4363038a683ac6ea88f0467 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 +- .../FBSDKCoreKitTests-Bridging-Header.h | 1 + .../FBSDKAppEventsConfigurationTests.m | 95 ------------------- .../FBSDKAppEventsConfigurationTests.swift | 58 +++++++++++ 4 files changed, 63 insertions(+), 99 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 927cb7ff27..fcdce7ea0c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -1002,7 +1002,7 @@ F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F952EA4E2339432000B20652 /* FBSDKMetadataIndexerTests.m */; }; F96ADE7A21E6ABB400F6043F /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F96ADE6321E6ABB400F6043F /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */; }; - F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m */; }; + F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift */; }; F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */; }; F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */; }; F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; @@ -1626,7 +1626,7 @@ F96ADE6321E6ABB400F6043F /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; F98D1D3625124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfigurationFixtures.h; sourceTree = ""; }; F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationFixtures.m; sourceTree = ""; }; - F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationTests.m; sourceTree = ""; }; + F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKAppEventsConfigurationTests.swift; sourceTree = ""; }; F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawAppEventsConfigurationResponseFixtures.swift; sourceTree = ""; }; F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationManagerTests.m; sourceTree = ""; }; F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfiguration.h; sourceTree = ""; }; @@ -2214,7 +2214,7 @@ 5D68D7D722BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m */, F98D1D3625124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.h */, F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */, - F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m */, + F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift */, F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */, F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */, ); @@ -4104,7 +4104,7 @@ 9D18A8E91A95495D00A41042 /* FBSDKAppEventsUtilityTests.m in Sources */, 5CD6DB3C255B1D07002C296F /* FBSDKAppEventsUtilityTests.swift in Sources */, F4BD4024241EEDE500B45D39 /* FBSDKTestCoder.m in Sources */, - F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.m in Sources */, + F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift in Sources */, F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */, 7E55573C1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m in Sources */, 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index f49a02586c..56d7f86aa6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -18,6 +18,7 @@ #import +#import "FBSDKAppEventsConfigurationFixtures.h" #import "FBSDKBridgeAPI+Testing.h" #import "FBSDKEventDeactivationManager.h" #import "FBSDKSKAdNetworkEvent.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m deleted file mode 100644 index 3ae8c05f5f..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.m +++ /dev/null @@ -1,95 +0,0 @@ -// 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 "FBSDKAppEventsConfigurationFixtures.h" -#import "FBSDKCoreKit+Internal.h" - -@interface FBSDKAppEventsConfigurationTests : XCTestCase - -@end - -@implementation FBSDKAppEventsConfigurationTests -{ - FBSDKAppEventsConfiguration *config; -} - -typedef FBSDKAppEventsConfigurationFixtures Fixtures; - -- (void)setUp -{ - [super setUp]; - - config = [Fixtures defaultConfig]; -} - -- (void)tearDown -{ - [super tearDown]; - - config = nil; -} - -- (void)testCreatingWithDefaultATEStatus -{ - XCTAssertEqual(config.defaultATEStatus, FBSDKAdvertisingTrackingUnspecified, "Default ATE Status should be unspecified"); -} - -- (void)testCreatingWithKnownDefaultATEStatus -{ - config = [Fixtures configWithDictionary:@{@"default_ate_status" : @(FBSDKAdvertisingTrackingAllowed)}]; - XCTAssertEqual(config.defaultATEStatus, FBSDKAdvertisingTrackingAllowed, "Default ATE Status should be settable"); -} - -- (void)testCreatingWithDefaultAdvertisingIDCollectionEnabled -{ - XCTAssertTrue( - config.advertiserIDCollectionEnabled, - "Advertising identifier collection enabled should default to true" - ); -} - -- (void)testCreatingWithKnownAdvertisingIDCollectionEnabled -{ - config = [Fixtures configWithDictionary:@{@"advertiser_id_collection_enabled" : @(NO)}]; - XCTAssertFalse( - config.advertiserIDCollectionEnabled, - "Advertising identifier collection enabled should be settable" - ); -} - -- (void)testCreatingWithDefaultEventCollectionEnabled -{ - XCTAssertFalse( - config.eventCollectionEnabled, - "Event collection enabled should default to false" - ); -} - -- (void)testCreatingWithKnownEventCollectionEnabled -{ - config = [Fixtures configWithDictionary:@{@"event_collection_enabled" : @(YES)}]; - XCTAssertTrue( - config.eventCollectionEnabled, - "Event collection enabled should be settable" - ); -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.swift new file mode 100644 index 0000000000..8ea2908ba8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationTests.swift @@ -0,0 +1,58 @@ +// 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 XCTest + +class FBSDKAppEventsConfigurationTests: XCTestCase { + typealias Fixtures = FBSDKAppEventsConfigurationFixtures + + private var config = Fixtures.defaultConfig() + + override func setUp() { + super.setUp() + config = Fixtures.defaultConfig() + } + + func testCreatingWithDefaultATEStatus() { + XCTAssertEqual(config.defaultATEStatus, .unspecified, "Default ATE Status should be unspecified") + } + + func testCreatingWithKnownDefaultATEStatus() { + config = Fixtures.config(with: ["default_ate_status": AppEventsUtility.AdvertisingTrackingStatus.allowed.rawValue]) + XCTAssertEqual(config.defaultATEStatus, .allowed, "Default ATE Status should be settable") + } + + func testCreatingWithDefaultAdvertisingIDCollectionEnabled() { + XCTAssertTrue(config.advertiserIDCollectionEnabled, + "Advertising identifier collection enabled should default to true") + } + + func testCreatingWithKnownAdvertisingIDCollectionEnabled() { + config = Fixtures.config(with: ["advertiser_id_collection_enabled": false]) + XCTAssertFalse(config.advertiserIDCollectionEnabled, "Advertising identifier collection enabled should be settable") + } + + func testCreatingWithDefaultEventCollectionEnabled() { + XCTAssertFalse(config.eventCollectionEnabled, "Event collection enabled should default to false") + } + + func testCreatingWithKnownEventCollectionEnabled() { + config = Fixtures.config(with: ["event_collection_enabled": true]) + XCTAssertTrue(config.eventCollectionEnabled, "Event collection enabled should be settable") + } +} From 2e3fd74ff6987cbace7c6deef901fedace8a6e06 Mon Sep 17 00:00:00 2001 From: Michael Katz Date: Tue, 17 Nov 2020 07:06:22 -0800 Subject: [PATCH 114/227] Unit test hardening - FBSDKProfileTests Summary: Auditing - FBSDKProfileTests.m There did not seem to be any of the issues identified in the task: singletons, async tests I did add a little cleanup in the `tearDown`, but I am not sure it was strictly necessary. Reviewed By: joesus Differential Revision: D24954993 fbshipit-source-id: bbd9c71a14ca6060c4d546c89568975190e048c2 --- FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index 803de7a3f8..65780f7fbf 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -70,9 +70,10 @@ - (void)setUp - (void)tearDown { - [super tearDown]; - [self resetCaches]; + _profile = nil; + + [super tearDown]; } - (void)resetCaches From 154aad7b16fd9cfa9a1b512ac4520e7608ce507a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 17 Nov 2020 09:42:41 -0800 Subject: [PATCH 115/227] FBSDKBridgeAPI Unit Tests 4/n Summary: Tests the method: ``` - (void)openURL:(NSURL *)url sender:(nullable id)sender handler:(FBSDKSuccessBlock)handler; ``` Reviewed By: jawwad Differential Revision: D24998219 fbshipit-source-id: 55da969269dbbb0363fbc47ad8e0ba98bf4d2928 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +- .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 17 +-- ... FBSDKBridgeAPI+ApplicationOpenUrlTests.m} | 2 +- .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 112 ++++++++++++++++++ .../Internal/Helpers/FBSDKTestCase.h | 19 ++- .../Internal/Helpers/FBSDKTestCase.m | 30 +++++ 6 files changed, 169 insertions(+), 21 deletions(-) rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/{FBSDKBridgeAPI+OpenUrlTests.m => FBSDKBridgeAPI+ApplicationOpenUrlTests.m} (99%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index fcdce7ea0c..8d1035c709 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -804,7 +804,7 @@ F40F6568241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; F40F6569241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; F40F656A241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */; }; - F41200D0255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41200CF255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m */; }; + F41200D0255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41200CF255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m */; }; F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */; }; F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */; }; F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41979272475A20E003007CC /* FBSDKTypeUtilityTests.m */; }; @@ -1534,7 +1534,7 @@ F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntryTests.m; sourceTree = ""; }; F40F655F241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMethodUsageMonitorEntry.h; sourceTree = ""; }; F40F6560241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntry.m; sourceTree = ""; }; - F41200CF255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "FBSDKBridgeAPI+OpenUrlTests.m"; sourceTree = ""; }; + F41200CF255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "FBSDKBridgeAPI+ApplicationOpenUrlTests.m"; sourceTree = ""; }; F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKBridgeAPITests.h; sourceTree = ""; }; F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FBSDKSafeCastTests.m; path = Internal/Basics/FBSDKSafeCastTests.m; sourceTree = ""; }; F4181B332416EC06006DB452 /* FBSDKMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorTests.m; sourceTree = ""; }; @@ -2104,7 +2104,7 @@ children = ( 894C0B351A702DDD009137EF /* ProtocolVersions */, F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */, - F41200CF255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m */, + F41200CF255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m */, F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */, ); path = BridgeAPI; @@ -2672,9 +2672,9 @@ F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */, F496E60E24E5D195006231A2 /* SampleAccessToken.swift */, F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */, + F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.swift */, F4E50152243648A100C99262 /* FBSDKServerConfigurationFixtures.h */, - F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, F4EB31D22540A35800736B67 /* SampleGraphRequest.swift */, F4EB31BA2540A1B800736B67 /* SampleGraphRequestConnection.swift */, F4EB33CD2542323500736B67 /* SampleRawRemotePermissions.swift */, @@ -4157,7 +4157,7 @@ 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */, F4EB317F2540955500736B67 /* FBSDKGraphRequestPiggybackManagerTests.m in Sources */, F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, - F41200D0255F45FE009E323F /* FBSDKBridgeAPI+OpenUrlTests.m in Sources */, + F41200D0255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, F402B062255C645600473083 /* FakeLoginManager.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index b2a8df73a5..d012ab194b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -270,20 +270,9 @@ - (void)openURL:(NSURL *)url sender:(id)sender handler:(FBSDKSu handler(success, nil); }]; } - } else { - BOOL opened = [[UIApplication sharedApplication] openURL:url]; - - if ([url.scheme hasPrefix:@"http"] && !opened) { - NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; - if (![NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:iOS8Version]) { - // Safari openURL calls can wrongly return NO on iOS 7 so manually overwrite that case to YES. - // Otherwise we would rather trust in the actual result of openURL - opened = YES; - } - } - if (handler) { - handler(opened, nil); - } + } else if (handler) { + BOOL opened = [UIApplication.sharedApplication openURL:url]; + handler(opened, nil); } }); } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m similarity index 99% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m index ea00594e7a..d416b74b61 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+OpenUrlTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m @@ -18,7 +18,7 @@ #import "FBSDKBridgeAPITests.h" -@implementation FBSDKBridgeAPITests (OpenURLTests) +@implementation FBSDKBridgeAPITests (ApplicationOpenURLTests) // MARK: - Url Opening diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m index f3c630c5b3..05e350778d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -288,6 +288,117 @@ - (void)testDidFinishLaunchingWithLaunchedUrlWithSourceApplication XCTAssertEqualObjects(FBSDKLoginManager.capturedAnnotation, sampleAnnotation, "Should pass the annotation to the login manager"); } +// MARK: - Open Url + +- (void)testOpenUrlWithMissingSender +{ + [self.api openURL:self.sampleUrl + sender:nil + handler:^(BOOL _success, NSError *_Nullable error) {}]; + + XCTAssertTrue(self.api.expectingBackground, "Should set expecting background to true when opening a URL"); + XCTAssertNil(self.api.pendingUrlOpen, "Should not set the pending url opener if there is no sender"); +} + +- (void)testOpenUrlWithSender +{ + FBSDKLoginManager *urlOpener = [FBSDKLoginManager new]; + [self.api openURL:self.sampleUrl + sender:urlOpener + handler:^(BOOL _success, NSError *_Nullable error) {}]; + + XCTAssertTrue(self.api.expectingBackground, "Should set expecting background to true when opening a URL"); + XCTAssertEqual(self.api.pendingUrlOpen, urlOpener, "Should set the pending url opener to the sender"); +} + +- (void)testOpenUrlWithVersionBelow10WhenApplicationOpens +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + + BOOL applicationOpensSuccessfully = YES; + [self stubIsOperatingSystemVersionAtLeast:iOS10Version with:NO]; + [self stubOpenURLWith:applicationOpensSuccessfully]; + + [self.api openURL:self.sampleUrl sender:nil handler:^(BOOL _success, NSError *_Nullable error) { + XCTAssertEqual( + _success, + applicationOpensSuccessfully, + "Should call the completion handler with the expected value" + ); + XCTAssertNil(error, "Should not call the completion handler with an error"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +- (void)testOpenUrlWithVersionBelow10WhenApplicationDoesNotOpen +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + + BOOL applicationOpensSuccessfully = NO; + [self stubIsOperatingSystemVersionAtLeast:iOS10Version with:NO]; + [self stubOpenURLWith:applicationOpensSuccessfully]; + + [self.api openURL:self.sampleUrl sender:nil handler:^(BOOL _success, NSError *_Nullable error) { + XCTAssertEqual( + _success, + applicationOpensSuccessfully, + "Should call the completion handler with the expected value" + ); + XCTAssertNil(error, "Should not call the completion handler with an error"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +- (void)testOpenUrlWhenApplicationOpens +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + + BOOL applicationOpensSuccessfully = YES; + [self stubIsOperatingSystemVersionAtLeast:iOS10Version with:YES]; + [self stubOpenUrlOptionsCompletionHandlerWithPerformCompletion:YES + completionSuccess:applicationOpensSuccessfully]; + + [self.api openURL:self.sampleUrl sender:nil handler:^(BOOL _success, NSError *_Nullable error) { + XCTAssertEqual( + _success, + applicationOpensSuccessfully, + "Should call the completion handler with the expected value" + ); + XCTAssertNil(error, "Should not call the completion handler with an error"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +- (void)testOpenUrlWhenApplicationDoesNotOpen +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + + BOOL applicationOpensSuccessfully = NO; + [self stubIsOperatingSystemVersionAtLeast:iOS10Version with:YES]; + [self stubOpenUrlOptionsCompletionHandlerWithPerformCompletion:YES + completionSuccess:applicationOpensSuccessfully]; + + [self.api openURL:self.sampleUrl sender:nil handler:^(BOOL _success, NSError *_Nullable error) { + XCTAssertEqual( + _success, + applicationOpensSuccessfully, + "Should call the completion handler with the expected value" + ); + XCTAssertNil(error, "Should not call the completion handler with an error"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +// MARK: - Helpers + - (NSURL *)sampleUrl { return [NSURL URLWithString:@"http://example.com"]; @@ -300,5 +411,6 @@ - (NSURL *)sampleUrl NSString *const sampleSource = @"com.example"; NSString *const sampleAnnotation = @"foo"; +NSOperatingSystemVersion const iOS10Version = { .majorVersion = 10, .minorVersion = 0, .patchVersion = 0 }; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 029db81aba..3e85e3c133 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -137,6 +137,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKLogger` class mock between tests @property (nullable, nonatomic, assign) id loggerClassMock; +/// Used for sharing an `NSProcessInfo.processInfo` mock between tests +@property (nullable, nonatomic, assign) id processInfoMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; @@ -258,9 +261,20 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKSettings.facebookDomainPart` with the provided value - (void)stubFacebookDomainPartWith:(NSString *)domainPart; -/// Stubs `UIApplication.sharedApplication`'s `canOpenURL:` method with the value +/// Stubs `UIApplication.sharedApplication`'s `canOpenURL:` method and returns the provided value - (void)stubCanOpenURLWith:(BOOL)canOpenURL; +/// Stubs `UIApplication.sharedApplication`'s `openURL:` method and returns the provided value +- (void)stubOpenURLWith:(BOOL)openURL; + +/// Stubs `UIApplication.sharedApplication`'s `openURL:options:completionHandler:` method +/// +/// - Parameters: +/// - performCompletion: Whether to invoke the completion handler +/// - completionSuccess: The value to pass for the success parameter of the completion handler +- (void)stubOpenUrlOptionsCompletionHandlerWithPerformCompletion:(BOOL)performCompletion + completionSuccess:(BOOL)completionSuccess; + /// Stubs `FBSDKSettings.appURLSchemeSuffix` and return the provided value - (void)stubAppUrlSchemeSuffixWith:(nullable NSString *)suffix; @@ -270,6 +284,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKSettings.userAgentSuffix` and returns the provided value - (void)stubUserAgentSuffixWith:(nullable NSString *)suffix; +/// Stubs `NSProcessInfo`'s `isOperatingSystemVersionAtLeast:` and returns the provided value +- (void)stubIsOperatingSystemVersionAtLeast:(NSOperatingSystemVersion)version with:(BOOL)returnValue; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index f39d4d063b..202d3780df 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -104,6 +104,7 @@ - (void)setUp [self setUpNSDateClassMock]; [self setUpSharedApplicationMock]; [self setUpLoggerClassMock]; + [self setUpProcessInfoMock]; } - (void)tearDown @@ -190,6 +191,9 @@ - (void)tearDown [_loggerClassMock stopMocking]; _loggerClassMock = nil; + + [_processInfoMock stopMocking]; + _processInfoMock = nil; } - (void)setUpSettingsMock @@ -329,6 +333,12 @@ - (void)setUpLoggerClassMock self.loggerClassMock = OCMClassMock(FBSDKLogger.class); } +- (void)setUpProcessInfoMock +{ + self.processInfoMock = OCMClassMock(NSProcessInfo.class); + OCMStub(ClassMethod([_processInfoMock processInfo])).andReturn(_processInfoMock); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID @@ -537,6 +547,21 @@ - (void)stubCanOpenURLWith:(BOOL)canOpenURL OCMStub([_sharedApplicationMock canOpenURL:OCMArg.any]).andReturn(canOpenURL); } +- (void)stubOpenURLWith:(BOOL)openURL +{ + OCMStub([_sharedApplicationMock openURL:OCMArg.any]).andReturn(openURL); +} + +- (void)stubOpenUrlOptionsCompletionHandlerWithPerformCompletion:(BOOL)performCompletion + completionSuccess:(BOOL)completionSuccess +{ + if (performCompletion) { + OCMStub([_sharedApplicationMock openURL:OCMArg.any options:OCMArg.any completionHandler:([OCMArg invokeBlockWithArgs:@(completionSuccess), nil])]); + } else { + OCMStub([_sharedApplicationMock openURL:OCMArg.any options:OCMArg.any completionHandler:OCMArg.any]); + } +} + - (void)stubAppUrlSchemeSuffixWith:(NSString *)suffix { OCMStub(ClassMethod([_settingsClassMock appURLSchemeSuffix])).andReturn(suffix); @@ -547,6 +572,11 @@ - (void)stubUserAgentSuffixWith:(nullable NSString *)suffix OCMStub(ClassMethod([self.settingsClassMock userAgentSuffix])).andReturn(suffix); } +- (void)stubIsOperatingSystemVersionAtLeast:(NSOperatingSystemVersion)version with:(BOOL)returnValue +{ + OCMStub([self.processInfoMock isOperatingSystemAtLeastVersion:version]).andReturn(returnValue); +} + // MARK: - Helpers - (void)resetCachedSettings From a2e81e417c53c3302a6cea910af4452408e031e0 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 17 Nov 2020 09:42:41 -0800 Subject: [PATCH 116/227] FBSDKBridgeAPI Unit Tests 5/n Summary: Adding tests for the method: ``` openBridgeAPIRequest:useSafariViewController:fromViewController:completionBlock: ``` Introduces a new protocol `FBSDKBridgeAPIRequestProtocol` to substitute for an actual `FBSDKBridgeAPIRequest`. This is mostly to make it easier to test and help with the upcoming conversion to Swift. Refactors usages of `FBSDKBridgeAPIRequest` to use the new protocol. Reviewed By: jawwad Differential Revision: D25007249 fbshipit-source-id: 3295390b20888ec5214a974c9350bc9008e9eb0f --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 16 +- .../Internal/BridgeAPI/FBSDKBridgeAPI.h | 4 +- .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 30 +- .../BridgeAPI/FBSDKBridgeAPIRequest+Private.h | 2 +- .../BridgeAPI/FBSDKBridgeAPIRequest.h | 15 +- .../BridgeAPI/FBSDKBridgeAPIResponse.h | 8 +- .../BridgeAPI/FBSDKBridgeAPIResponse.m | 10 +- .../FBSDKBridgeAPI+Testing.h | 4 +- .../FBSDKBridgeAPIOpenBridgeRequestTests.m | 293 ++++++++++++++++++ .../FBSDKBridgeAPIRequestTests.swift | 29 ++ .../Helpers/FakeBridgeApiRequest.swift | 52 ++++ .../Internal/Helpers/ViewControllerSpy.swift | 19 ++ 12 files changed, 455 insertions(+), 27 deletions(-) rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/{Helpers => BridgeAPI}/FBSDKBridgeAPI+Testing.h (92%) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 8d1035c709..7b210d2b1b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -793,6 +793,9 @@ F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F402AFF2255B4EE400473083 /* AuthenticationSessionSpy.swift */; }; F402B062255C645600473083 /* FakeLoginManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F402B061255C645600473083 /* FakeLoginManager.m */; }; F402B071255C740C00473083 /* ViewControllerSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F402B070255C740C00473083 /* ViewControllerSpy.swift */; }; + F408C6C02563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F408C6BF2563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m */; }; + F408C6E9256309A500372D61 /* FakeBridgeApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F408C6E8256309A500372D61 /* FakeBridgeApiRequest.swift */; }; + F408C712256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F408C711256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift */; }; F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */; }; F40B24C224732DD90059351C /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40B24C124732DD90059351C /* Fuzzer.swift */; }; F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */; }; @@ -1529,6 +1532,9 @@ F402B060255C645600473083 /* FakeLoginManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FakeLoginManager.h; sourceTree = ""; }; F402B061255C645600473083 /* FakeLoginManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FakeLoginManager.m; sourceTree = ""; }; F402B070255C740C00473083 /* ViewControllerSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerSpy.swift; sourceTree = ""; }; + F408C6BF2563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKBridgeAPIOpenBridgeRequestTests.m; sourceTree = ""; }; + F408C6E8256309A500372D61 /* FakeBridgeApiRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeBridgeApiRequest.swift; sourceTree = ""; }; + F408C711256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKBridgeAPIRequestTests.swift; sourceTree = ""; }; F40B24B1247324BB0059351C /* RawServerConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawServerConfigurationResponseFixtures.swift; sourceTree = ""; }; F40B24C124732DD90059351C /* Fuzzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; F40F6550241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitorEntryTests.m; sourceTree = ""; }; @@ -2103,9 +2109,12 @@ isa = PBXGroup; children = ( 894C0B351A702DDD009137EF /* ProtocolVersions */, + F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */, F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */, F41200CF255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m */, - F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */, + F408C6BF2563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m */, + F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */, + F408C711256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift */, ); path = BridgeAPI; sourceTree = ""; @@ -2656,7 +2665,6 @@ F4CD7CDA243E2CF7004C27F1 /* Helpers */ = { isa = PBXGroup; children = ( - F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */, F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */, F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */, F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */, @@ -2683,6 +2691,7 @@ F402B070255C740C00473083 /* ViewControllerSpy.swift */, F402B060255C645600473083 /* FakeLoginManager.h */, F402B061255C645600473083 /* FakeLoginManager.m */, + F408C6E8256309A500372D61 /* FakeBridgeApiRequest.swift */, ); path = Helpers; sourceTree = ""; @@ -4143,9 +4152,11 @@ F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */, + F408C712256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift in Sources */, 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */, F40B24C224732DD90059351C /* Fuzzer.swift in Sources */, 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */, + F408C6E9256309A500372D61 /* FakeBridgeApiRequest.swift in Sources */, F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */, 5C49DF9E2554C9ED00E0FD91 /* SampleUserProfile.swift in Sources */, F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */, @@ -4178,6 +4189,7 @@ F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift in Sources */, F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */, F402AFF3255B4EE400473083 /* AuthenticationSessionSpy.swift in Sources */, + F408C6C02563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m in Sources */, F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */, F40F6551241A974400B10EAA /* FBSDKMethodUsageMonitorEntryTests.m in Sources */, ); diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h index 6a461dcd08..20c274dcef 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h @@ -41,14 +41,14 @@ NS_SWIFT_NAME(BridgeAPIResponseBlock); @interface FBSDKBridgeAPI : NSObject -- (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request +- (void)openBridgeAPIRequest:(NSObject *)request useSafariViewController:(BOOL)useSafariViewController fromViewController:(nullable UIViewController *)fromViewController completionBlock:(FBSDKBridgeAPIResponseBlock)completionBlock; - (void)openURLWithSafariViewController:(NSURL *)url sender:(nullable id)sender - fromViewController:(UIViewController *)fromViewController + fromViewController:(nullable UIViewController *)fromViewController handler:(FBSDKSuccessBlock)handler; - (void)openURL:(NSURL *)url diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index d012ab194b..98b10bac66 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -41,6 +41,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { }; typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); +typedef void (^FBSDKBridgeAPIRequestCompletionBlock)(BOOL, NSError *); @protocol FBSDKAuthenticationSession @@ -63,7 +64,7 @@ @interface FBSDKBridgeAPI () *_pendingRequest; FBSDKBridgeAPIResponseBlock _pendingRequestCompletionBlock; id _pendingURLOpen; id _authenticationSession NS_AVAILABLE_IOS(11_0); @@ -279,7 +280,7 @@ - (void)openURL:(NSURL *)url sender:(id)sender handler:(FBSDKSu #pragma clang diagnostic pop -- (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request +- (void)openBridgeAPIRequest:(NSObject *)request useSafariViewController:(BOOL)useSafariViewController fromViewController:(UIViewController *)fromViewController completionBlock:(FBSDKBridgeAPIResponseBlock)completionBlock @@ -296,7 +297,19 @@ - (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request } _pendingRequest = request; _pendingRequestCompletionBlock = [completionBlock copy]; - void (^handler)(BOOL, NSError *) = ^(BOOL openedURL, NSError *anError) { + FBSDKBridgeAPIRequestCompletionBlock handler = [self _bridgeAPIRequestCompletionBlockWithRequest:request + completion:completionBlock]; + if (useSafariViewController) { + [self openURLWithSafariViewController:requestURL sender:nil fromViewController:fromViewController handler:handler]; + } else { + [self openURL:requestURL sender:nil handler:handler]; + } +} + +- (FBSDKBridgeAPIRequestCompletionBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request + completion:(FBSDKBridgeAPIResponseBlock)completionBlock +{ + return ^(BOOL openedURL, NSError *anError) { if (!openedURL) { self->_pendingRequest = nil; self->_pendingRequestCompletionBlock = nil; @@ -314,11 +327,6 @@ - (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request return; } }; - if (useSafariViewController) { - [self openURLWithSafariViewController:requestURL sender:nil fromViewController:fromViewController handler:handler]; - } else { - [self openURL:requestURL sender:nil handler:handler]; - } } - (void)openURLWithSafariViewController:(NSURL *)url @@ -469,7 +477,7 @@ - (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewControlle - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication { - FBSDKBridgeAPIRequest *request = _pendingRequest; + NSObject *request = _pendingRequest; FBSDKBridgeAPIResponseBlock completionBlock = _pendingRequestCompletionBlock; _pendingRequest = nil; _pendingRequestCompletionBlock = NULL; @@ -602,12 +610,12 @@ - (void)setIsDismissingSafariViewController:(BOOL)isDismissing _isDismissingSafariViewController = isDismissing; } -- (FBSDKBridgeAPIRequest *)pendingRequest +- (NSObject *)pendingRequest { return _pendingRequest; } -- (void)setPendingRequest:(FBSDKBridgeAPIRequest *)newValue +- (void)setPendingRequest:(NSObject *)newValue { _pendingRequest = newValue; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h index 8f39a7a672..77bb0f5c53 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h @@ -34,7 +34,7 @@ userInfo:(NSDictionary *)userInfo NS_DESIGNATED_INITIALIZER; -@property (nonatomic, readonly, strong) id protocol; +@property (nonatomic, readwrite, strong) id protocol; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.h index bbc25d6455..dbf842ffaa 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.h @@ -28,10 +28,23 @@ #import #endif +#import "FBSDKBridgeAPIProtocol.h" #import "FBSDKBridgeAPIProtocolType.h" +@protocol FBSDKBridgeAPIRequestProtocol + +@property (nonatomic, copy, readonly) NSString *scheme; +@property (nonatomic, copy, readonly) NSString *actionID; +@property (nonatomic, copy, readonly) NSString *methodName; +@property (nonatomic, assign, readonly) FBSDKBridgeAPIProtocolType protocolType; +@property (nonatomic, readonly, strong) id protocol; + +- (NSURL *)requestURL:(NSError *__autoreleasing *)errorRef; + +@end + NS_SWIFT_NAME(BridgeAPIRequest) -@interface FBSDKBridgeAPIRequest : NSObject +@interface FBSDKBridgeAPIRequest : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.h index 8cbe0cd409..a17bd03e7b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.h @@ -36,16 +36,16 @@ NS_SWIFT_NAME(BridgeAPIResponse) - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; -+ (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request error:(NSError *)error; -+ (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request ++ (instancetype)bridgeAPIResponseWithRequest:(NSObject *)request error:(NSError *)error; ++ (instancetype)bridgeAPIResponseWithRequest:(NSObject *)request responseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication error:(NSError *__autoreleasing *)errorRef; -+ (instancetype)bridgeAPIResponseCancelledWithRequest:(FBSDKBridgeAPIRequest *)request; ++ (instancetype)bridgeAPIResponseCancelledWithRequest:(NSObject *)request; @property (nonatomic, assign, readonly, getter=isCancelled) BOOL cancelled; @property (nonatomic, copy, readonly) NSError *error; -@property (nonatomic, copy, readonly) FBSDKBridgeAPIRequest *request; +@property (nonatomic, copy, readonly) NSObject *request; @property (nonatomic, copy, readonly) NSDictionary *responseParameters; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m index 5c5ea7ad1a..7416dc87f5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m @@ -28,7 +28,7 @@ #import "FBSDKInternalUtility.h" @interface FBSDKBridgeAPIResponse () -- (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request +- (instancetype)initWithRequest:(id)request responseParameters:(NSDictionary *)responseParameters cancelled:(BOOL)cancelled error:(NSError *)error @@ -39,7 +39,7 @@ @implementation FBSDKBridgeAPIResponse #pragma mark - Class Methods -+ (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request error:(NSError *)error ++ (instancetype)bridgeAPIResponseWithRequest:(id)request error:(NSError *)error { return [[self alloc] initWithRequest:request responseParameters:nil @@ -47,7 +47,7 @@ + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request er error:error]; } -+ (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request ++ (instancetype)bridgeAPIResponseWithRequest:(NSObject *)request responseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication error:(NSError *__autoreleasing *)errorRef @@ -95,7 +95,7 @@ + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request error:error]; } -+ (instancetype)bridgeAPIResponseCancelledWithRequest:(FBSDKBridgeAPIRequest *)request ++ (instancetype)bridgeAPIResponseCancelledWithRequest:(NSObject *)request { return [[self alloc] initWithRequest:request responseParameters:nil @@ -105,7 +105,7 @@ + (instancetype)bridgeAPIResponseCancelledWithRequest:(FBSDKBridgeAPIRequest *)r #pragma mark - Object Lifecycle -- (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request +- (instancetype)initWithRequest:(NSObject *)request responseParameters:(NSDictionary *)responseParameters cancelled:(BOOL)cancelled error:(NSError *)error diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h similarity index 92% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h index 0d0ca6fd96..47a1206bb4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKBridgeAPI+Testing.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); +typedef void (^FBSDKBridgeAPIRequestCompletionBlock)(BOOL, NSError *); NS_SWIFT_NAME(AuthenticationSessionHandling) @protocol FBSDKAuthenticationSession @@ -85,7 +86,8 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (void)setPendingRequestCompletionBlock:(FBSDKBridgeAPIResponseBlock)newValue; - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication; - +- (FBSDKBridgeAPIRequestCompletionBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request + completion:(FBSDKBridgeAPIResponseBlock)completionBlock; @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m new file mode 100644 index 0000000000..99a4b19b97 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m @@ -0,0 +1,293 @@ +// 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 + +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" + +@interface FBSDKBridgeAPIOpenBridgeRequestTests : FBSDKTestCase + +@property FBSDKBridgeAPI *api; +@property id partialMock; +@property (readonly) NSURL *sampleUrl; + +@end + +@implementation FBSDKBridgeAPIOpenBridgeRequestTests + +- (void)setUp +{ + [super setUp]; + + _api = [FBSDKBridgeAPI new]; + _partialMock = OCMPartialMock(self.api); + + OCMStub( + [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:OCMArg.any + completion:OCMArg.any] + ); + OCMStub( + [_partialMock openURLWithSafariViewController:OCMArg.any + sender:OCMArg.any + fromViewController:OCMArg.any + handler:OCMArg.any] + ); + OCMStub([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); +} + +- (void)tearDown +{ + _api = nil; + + [_partialMock stopMocking]; + _partialMock = nil; + + [super tearDown]; +} + +// MARK: - Url Opening + +- (void)testOpeningBridgeRequestWithRequestUrlUsingSafariVcWithFromVc +{ + ViewControllerSpy *spy = [ViewControllerSpy makeDefaultSpy]; + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + [self.api openBridgeAPIRequest:request + useSafariViewController:YES + fromViewController:spy + completionBlock:self.uninvokedCompletionHandler]; + + XCTAssertEqualObjects(self.api.pendingRequest, request); + XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); + OCMVerify( + [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request + completion:self.uninvokedCompletionHandler] + ); + OCMVerify( + [_partialMock openURLWithSafariViewController:self.sampleUrl + sender:nil + fromViewController:spy + handler:OCMArg.any] + ); +} + +- (void)testOpeningBridgeRequestWithRequestUrlUsingSafariVcWithoutFromVc +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + [self.api openBridgeAPIRequest:request + useSafariViewController:YES + fromViewController:nil + completionBlock:self.uninvokedCompletionHandler]; + + XCTAssertEqualObjects(self.api.pendingRequest, request); + XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); + OCMVerify( + [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request + completion:self.uninvokedCompletionHandler] + ); + OCMVerify( + [_partialMock openURLWithSafariViewController:self.sampleUrl + sender:nil + fromViewController:nil + handler:OCMArg.any] + ); +} + +- (void)testOpeningBridgeRequestWithRequestUrlNotUsingSafariVcWithFromVc +{ + ViewControllerSpy *spy = [ViewControllerSpy makeDefaultSpy]; + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + [self.api openBridgeAPIRequest:request + useSafariViewController:NO + fromViewController:spy + completionBlock:self.uninvokedCompletionHandler]; + + XCTAssertEqualObjects(self.api.pendingRequest, request); + XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); + OCMVerify( + [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request + completion:self.uninvokedCompletionHandler] + ); + OCMVerify([_partialMock openURL:self.sampleUrl sender:nil handler:OCMArg.any]); +} + +- (void)testOpeningBridgeRequestWithRequestUrlNotUsingSafariVcWithoutFromVc +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + [self.api openBridgeAPIRequest:request + useSafariViewController:NO + fromViewController:nil + completionBlock:self.uninvokedCompletionHandler]; + + XCTAssertEqualObjects(self.api.pendingRequest, request); + XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); + OCMVerify( + [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request + completion:self.uninvokedCompletionHandler] + ); + OCMVerify([_partialMock openURL:self.sampleUrl sender:nil handler:OCMArg.any]); +} + +- (void)testOpeningBridgeRequestWithoutRequestUrlUsingSafariVcWithFromVc +{ + ViewControllerSpy *spy = [ViewControllerSpy makeDefaultSpy]; + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:nil]; + FBSDKBridgeAPIResponseBlock completionHandler = ^(FBSDKBridgeAPIResponse *_Nonnull response) { + XCTAssertEqualObjects( + response.request, + request, + "Should call the completion with a response that includes the original request" + ); + XCTAssertTrue( + [response.error isKindOfClass:FakeBridgeApiRequestError.class], + "Should call the completion with an error if the request cannot provide a url" + ); + }; + [self rejectApiOpeningBridgeRequest]; + [self.api openBridgeAPIRequest:request + useSafariViewController:YES + fromViewController:spy + completionBlock:completionHandler]; + [self assertPendingPropertiesNotSet]; +} + +- (void)testOpeningBridgeRequestWithoutRequestUrlUsingSafariVcWithoutFromVc +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:nil]; + FBSDKBridgeAPIResponseBlock completionHandler = ^(FBSDKBridgeAPIResponse *_Nonnull response) { + XCTAssertEqualObjects( + response.request, + request, + "Should call the completion with a response that includes the original request" + ); + XCTAssertTrue( + [response.error isKindOfClass:FakeBridgeApiRequestError.class], + "Should call the completion with an error if the request cannot provide a url" + ); + }; + [self rejectApiOpeningBridgeRequest]; + [self.api openBridgeAPIRequest:request + useSafariViewController:YES + fromViewController:nil + completionBlock:completionHandler]; + [self assertPendingPropertiesNotSet]; +} + +- (void)testOpeningBridgeRequestWithoutRequestUrlNotUsingSafariVcWithFromVc +{ + ViewControllerSpy *spy = [ViewControllerSpy makeDefaultSpy]; + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:nil]; + FBSDKBridgeAPIResponseBlock completionHandler = ^(FBSDKBridgeAPIResponse *_Nonnull response) { + XCTAssertEqualObjects( + response.request, + request, + "Should call the completion with a response that includes the original request" + ); + XCTAssertTrue( + [response.error isKindOfClass:FakeBridgeApiRequestError.class], + "Should call the completion with an error if the request cannot provide a url" + ); + }; + [self rejectApiOpeningBridgeRequest]; + [self.api openBridgeAPIRequest:request + useSafariViewController:NO + fromViewController:spy + completionBlock:completionHandler]; + [self assertPendingPropertiesNotSet]; +} + +- (void)testOpeningBridgeRequestWithoutRequestUrlNotUsingSafariVcWithoutFromVc +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:nil]; + FBSDKBridgeAPIResponseBlock completionHandler = ^(FBSDKBridgeAPIResponse *_Nonnull response) { + XCTAssertEqualObjects( + response.request, + request, + "Should call the completion with a response that includes the original request" + ); + XCTAssertTrue( + [response.error isKindOfClass:FakeBridgeApiRequestError.class], + "Should call the completion with an error if the request cannot provide a url" + ); + }; + [self rejectApiOpeningBridgeRequest]; + [self.api openBridgeAPIRequest:request + useSafariViewController:NO + fromViewController:nil + completionBlock:completionHandler]; + [self assertPendingPropertiesNotSet]; +} + +- (void)testOpeningBridgeRequestWithInsecureRequestUrl +{ + NSURL *expectedUrl = [NSURL URLWithString:@"file:///foo"]; + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:expectedUrl]; + [self.api openBridgeAPIRequest:request + useSafariViewController:NO + fromViewController:nil + completionBlock:self.uninvokedCompletionHandler]; + + XCTAssertEqualObjects(self.api.pendingRequest, request); + XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); + OCMVerify([_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request completion:self.uninvokedCompletionHandler]); + OCMVerify([_partialMock openURL:expectedUrl sender:nil handler:OCMArg.any]); +} + +// MARK: - Helpers + +- (void)rejectApiOpeningBridgeRequest +{ + OCMReject([_partialMock _bridgeAPIRequestCompletionBlockWithRequest:OCMArg.any completion:OCMArg.any]); + OCMReject([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); + OCMReject( + [_partialMock openURLWithSafariViewController:OCMArg.any + sender:OCMArg.any + fromViewController:OCMArg.any + handler:OCMArg.any] + ); +} + +- (void)assertPendingPropertiesNotSet +{ + XCTAssertNil( + self.api.pendingRequest, + "Should not set a pending request if the bridge request does not have a request url" + ); + XCTAssertNil( + self.api.pendingRequestCompletionBlock, + "Should not set a pending request completion block if the bridge request does not have a request url" + ); +} + +- (FBSDKBridgeAPIResponseBlock)uninvokedCompletionHandler +{ + return ^(FBSDKBridgeAPIResponse *_Nonnull response) { + XCTFail("Should not invoke the completion handler"); + }; +} + +- (NSURL *)sampleUrl +{ + return [NSURL URLWithString:@"http://example.com"]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift new file mode 100644 index 0000000000..a674cf5a37 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift @@ -0,0 +1,29 @@ +// 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 XCTest + +class FBSDKBridgeAPIRequestTests: FBSDKTestCase { + + func testDefaultProtocolConformance() { + let request: Any = BridgeAPIRequest(protocolType: .web, scheme: "https", methodName: nil, methodVersion: nil, parameters: [:], userInfo: [:]) as Any + let conformedRequest = request as? FBSDKBridgeAPIRequestProtocol + + XCTAssertNotNil(conformedRequest, "BridgeAPIRequest should conform to the expected protocol") + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift new file mode 100644 index 0000000000..f97da4a3f8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift @@ -0,0 +1,52 @@ +// 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. + +@objcMembers +public class FakeBridgeApiRequest: NSObject, FBSDKBridgeAPIRequestProtocol { + public var actionID: String? + public var methodName: String? + public var protocolType: FBSDKBridgeAPIProtocolType + public var `protocol`: BridgeAPIProtocol? + public var scheme: String? + + let url: URL? + + init(url: URL?, protocolType: FBSDKBridgeAPIProtocolType = .native, scheme: String? = nil) { + self.url = url + self.protocolType = protocolType + self.scheme = scheme + } + + public func copy(with zone: NSZone? = nil) -> Any { + return self + } + + public func requestURL() throws -> URL { + guard let url = url else { + throw FakeBridgeApiRequestError(domain: "tests", code: 0, userInfo: [:]) + } + return url + } + + public static func request(withURL url: URL?) -> FakeBridgeApiRequest { + return FakeBridgeApiRequest(url: url) + } +} + +@objc +public class FakeBridgeApiRequestError: NSError {} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift index 0230181e64..0d56b0db5c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift @@ -23,6 +23,15 @@ public class ViewControllerSpy: UIViewController { public var capturedDismissCompletion: (() -> Void)? public var dismissWasCalled = false + public var capturedPresentViewController: UIViewController? + public var capturedPresentViewControllerAnimated: Bool? + public var capturedPresentViewControllerCompletion: (() -> Void)? + + // Overriding with no implementation to stub the property + public override var transitionCoordinator: UIViewControllerTransitionCoordinator? { + return nil + } + private lazy var presenting = { ViewControllerSpy.makeDefaultSpy() }() @@ -39,4 +48,14 @@ public class ViewControllerSpy: UIViewController { public static func makeDefaultSpy() -> ViewControllerSpy { return ViewControllerSpy() } + + // Overriding with no implementation to stub the method + public override func present( + _ viewControllerToPresent: UIViewController, + animated: Bool, + completion: (() -> Void)? = nil) { + capturedPresentViewController = viewControllerToPresent + capturedPresentViewControllerAnimated = animated + capturedPresentViewControllerCompletion = completion + } } From a349dd15d28a209b8b3e4531b2f2189a842a123d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 17 Nov 2020 11:57:06 -0800 Subject: [PATCH 117/227] Disable flaky test Summary: $title Reviewed By: jawwad Differential Revision: D24901381 fbshipit-source-id: 50b4d859cada69f25f430a4a298a888fa90b786e --- .../FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m index 9b5fbcd865..8e25188e40 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKGraphRequestConnectionTests.m @@ -104,7 +104,7 @@ - (void)requestConnectionWillBeginLoading:(FBSDKGraphRequestConnection *)connect #pragma mark - Tests -- (void)testClientToken +- (void)_testClientToken { // if it's a batch request the body will be zipped so make sure we don't do that id mockUtility = [OCMockObject niceMockForClass:[FBSDKBasicUtility class]]; From dda54a335b2922d1903de6c832204a117963f36b Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Tue, 17 Nov 2020 13:04:52 -0800 Subject: [PATCH 118/227] Fix a few swiftlint warnings particularly the one about modifier_order Summary: Swiftlint's default preferred modifier order is to have override before public, however Xcode's default is to have "public override". This can be tested by removing "public override" and applying Xcode's fix-its. Regardless of what fix-it you apply first, Xcode always ends up with "public override". This is also what the team prefers. Updated the preferred_modifier_order setting to have "acl" before "override" Also fixed or disabled line_length warnings. Reviewed By: joesus Differential Revision: D25029770 fbshipit-source-id: b896102f3f8be2cacfbc7ca1237a7dba12e3906a --- .swiftlint.yml | 4 ++++ .../Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift | 9 ++++++++- .../Internal/Helpers/AppDelegateObserverFake.swift | 6 ++++-- .../Internal/Monitoring/FakeMonitorStore.swift | 6 +++--- .../FBSDKServerConfigurationManagerTests.swift | 6 +++++- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 2466a484b9..e38e9b01e5 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -37,6 +37,10 @@ private_outlet: type_name: excluded: [RawAppEventsConfigurationResponseFixtures] +# Xcode fixits insert these as "public override" vs "override public" so overriding Swiftlint's defaullt of "override, acl, ..." to "acl, override, ..." +modifier_order: + preferred_modifier_order: [acl, override, setterACL, dynamic, mutators, lazy, final, required, convenience, typeMethods, owned] + disabled_rules: - attributes - conditional_returns_on_newline diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift index a674cf5a37..469ece8407 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIRequestTests.swift @@ -21,7 +21,14 @@ import XCTest class FBSDKBridgeAPIRequestTests: FBSDKTestCase { func testDefaultProtocolConformance() { - let request: Any = BridgeAPIRequest(protocolType: .web, scheme: "https", methodName: nil, methodVersion: nil, parameters: [:], userInfo: [:]) as Any + let request: Any = BridgeAPIRequest( + protocolType: .web, + scheme: "https", + methodName: nil, + methodVersion: nil, + parameters: [:], + userInfo: [:] + ) as Any let conformedRequest = request as? FBSDKBridgeAPIRequestProtocol XCTAssertNotNil(conformedRequest, "BridgeAPIRequest should conform to the expected protocol") diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift index c3ea5c45c4..441d951ab1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/AppDelegateObserverFake.swift @@ -21,8 +21,10 @@ public class ApplicationDelegateObserverFake: NSObject, FBSDKApplicationObservin public private(set) var didFinishLaunchingCallCount = 0 public private(set) var capturedLaunchOptions: [UIApplication.LaunchOptionsKey: Any]? - public func application(_ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { + public func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil + ) -> Bool { didFinishLaunchingCallCount += 1 capturedLaunchOptions = launchOptions return true diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift index b54b6e2952..0f3db980f0 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FakeMonitorStore.swift @@ -24,20 +24,20 @@ public class FakeMonitorStore: FBSDKMonitorStore { public var persistWasCalled = false public var capturedPersistedEntries: [FBSDKMonitorEntry] = [] - override public func persist(_ entries: [FBSDKMonitorEntry]) { + public override func persist(_ entries: [FBSDKMonitorEntry]) { super.persist(entries) persistWasCalled = true capturedPersistedEntries = entries } - override public func retrieveEntries() -> [FBSDKMonitorEntry] { + public override func retrieveEntries() -> [FBSDKMonitorEntry] { retrieveEntriesWasCalled = true return super.retrieveEntries() } - override public func clear() { + public override func clear() { super.clear() clearWasCalled = true diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift index 1366562986..6ccaa80a03 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/ServerConfiguration/FBSDKServerConfigurationManagerTests.swift @@ -21,7 +21,11 @@ import XCTest class FBSDKServerConfigurationManagerTests: XCTestCase { func testParsingResponses() { for _ in 0..<100 { - ServerConfigurationManager.processLoadRequestResponse(RawServerConfigurationResponseFixtures.random, error: nil, appID: nil) + ServerConfigurationManager.processLoadRequestResponse( + RawServerConfigurationResponseFixtures.random, + error: nil, + appID: nil + ) } } } From 2d5d9e5f4f42311d0c10bc798a26479cbf9ebaf8 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 17 Nov 2020 15:13:02 -0800 Subject: [PATCH 119/227] FBSDKBridgeAPI Unit Tests 6/n Summary: Testing the method: `_bridgeAPIRequestCompletionBlockWithRequest` Also updates some test fixtures and removes a test that wasn't providing a benefit. Reviewed By: jawwad Differential Revision: D25025620 fbshipit-source-id: 597740fb94fcca5a6d7b9680a585e2965f38a46a --- .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 9 +- .../BridgeAPI/FBSDKBridgeAPI+Testing.h | 7 +- .../FBSDKBridgeAPIOpenBridgeRequestTests.m | 25 +--- .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 111 ++++++++++++++++++ .../Helpers/FakeBridgeApiRequest.swift | 4 + 5 files changed, 127 insertions(+), 29 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 98b10bac66..476d2e1b08 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -41,7 +41,6 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { }; typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); -typedef void (^FBSDKBridgeAPIRequestCompletionBlock)(BOOL, NSError *); @protocol FBSDKAuthenticationSession @@ -297,8 +296,8 @@ - (void)openBridgeAPIRequest:(NSObject *)request } _pendingRequest = request; _pendingRequestCompletionBlock = [completionBlock copy]; - FBSDKBridgeAPIRequestCompletionBlock handler = [self _bridgeAPIRequestCompletionBlockWithRequest:request - completion:completionBlock]; + FBSDKSuccessBlock handler = [self _bridgeAPIRequestCompletionBlockWithRequest:request + completion:completionBlock]; if (useSafariViewController) { [self openURLWithSafariViewController:requestURL sender:nil fromViewController:fromViewController handler:handler]; } else { @@ -306,8 +305,8 @@ - (void)openBridgeAPIRequest:(NSObject *)request } } -- (FBSDKBridgeAPIRequestCompletionBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request - completion:(FBSDKBridgeAPIResponseBlock)completionBlock +- (FBSDKSuccessBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request + completion:(FBSDKBridgeAPIResponseBlock)completionBlock { return ^(BOOL openedURL, NSError *anError) { if (!openedURL) { diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h index 47a1206bb4..381d188d26 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h @@ -22,7 +22,6 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); -typedef void (^FBSDKBridgeAPIRequestCompletionBlock)(BOOL, NSError *); NS_SWIFT_NAME(AuthenticationSessionHandling) @protocol FBSDKAuthenticationSession @@ -60,7 +59,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (id)pendingUrlOpen; - (UIViewController *)safariViewController; - (BOOL)isDismissingSafariViewController; -- (FBSDKBridgeAPIRequest *)pendingRequest; +- (NSObject *)pendingRequest; - (FBSDKBridgeAPIResponseBlock)pendingRequestCompletionBlock; - (void)applicationWillResignActive:(UIApplication *)application; @@ -82,11 +81,11 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (void)setPendingUrlOpen:(id)opening; - (void)setSafariViewController:(nullable UIViewController *)controller; - (void)setIsDismissingSafariViewController:(BOOL)isDismissing; -- (void)setPendingRequest:(FBSDKBridgeAPIRequest *)newValue; +- (void)setPendingRequest:(NSObject *)newValue; - (void)setPendingRequestCompletionBlock:(FBSDKBridgeAPIResponseBlock)newValue; - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication; -- (FBSDKBridgeAPIRequestCompletionBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request +- (FBSDKSuccessBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request completion:(FBSDKBridgeAPIResponseBlock)completionBlock; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m index 99a4b19b97..b02619b9d4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenBridgeRequestTests.m @@ -44,7 +44,7 @@ - (void)setUp OCMStub( [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:OCMArg.any - completion:OCMArg.any] + completion:OCMArg.any] ); OCMStub( [_partialMock openURLWithSafariViewController:OCMArg.any @@ -80,7 +80,7 @@ - (void)testOpeningBridgeRequestWithRequestUrlUsingSafariVcWithFromVc XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); OCMVerify( [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request - completion:self.uninvokedCompletionHandler] + completion:self.uninvokedCompletionHandler] ); OCMVerify( [_partialMock openURLWithSafariViewController:self.sampleUrl @@ -102,7 +102,7 @@ - (void)testOpeningBridgeRequestWithRequestUrlUsingSafariVcWithoutFromVc XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); OCMVerify( [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request - completion:self.uninvokedCompletionHandler] + completion:self.uninvokedCompletionHandler] ); OCMVerify( [_partialMock openURLWithSafariViewController:self.sampleUrl @@ -125,7 +125,7 @@ - (void)testOpeningBridgeRequestWithRequestUrlNotUsingSafariVcWithFromVc XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); OCMVerify( [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request - completion:self.uninvokedCompletionHandler] + completion:self.uninvokedCompletionHandler] ); OCMVerify([_partialMock openURL:self.sampleUrl sender:nil handler:OCMArg.any]); } @@ -142,7 +142,7 @@ - (void)testOpeningBridgeRequestWithRequestUrlNotUsingSafariVcWithoutFromVc XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); OCMVerify( [_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request - completion:self.uninvokedCompletionHandler] + completion:self.uninvokedCompletionHandler] ); OCMVerify([_partialMock openURL:self.sampleUrl sender:nil handler:OCMArg.any]); } @@ -237,21 +237,6 @@ - (void)testOpeningBridgeRequestWithoutRequestUrlNotUsingSafariVcWithoutFromVc [self assertPendingPropertiesNotSet]; } -- (void)testOpeningBridgeRequestWithInsecureRequestUrl -{ - NSURL *expectedUrl = [NSURL URLWithString:@"file:///foo"]; - FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:expectedUrl]; - [self.api openBridgeAPIRequest:request - useSafariViewController:NO - fromViewController:nil - completionBlock:self.uninvokedCompletionHandler]; - - XCTAssertEqualObjects(self.api.pendingRequest, request); - XCTAssertEqualObjects(self.api.pendingRequestCompletionBlock, self.uninvokedCompletionHandler); - OCMVerify([_partialMock _bridgeAPIRequestCompletionBlockWithRequest:request completion:self.uninvokedCompletionHandler]); - OCMVerify([_partialMock openURL:expectedUrl sender:nil handler:OCMArg.any]); -} - // MARK: - Helpers - (void)rejectApiOpeningBridgeRequest diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m index 05e350778d..0df5319b41 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -397,13 +397,124 @@ - (void)testOpenUrlWhenApplicationDoesNotOpen [self waitForExpectationsWithTimeout:1 handler:nil]; } +// MARK: - Request completion block + +- (void)testRequestCompletionBlockCalledWithSuccess +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + FBSDKBridgeAPIResponseBlock responseBlock = ^void (FBSDKBridgeAPIResponse *response) { + XCTFail("Should not call the response block when the request completion is called with success"); + }; + self.api.pendingRequest = request; + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *response) {}; + + FBSDKSuccessBlock completion = [self.api _bridgeAPIRequestCompletionBlockWithRequest:request + completion:responseBlock]; + // With Error + completion(true, self.sampleError); + [self assertPendingPropertiesNotCleared]; + + // Without Error + completion(true, nil); + [self assertPendingPropertiesNotCleared]; +} + +- (void)testRequestCompletionBlockWithNonHttpRequestCalledWithoutSuccess +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl scheme:@"file"]; + FBSDKBridgeAPIResponseBlock responseBlock = ^void (FBSDKBridgeAPIResponse *response) { + XCTAssertEqualObjects(response.request, request, "The response should contain the original request"); + XCTAssertEqual( + response.error.code, + FBSDKErrorAppVersionUnsupported, + "The response should contain the expected error code" + ); + XCTAssertEqualObjects( + response.error.userInfo[FBSDKErrorDeveloperMessageKey], + @"the app switch failed because the destination app is out of date", + "The response should contain the expected error message" + ); + }; + self.api.pendingRequest = request; + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *response) {}; + + FBSDKSuccessBlock completion = [self.api _bridgeAPIRequestCompletionBlockWithRequest:request + completion:responseBlock]; + // With Error + completion(false, self.sampleError); + [self assertPendingPropertiesCleared]; + + // Without Error + completion(false, nil); + [self assertPendingPropertiesCleared]; +} + +- (void)testRequestCompletionBlockWithHttpRequestCalledWithoutSuccess +{ + FakeBridgeApiRequest *request = [FakeBridgeApiRequest requestWithURL:self.sampleUrl scheme:@"https"]; + FBSDKBridgeAPIResponseBlock responseBlock = ^void (FBSDKBridgeAPIResponse *response) { + XCTAssertEqualObjects(response.request, request, "The response should contain the original request"); + XCTAssertEqual( + response.error.code, + FBSDKErrorBrowserUnavailable, + "The response should contain the expected error code" + ); + XCTAssertEqualObjects( + response.error.userInfo[FBSDKErrorDeveloperMessageKey], + @"the app switch failed because the browser is unavailable", + "The response should contain the expected error message" + ); + }; + self.api.pendingRequest = request; + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *response) {}; + + FBSDKSuccessBlock completion = [self.api _bridgeAPIRequestCompletionBlockWithRequest:request + completion:responseBlock]; + // With Error + completion(false, self.sampleError); + [self assertPendingPropertiesCleared]; + + // Without Error + completion(false, nil); + [self assertPendingPropertiesCleared]; +} + // MARK: - Helpers +- (void)assertPendingPropertiesCleared +{ + XCTAssertNil( + self.api.pendingRequest, + "Should clear the pending request" + ); + XCTAssertNil( + self.api.pendingRequestCompletionBlock, + "Should clear the pending request completion block" + ); +} + +- (void)assertPendingPropertiesNotCleared +{ + XCTAssertNotNil( + self.api.pendingRequest, + "Should not clear the pending request" + ); + XCTAssertNotNil( + self.api.pendingRequestCompletionBlock, + "Should not clear the pending request completion block" + ); +} + - (NSURL *)sampleUrl { return [NSURL URLWithString:@"http://example.com"]; } +- (NSError *)sampleError +{ + return [NSError errorWithDomain:self.name code:0 userInfo:nil]; +} + static inline NSString *StringFromBool(BOOL value) { return value ? @"YES" : @"NO"; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift index f97da4a3f8..61fb7242f3 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeBridgeApiRequest.swift @@ -46,6 +46,10 @@ public class FakeBridgeApiRequest: NSObject, FBSDKBridgeAPIRequestProtocol { public static func request(withURL url: URL?) -> FakeBridgeApiRequest { return FakeBridgeApiRequest(url: url) } + + public static func request(withURL url: URL, scheme: String) -> FakeBridgeApiRequest { + return FakeBridgeApiRequest(url: url, scheme: scheme) + } } @objc From 3ff7a295bdd1e68d4873edda4b8c01e54008f25b Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Tue, 17 Nov 2020 15:18:03 -0800 Subject: [PATCH 120/227] Convert FBSDKAppEventsConfigurationManagerTests.m to Swift Summary: This file is one that needs access to a private method in FBSDKAppEventsConfigurationManager. To expose the private method to Swift I added an entry for the category in the bridging header. We could decide to move these into a separate file if needed but I think it feels ok to have them directly in here for now. (Easier to search for bridging header than "what's the name of that new swift header I had created" for Objective-C categories that Swift needs") Reviewed By: joesus Differential Revision: D25031348 fbshipit-source-id: 236f95968ce17491da08bcda9e884248e4e7916c --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 ++--- .../FBSDKCoreKitTests-Bridging-Header.h | 5 +++ ...KAppEventsConfigurationManagerTests.swift} | 32 +++---------------- 3 files changed, 14 insertions(+), 31 deletions(-) rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/{FBSDKAppEventsConfigurationManagerTests.m => FBSDKAppEventsConfigurationManagerTests.swift} (63%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 7b210d2b1b..cae3bb9873 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -1007,7 +1007,7 @@ F98D1D3825124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */; }; F98D1D5525124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift */; }; F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */; }; - F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */; }; + F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift */; }; F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; F9A06DB82510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */; }; F9A06DB92510FAD3007E6386 /* FBSDKAppEventsConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */; }; @@ -1634,7 +1634,7 @@ F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationFixtures.m; sourceTree = ""; }; F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKAppEventsConfigurationTests.swift; sourceTree = ""; }; F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawAppEventsConfigurationResponseFixtures.swift; sourceTree = ""; }; - F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfigurationManagerTests.m; sourceTree = ""; }; + F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKAppEventsConfigurationManagerTests.swift; sourceTree = ""; }; F9A06DB52510FAD3007E6386 /* FBSDKAppEventsConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfiguration.h; sourceTree = ""; }; F9A06DB62510FAD3007E6386 /* FBSDKAppEventsConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsConfiguration.m; sourceTree = ""; }; F9A06DCD2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsConfigurationManager.h; sourceTree = ""; }; @@ -2224,7 +2224,7 @@ F98D1D3625124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.h */, F98D1D3725124FAE00276B68 /* FBSDKAppEventsConfigurationFixtures.m */, F98D1D5425124FCB00276B68 /* FBSDKAppEventsConfigurationTests.swift */, - F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m */, + F98D1D72251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift */, F98D1D63251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift */, ); path = AppEvents; @@ -4150,7 +4150,7 @@ F4210E1E241AFF740061F56D /* FBSDKMethodUsageMonitorTests.m in Sources */, F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */, F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, - F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, + F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift in Sources */, 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */, F408C712256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift in Sources */, 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 56d7f86aa6..6cfb893d51 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -29,3 +29,8 @@ // Interfaces for Swift extensions on Objective-C Test classes @interface FBSDKAppEventsUtilityTests : FBSDKTestCase @end + +// Categories needed to expose private methods to Swift +@interface FBSDKAppEventsConfigurationManager (Testing) ++ (void)_processResponse:(id)response error:(NSError *)error; +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.swift similarity index 63% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.swift index cfc1307787..c012dcc8cf 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsConfigurationManagerTests.swift @@ -16,32 +16,10 @@ // 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 "FBSDKCoreKit+Internal.h" -#import "FBSDKCoreKitTests-Swift.h" - -@interface FBSDKAppEventsConfigurationManager (Testing) - -+ (void)_processResponse:(id)response - error:(NSError *)error; - -@end - -@interface FBSDKAppEventsConfigurationManagerTests : XCTestCase - -@end - -@implementation FBSDKAppEventsConfigurationManagerTests - -- (void)testParsingResponses -{ - for (int i = 0; i < 100; i++) { - [FBSDKAppEventsConfigurationManager _processResponse:RawAppEventsConfigurationResponseFixtures.random error:nil]; +class FBSDKAppEventsConfigurationManagerTests: XCTestCase { + func testParsingResponses() { + for _ in 0..<100 { + AppEventsConfigurationManager._processResponse(RawAppEventsConfigurationResponseFixtures.random, error: nil) + } } } - -@end From a544fdf35eacc90bf715205cedeaa4a70814b564 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Wed, 18 Nov 2020 12:00:16 -0800 Subject: [PATCH 121/227] Convert FBSDKSampleEventBinding.m test helper to Swift Summary: Converted the FBSDKSampleEventBinding.m test helper to Swift Reviewed By: joesus Differential Revision: D25006089 fbshipit-source-id: 5c00c1b5a879d2902fe77c465d133560d22006bc --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 +- .../Codeless/FBSDKEventBindingTests.m | 1 - .../Codeless/FBSDKSampleEventBinding.h | 23 --- .../Codeless/FBSDKSampleEventBinding.m | 141 ------------------ .../Codeless/FBSDKSampleEventBinding.swift | 140 +++++++++++++++++ 5 files changed, 144 insertions(+), 171 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index cae3bb9873..7e52a923ec 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -699,7 +699,7 @@ C4FC99F1202CD56D0038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = C4FC99D7202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.h */; }; C4FC99F2202CD56D0038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = C4FC99D8202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m */; }; C51121CB20A27EF50041DC94 /* FBSDKEventBindingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C51121C920A27EF50041DC94 /* FBSDKEventBindingTests.m */; }; - C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.m in Sources */ = {isa = PBXBuildFile; fileRef = C51121CA20A27EF50041DC94 /* FBSDKSampleEventBinding.m */; }; + C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51121CA20A27EF50041DC94 /* FBSDKSampleEventBinding.swift */; }; C51122A020A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C511229F20A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m */; }; C5188DF9222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = C5188DF8222F388400F4D8BC /* FBSDKApplicationObserving.h */; }; C5188DFA222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */ = {isa = PBXBuildFile; fileRef = C5188DF8222F388400F4D8BC /* FBSDKApplicationObserving.h */; }; @@ -1488,9 +1488,8 @@ C4513900202CBF1F0063275D /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.2.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; }; C4FC99D7202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKHybridAppEventsScriptMessageHandler.h; sourceTree = ""; }; C4FC99D8202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKHybridAppEventsScriptMessageHandler.m; sourceTree = ""; }; - C51121C820A27EF50041DC94 /* FBSDKSampleEventBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKSampleEventBinding.h; sourceTree = ""; }; C51121C920A27EF50041DC94 /* FBSDKEventBindingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKEventBindingTests.m; sourceTree = ""; }; - C51121CA20A27EF50041DC94 /* FBSDKSampleEventBinding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSampleEventBinding.m; sourceTree = ""; }; + C51121CA20A27EF50041DC94 /* FBSDKSampleEventBinding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBSDKSampleEventBinding.swift; sourceTree = ""; }; C511229F20A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKApplicationDelegateTests.m; sourceTree = ""; }; C5188DF8222F388400F4D8BC /* FBSDKApplicationObserving.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKApplicationObserving.h; sourceTree = ""; }; C5188E312231C4B500F4D8BC /* FBSDKBridgeAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKBridgeAPI.h; sourceTree = ""; }; @@ -2448,8 +2447,7 @@ C51121C720A27EF50041DC94 /* Codeless */ = { isa = PBXGroup; children = ( - C51121C820A27EF50041DC94 /* FBSDKSampleEventBinding.h */, - C51121CA20A27EF50041DC94 /* FBSDKSampleEventBinding.m */, + C51121CA20A27EF50041DC94 /* FBSDKSampleEventBinding.swift */, C51121C920A27EF50041DC94 /* FBSDKEventBindingTests.m */, ); path = Codeless; @@ -4162,7 +4160,7 @@ F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */, 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.swift in Sources */, F41979282475A20E003007CC /* FBSDKTypeUtilityTests.m in Sources */, - C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.m in Sources */, + C51121CC20A27EF50041DC94 /* FBSDKSampleEventBinding.swift in Sources */, F916581524F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m in Sources */, F4A826B724EC6FAD00EB2CD4 /* FBSDKProfileTests.m in Sources */, 5D59BFFF23A7505D0008CA5A /* FBSDKLibAnalyzerTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m index 78ec774236..12298a932d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKEventBindingTests.m @@ -22,7 +22,6 @@ #import "FBSDKCoreKitTests-Swift.h" #import "FBSDKEventBinding.h" #import "FBSDKEventBindingManager.h" -#import "FBSDKSampleEventBinding.h" @interface FBSDKEventBindingTests : XCTestCase { diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h deleted file mode 100644 index 9cc8c475b8..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.h +++ /dev/null @@ -1,23 +0,0 @@ -// 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 - -@interface FBSDKSampleEventBinding : NSObject -+ (NSDictionary *)getSampleDictionary; -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m deleted file mode 100644 index 87da087c93..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.m +++ /dev/null @@ -1,141 +0,0 @@ -// 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 "FBSDKSampleEventBinding.h" - -@implementation FBSDKSampleEventBinding -+ (NSDictionary *)getSampleDictionary -{ - return @{ - @"event_bindings" : @[ - @{ - @"event_name" : @"Quantity Changed", - @"event_type" : @"click", - @"app_version" : @"1.2", - @"path" : @[ - @{ - @"class_name" : @"UIWindow", - }, - @{ - @"class_name" : @"UITabBarController", - }, - @{ - @"class_name" : @"UINavigationController", - }, - @{ - @"class_name" : @"UIViewController", - }, - @{ - @"class_name" : @"UIStackView", - }, - @{ - @"class_name" : @"UIStackView", - }, - @{ - @"class_name" : @"UIStepper", - } - ] - }, - @{ - @"event_name" : @"Add To Cart", - @"event_type" : @"click", - @"app_version" : @"1.2", - @"path" : @[ - @{ - @"class_name" : @"UIViewController", - }, - @{ - @"class_name" : @"UIStackView", - }, - @{ - @"class_name" : @"UIButton", - @"text" : @"Buy" - } - ], - @"parameters" : @[ - @{ - @"parameter_name" : @"price", - @"path_type" : @"relative", - @"path" : @[ - @{ - @"class_name" : @"..", - }, - @{ - @"class_name" : @"UILabel", - @"index" : @2, - }, - ] - } - ] - }, - @{ - @"event_name" : @"Purchase", - @"event_type" : @"click", - @"app_version" : @"1.2", - @"path" : @[ - @{ - @"class_name" : @"UIWindow", - }, - @{ - @"class_name" : @"UITabBarController", - }, - @{ - @"class_name" : @"UINavigationController", - }, - @{ - @"class_name" : @"UIViewController", - }, - @{ - @"class_name" : @"UIStackView", - }, - @{ - @"class_name" : @"UIButton", - @"text" : @"Confirm" - }, - ], - @"parameters" : @[ - @{ - @"parameter_name" : @"price", - @"path_type" : @"relative", - @"path" : @[ - @{ - @"class_name" : @"..", - }, - @{ - @"class_name" : @"UIStackView", - }, - @{ - @"class_name" : @"UILabel", - @"index" : @0, - } - ] - }, - @{ - @"parameter_name" : @"action", - @"path_type" : @"relative", - @"path" : @[ - @{@"class_name" : @"."} - ], - }, - ] - } - ], - }; -} - -@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift new file mode 100644 index 0000000000..a05f07d4c6 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift @@ -0,0 +1,140 @@ +// 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. + +@objcMembers +class FBSDKSampleEventBinding: NSObject { + class func getSampleDictionary() -> [String: Any] { // swiftlint:ignore:this function_body_length + return [ + "event_bindings": [ + [ + "event_name": "Quantity Changed", + "event_type": "click", + "app_version": "1.2", + "path": [ + [ + "class_name": "UIWindow" + ], + [ + "class_name": "UITabBarController" + ], + [ + "class_name": "UINavigationController" + ], + [ + "class_name": "UIViewController" + ], + [ + "class_name": "UIStackView" + ], + [ + "class_name": "UIStackView" + ], + [ + "class_name": "UIStepper" + ], + ], + ], + [ + "event_name": "Add To Cart", + "event_type": "click", + "app_version": "1.2", + "path": [ + [ + "class_name": "UIViewController" + ], + [ + "class_name": "UIStackView" + ], + [ + "class_name": "UIButton", + "text": "Buy", + ], + ], + "parameters": [ + [ + "parameter_name": "price", + "path_type": "relative", + "path": [ + [ + "class_name": ".." + ], + [ + "class_name": "UILabel", + "index": 2, + ] + ] + ] + ] + ], + [ + "event_name": "Purchase", + "event_type": "click", + "app_version": "1.2", + "path": [ + [ + "class_name": "UIWindow" + ], + [ + "class_name": "UITabBarController" + ], + [ + "class_name": "UINavigationController" + ], + [ + "class_name": "UIViewController" + ], + [ + "class_name": "UIStackView" + ], + [ + "class_name": "UIButton", + "text": "Confirm", + ], + ], + "parameters": [ + [ + "parameter_name": "price", + "path_type": "relative", + "path": [ + [ + "class_name": ".." + ], + [ + "class_name": "UIStackView" + ], + [ + "class_name": "UILabel", + "index": 0, + ], + ], + ], + [ + "parameter_name": "action", + "path_type": "relative", + "path": [ + [ + "class_name": "." + ] + ] + ] + ] + ] + ] + ] + } +} From f439cbecd9edf2d5303fd5761ccde69464e5b9b5 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Wed, 18 Nov 2020 12:15:58 -0800 Subject: [PATCH 122/227] Update the Carthage version of OCMock to match the internal version Summary: OCMock was upgraded internally for buck to 3.6.1 with D21750024. However the version referenced the in Cartfile is 3.5.1. Updated the version in the Cartfile to match the internal version so that we don't run into weird issues when building via BUCK vs Xcode. This also takes care of the following error that was caused due to using an older version: ``` The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.2.99. ``` Also updated OCMVerify to OCMVerifyAll to fix 2 "Expression result unused" warnings https://stackoverflow.com/a/63926392/340508 Reviewed By: joesus Differential Revision: D25032351 fbshipit-source-id: 01fa64300359b8b3728274daeb25806af35b2fe5 --- Cartfile.private | 2 +- Cartfile.resolved | 2 +- .../Internal/Instrument/FBSDKCrashShieldTests.m | 2 +- .../Internal/Monitoring/FBSDKMonitorNetworkerTests.m | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cartfile.private b/Cartfile.private index 7fb0ee31fa..ca5073ace6 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,2 +1,2 @@ github "AliSoftware/OHHTTPStubs" "543182991a0d59db81f5b835a40901a9a386847d" -github "erikdoe/ocmock" "630598a81c8d51ae98434a388d17fe67de37b21a" +github "erikdoe/ocmock" "58bb623eb3852ab72b4c993bfd53040f051a405c" diff --git a/Cartfile.resolved b/Cartfile.resolved index 7fb0ee31fa..ca5073ace6 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,2 +1,2 @@ github "AliSoftware/OHHTTPStubs" "543182991a0d59db81f5b835a40901a9a386847d" -github "erikdoe/ocmock" "630598a81c8d51ae98434a388d17fe67de37b21a" +github "erikdoe/ocmock" "58bb623eb3852ab72b4c993bfd53040f051a405c" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m index 1755b7053f..31d481abed 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m @@ -222,7 +222,7 @@ - (void)testPostingCoreKitCrashLogsWithDataProcessingUnrestricted NSDictionary *expectedParameters = @{ @"crash_shield" : [self encodedCoreKitFeatureDataWithTimestamp:@"10"] }; - OCMVerify( + OCMVerifyAll( [self.graphRequestMock initWithGraphPath:expectedPath parameters:expectedParameters HTTPMethod:FBSDKHTTPMethodPOST] diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m index 8e703af991..4bb6a5449c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Monitoring/FBSDKMonitorNetworkerTests.m @@ -106,7 +106,7 @@ - (void)testSendingEntriesCreatesGraphRequest [FBSDKMonitorNetworker sendEntries:entries]; - OCMVerify( + OCMVerifyAll( [graphRequestMock initWithGraphPath:[OCMArg checkWithBlock:verifyPath] parameters:[OCMArg checkWithBlock:verifyParameters] tokenString:[OCMArg isNil] From 7b5261b92cef6bb201c092d38053e27442492744 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 18 Nov 2020 17:12:03 -0800 Subject: [PATCH 123/227] Fix Package Manager for Catalyst (#1579) Summary: Pull Request resolved: https://github.com/facebook/facebook-ios-sdk/pull/1579 A required macro was not available for macOS platform. Fixes: https://github.com/facebook/facebook-ios-sdk/issues/1577 Reviewed By: jawwad Differential Revision: D25064406 fbshipit-source-id: 969475e3cbb1ce86262591fa5160401114833f54 --- Package.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Package.swift b/Package.swift index a1e75d07b3..8055e127e0 100644 --- a/Package.swift +++ b/Package.swift @@ -100,7 +100,7 @@ let package = Package( cSettings: [ .headerSearchPath("Internal"), .headerSearchPath("../../FBSDKCoreKit/FBSDKCoreKit/Internal"), - .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) + .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS, .macOS], configuration: nil)) ] ), .target( @@ -116,7 +116,7 @@ let package = Package( cSettings: [ .headerSearchPath("Internal"), .headerSearchPath("../../FBSDKCoreKit/FBSDKCoreKit/Internal"), - .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) + .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS, .macOS], configuration: nil)) ] ), .target( @@ -133,7 +133,7 @@ let package = Package( .headerSearchPath("Internal"), .headerSearchPath("../../FBSDKCoreKit/FBSDKCoreKit/Internal"), .headerSearchPath("../../FBSDKShareKit/FBSDKShareKit/Internal"), - .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS], configuration: nil)) + .define("FBSDK_SWIFT_PACKAGE", to: nil, .when(platforms: [.iOS, .macOS], configuration: nil)) ] ), .target( From 78571afc4393afd7c5845ff54d85fa360eb2e614 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 18 Nov 2020 21:20:19 -0800 Subject: [PATCH 124/227] FBSDKBridgeAPI Unit Tests 7/n Summary: This one is a bit different. Currently there's no way to mock the way we load dynamic frameworks. So we can only test one condition branch for every dynamic framework. This fixes that by introducing a new protocol, `FBSDKDynamicFrameworkResolving` that wraps the c functions in the `FBSDKDynamicFrameworkLoader` class. For call sites we introduce a private method override to pass in a `id` object. The existing implementation passes in the shared instance of `FBSDKDynamicFrameworkLoader` and the new override can be used for testing. This is a common practice for protocol-based unit testing in Swift and will make the eventual transition easier. Reviewed By: jawwad Differential Revision: D25034818 fbshipit-source-id: 10e5f2107712c0b904ddefae6647b50cbf1afe87 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 19 ++ .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 15 +- .../Internal/FBSDKDynamicFrameworkLoader.h | 7 +- .../Internal/FBSDKDynamicFrameworkResolving.h | 31 ++ .../FBSDKDynamicFrameworkLoader.m | 15 + .../FBSDKBridgeAPIOpenUrlWithSafariTests.m | 274 ++++++++++++++++++ .../Internal/Helpers/FBSDKTestCase.h | 3 + .../Internal/Helpers/FBSDKTestCase.m | 10 + .../Internal/Helpers/FakeDylibResolver.swift | 26 ++ .../Internal/Helpers/FakeLoginManager.h | 1 + .../Internal/Helpers/FakeLoginManager.m | 2 +- .../Internal/Helpers/ViewControllerSpy.swift | 7 +- 12 files changed, 405 insertions(+), 5 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkResolving.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenUrlWithSafariTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeDylibResolver.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 7e52a923ec..d837a1016e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -843,6 +843,12 @@ F4210E37241B00790061F56D /* FBSDKMethodUsageMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */; }; F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */; }; F43960D02425513100C1868F /* FakeMonitorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F43960CF2425513100C1868F /* FakeMonitorStore.swift */; }; + F44B04B7256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F44B04A8256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m */; }; + F44B04EE256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */; }; + F44B04EF256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */; }; + F44B04F0256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */; }; + F44B04F1256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */; }; + F44B051125645DAC0059A3A6 /* FakeDylibResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44B051025645DAC0059A3A6 /* FakeDylibResolver.swift */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -1555,6 +1561,9 @@ F4210E2D241B00790061F56D /* FBSDKMethodUsageMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMethodUsageMonitor.m; sourceTree = ""; }; F428430A246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKServerConfigurationManagerTests.swift; sourceTree = ""; }; F43960CF2425513100C1868F /* FakeMonitorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeMonitorStore.swift; sourceTree = ""; }; + F44B04A8256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBridgeAPIOpenUrlWithSafariTests.m; sourceTree = ""; }; + F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKDynamicFrameworkResolving.h; sourceTree = ""; }; + F44B051025645DAC0059A3A6 /* FakeDylibResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeDylibResolver.swift; sourceTree = ""; }; F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; @@ -1979,6 +1988,7 @@ 520223F51D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.h */, 520223F61D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m */, 81C969301C114723002FC037 /* FBSDKDynamicFrameworkLoader.h */, + F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */, 894C0B5F1A7150AC009137EF /* FBSDKError.h */, 894C0B601A7150AC009137EF /* FBSDKError.m */, C5C7B74822D84F64004A5A0C /* FBSDKFeatureManager.h */, @@ -2111,6 +2121,7 @@ F41200EC255F4775009E323F /* FBSDKBridgeAPITests.h */, F402AFC7255B49A500473083 /* FBSDKBridgeAPITests.m */, F41200CF255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m */, + F44B04A8256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m */, F408C6BF2563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m */, F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */, F408C711256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift */, @@ -2690,6 +2701,7 @@ F402B060255C645600473083 /* FakeLoginManager.h */, F402B061255C645600473083 /* FakeLoginManager.m */, F408C6E8256309A500372D61 /* FakeBridgeApiRequest.swift */, + F44B051025645DAC0059A3A6 /* FakeDylibResolver.swift */, ); path = Helpers; sourceTree = ""; @@ -2773,6 +2785,7 @@ files = ( 814AC8171D1B528900D61E6C /* FBSDKKeychainStoreViaBundleID.h in Headers */, 5D6DF16D2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, + F44B04F1256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */, 814AC8181D1B528900D61E6C /* FBSDKError.h in Headers */, 814AC8191D1B528900D61E6C /* FBSDKButton.h in Headers */, 814AC81A1D1B528900D61E6C /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -2890,6 +2903,7 @@ F9A06DD02510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, 81B71D511D19C87400933E93 /* FBSDKButton.h in Headers */, 52963AAD2159A16E00C7B252 /* FBSDKMeasurementEvent.h in Headers */, + F44B04EF256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */, 81B71D521D19C87400933E93 /* FBSDKBridgeAPIProtocol.h in Headers */, C5696F94209BBC35009C931F /* FBSDKEventBinding.h in Headers */, 81B71D531D19C87400933E93 /* FBSDKGraphErrorRecoveryProcessor.h in Headers */, @@ -3120,6 +3134,7 @@ 9DC658A51A6EE7E200B85AAF /* FBSDKGraphRequestBody.h in Headers */, 896DE2341A9E509300195731 /* FBSDKGraphRequestDataAttachment.h in Headers */, F4A52AFE242A80F4005F65CE /* FBSDKPerformanceMonitorEntry.h in Headers */, + F44B04EE256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */, 9DA8303C1A6999EC00770955 /* FBSDKSettings.h in Headers */, 89830F2F1A7805E100226ABB /* FBSDKServerConfiguration.h in Headers */, 9D0BC15F1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.h in Headers */, @@ -3156,6 +3171,7 @@ files = ( 9D6DEECE1BC23A56001A94ED /* FBSDKKeychainStoreViaBundleID.h in Headers */, 5D6DF16C2398E2A200AC2D6C /* FBSDKEventDeactivationManager.h in Headers */, + F44B04F0256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */, 9DB0FA901BC22AE9005EB8B1 /* FBSDKError.h in Headers */, 9D65383B1BF413B3008A08E9 /* FBSDKButton.h in Headers */, 9D6DEEB91BC2389F001A94ED /* FBSDKErrorRecoveryConfiguration.h in Headers */, @@ -4149,6 +4165,8 @@ F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */, F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift in Sources */, + F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, + F44B051125645DAC0059A3A6 /* FakeDylibResolver.swift in Sources */, 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */, F408C712256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift in Sources */, 5DAB01F123A1831A005495FB /* FBSDKCrashObserverTests.m in Sources */, @@ -4174,6 +4192,7 @@ 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, + F44B04B7256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m in Sources */, E493252D23F7C60E0000B63A /* FBSDKModelParserTests.mm in Sources */, F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */, F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.swift in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 476d2e1b08..2637110eb9 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -332,6 +332,19 @@ - (void)openURLWithSafariViewController:(NSURL *)url sender:(id)sender fromViewController:(UIViewController *)fromViewController handler:(FBSDKSuccessBlock)handler +{ + [self _openURLWithSafariViewController:url + sender:sender + fromViewController:fromViewController + handler:handler + dylibResolver:FBSDKDynamicFrameworkLoader.shared]; +} + +- (void)_openURLWithSafariViewController:(NSURL *)url + sender:(id)sender + fromViewController:(UIViewController *)fromViewController + handler:(FBSDKSuccessBlock)handler + dylibResolver:(id)dylibResolver { if (![url.scheme hasPrefix:@"http"]) { [self openURL:url sender:sender handler:handler]; @@ -352,7 +365,7 @@ - (void)openURLWithSafariViewController:(NSURL *)url // trying to dynamically load SFSafariViewController class // so for the cases when it is available we can send users through Safari View Controller flow // in cases it is not available regular flow will be selected - Class SFSafariViewControllerClass = fbsdkdfl_SFSafariViewControllerClass(); + Class SFSafariViewControllerClass = dylibResolver.safariViewControllerClass; if (SFSafariViewControllerClass) { UIViewController *parent = fromViewController ?: [FBSDKInternalUtility topMostViewController]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkLoader.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkLoader.h index 35d002c16e..5847f84eab 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkLoader.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkLoader.h @@ -20,6 +20,8 @@ #import #import +#import "FBSDKDynamicFrameworkResolving.h" + NS_ASSUME_NONNULL_BEGIN #pragma mark - Security APIs @@ -141,11 +143,14 @@ FOUNDATION_EXPORT Class fbsdkdfl_WKUserScriptClass(void); As new types are needed, they should be added and strongly typed. */ NS_SWIFT_NAME(DynamicFrameworkLoader) -@interface FBSDKDynamicFrameworkLoader : NSObject +@interface FBSDKDynamicFrameworkLoader : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; +// A shared instance to access dynamically loaded types from ++ (instancetype)shared; + #pragma mark - Security Constants /** diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkResolving.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkResolving.h new file mode 100644 index 0000000000..6514d6979a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkResolving.h @@ -0,0 +1,31 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// Used for defining behavior of types that provide classes for types that +/// exist in dynamically loaded frameworks. +@protocol FBSDKDynamicFrameworkResolving + +- (nullable Class)safariViewControllerClass; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m b/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m index 3fd62d9231..734963054c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m @@ -111,6 +111,21 @@ static void fbsdkdfl_load_symbol_once(void *context) @implementation FBSDKDynamicFrameworkLoader ++ (FBSDKDynamicFrameworkLoader *)shared +{ + static dispatch_once_t onceToken; + static FBSDKDynamicFrameworkLoader *shared = nil; + dispatch_once(&onceToken, ^{ + shared = [[self alloc] init]; + }); + return shared; +} + +- (Class)safariViewControllerClass +{ + return fbsdkdfl_SFSafariViewControllerClass(); +} + #define _fbsdkdfl_Security_get_k(SYMBOL) _fbsdkdfl_symbol_get_k(Security, SYMBOL, CFTypeRef *) #define _fbsdkdfl_Security_get_and_return_k(SYMBOL) \ diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenUrlWithSafariTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenUrlWithSafariTests.m new file mode 100644 index 0000000000..ed9a993204 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPIOpenUrlWithSafariTests.m @@ -0,0 +1,274 @@ +// 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 + +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" +#import "FakeLoginManager.h" + +@interface FBSDKBridgeAPI (Testing) +- (void)_openURLWithSafariViewController:(NSURL *)url + sender:(id)sender + fromViewController:(UIViewController *)fromViewController + handler:(FBSDKSuccessBlock)handler + dylibResolver:(id)dylibResolver; +@end + +@interface FBSDKBridgeAPIOpenUrlWithSafariTests : FBSDKTestCase + +@property (nonatomic) FBSDKBridgeAPI *api; +@property (nonatomic) id partialMock; +@property (nonatomic, readonly) NSURL *sampleUrl; +@property (nonatomic) FBSDKLoginManager *urlOpener; + +@end + +@implementation FBSDKBridgeAPIOpenUrlWithSafariTests + +- (void)setUp +{ + [super setUp]; + + [FBSDKLoginManager resetTestEvidence]; + _api = [FBSDKBridgeAPI new]; + _partialMock = OCMPartialMock(self.api); + _urlOpener = [FBSDKLoginManager new]; + + OCMStub([_partialMock setSessionCompletionHandlerFromHandler:OCMArg.any]); + OCMStub([_partialMock openURLWithAuthenticationSession:OCMArg.any]); + OCMStub([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); +} + +- (void)tearDown +{ + _api = nil; + _urlOpener = nil; + + [_partialMock stopMocking]; + _partialMock = nil; + + [super tearDown]; +} + +// MARK: - Url Opening + +- (void)testWithNonHttpUrlScheme +{ + NSURL *url = [NSURL URLWithString:@"file://example.com"]; + self.api.expectingBackground = YES; // So we can check that it's unchanged + + [self.api openURLWithSafariViewController:url + sender:nil + fromViewController:nil + handler:self.uninvokedSuccessBlock]; + OCMVerify([_partialMock openURL:url sender:nil handler:self.uninvokedSuccessBlock]); + XCTAssertTrue(self.api.expectingBackground, "Should not modify whether the background is expected to change"); + XCTAssertNil(self.api.pendingUrlOpen, "Should not set a pending url opener"); +} + +- (void)testWithAuthenticationURL +{ + self.urlOpener.stubbedIsAuthenticationUrl = YES; + self.api.expectingBackground = YES; + + OCMReject([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); + + [self.api openURLWithSafariViewController:self.sampleUrl + sender:self.urlOpener + fromViewController:nil + handler:self.uninvokedSuccessBlock]; + + OCMVerify([_partialMock setSessionCompletionHandlerFromHandler:self.uninvokedSuccessBlock]); + OCMVerify([_partialMock openURLWithAuthenticationSession:self.sampleUrl]); + [self assertExpectingBackgroundAndPendingUrlOpener]; +} + +- (void)testWithNonAuthenticationURL +{ + self.urlOpener.stubbedIsAuthenticationUrl = NO; + self.api.expectingBackground = YES; + + OCMReject([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); + OCMReject([_partialMock setSessionCompletionHandlerFromHandler:OCMArg.any]); + OCMReject([_partialMock openURLWithAuthenticationSession:OCMArg.any]); + + [self.api openURLWithSafariViewController:self.sampleUrl + sender:self.urlOpener + fromViewController:nil + handler:self.uninvokedSuccessBlock]; + + [self assertExpectingBackgroundAndPendingUrlOpener]; +} + +- (void)testWithoutSafariVcAvailable +{ + FakeDylibResolver *resolver = [FakeDylibResolver new]; + self.urlOpener.stubbedIsAuthenticationUrl = NO; + self.api.expectingBackground = YES; + + OCMReject([_partialMock setSessionCompletionHandlerFromHandler:OCMArg.any]); + OCMReject([_partialMock openURLWithAuthenticationSession:OCMArg.any]); + + [self.api _openURLWithSafariViewController:self.sampleUrl + sender:self.urlOpener + fromViewController:nil + handler:self.uninvokedSuccessBlock + dylibResolver:resolver]; + + OCMVerify( + [_partialMock openURL:self.sampleUrl + sender:self.urlOpener + handler:self.uninvokedSuccessBlock] + ); + [self assertExpectingBackgroundAndPendingUrlOpener]; +} + +- (void)testWithoutFromViewController +{ + self.urlOpener.stubbedIsAuthenticationUrl = NO; + self.api.expectingBackground = YES; + + OCMReject([_partialMock setSessionCompletionHandlerFromHandler:OCMArg.any]); + OCMReject([_partialMock openURLWithAuthenticationSession:OCMArg.any]); + OCMReject([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); + + [self.api openURLWithSafariViewController:self.sampleUrl + sender:self.urlOpener + fromViewController:nil + handler:self.uninvokedSuccessBlock]; + + OCMVerify( + [self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + logEntry:@"There are no valid ViewController to present SafariViewController with"] + ); + [self assertExpectingBackgroundAndPendingUrlOpener]; +} + +- (void)testWithFromViewControllerMissingTransitionCoordinator +{ + ViewControllerSpy *spy = ViewControllerSpy.makeDefaultSpy; + self.urlOpener.stubbedIsAuthenticationUrl = NO; + self.api.expectingBackground = YES; + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertTrue(success, "Should call the handler with success"); + XCTAssertNil(error, "Should not call the handler with an error"); + }; + + OCMReject([_partialMock setSessionCompletionHandlerFromHandler:OCMArg.any]); + OCMReject([_partialMock openURLWithAuthenticationSession:OCMArg.any]); + OCMReject([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); + + [self.api openURLWithSafariViewController:self.sampleUrl + sender:self.urlOpener + fromViewController:spy + handler:handler]; + + SFSafariViewController *safariVc = (SFSafariViewController *)self.api.safariViewController; + + XCTAssertNotNil(safariVc, "Should create and set a safari view controller for display"); + XCTAssertEqual( + safariVc.modalPresentationStyle, + UIModalPresentationOverFullScreen, + "Should set the correct modal presentation style" + ); + XCTAssertEqualObjects( + safariVc.delegate, + self.api, + "Should set the safari view controller delegate to the bridge api" + ); + XCTAssertEqualObjects( + spy.capturedPresentViewController, + safariVc.parentViewController, + "Should present the view controller containing the safari view controller" + ); + XCTAssertTrue(spy.capturedPresentViewControllerAnimated, "Should animate presenting the safari view controller"); + XCTAssertNil(spy.capturedPresentViewControllerCompletion, "Should not pass a completion handler to the safari vc presentation"); + [self assertExpectingBackgroundAndPendingUrlOpener]; +} + +- (void)testWithFromViewControllerWithTransitionCoordinator +{ + ViewControllerSpy *spy = ViewControllerSpy.makeDefaultSpy; + spy.stubbedTransitionCoordinator = self.transitionCoordinatorMock; + self.urlOpener.stubbedIsAuthenticationUrl = NO; + self.api.expectingBackground = YES; + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertTrue(success, "Should call the handler with success"); + XCTAssertNil(error, "Should not call the handler with an error"); + }; + + OCMReject([_partialMock setSessionCompletionHandlerFromHandler:OCMArg.any]); + OCMReject([_partialMock openURLWithAuthenticationSession:OCMArg.any]); + OCMReject([_partialMock openURL:OCMArg.any sender:OCMArg.any handler:OCMArg.any]); + + OCMStub([self.transitionCoordinatorMock animateAlongsideTransition:nil completion:[OCMArg invokeBlock]]); + + [self.api openURLWithSafariViewController:self.sampleUrl + sender:self.urlOpener + fromViewController:spy + handler:handler]; + + SFSafariViewController *safariVc = (SFSafariViewController *)self.api.safariViewController; + + XCTAssertNotNil(safariVc, "Should create and set a safari view controller for display"); + XCTAssertEqual( + safariVc.modalPresentationStyle, + UIModalPresentationOverFullScreen, + "Should set the correct modal presentation style" + ); + XCTAssertEqualObjects( + safariVc.delegate, + self.api, + "Should set the safari view controller delegate to the bridge api" + ); + XCTAssertEqualObjects( + spy.capturedPresentViewController, + safariVc.parentViewController, + "Should present the view controller containing the safari view controller" + ); + XCTAssertTrue(spy.capturedPresentViewControllerAnimated, "Should animate presenting the safari view controller"); + XCTAssertNil(spy.capturedPresentViewControllerCompletion, "Should not pass a completion handler to the safari vc presentation"); + [self assertExpectingBackgroundAndPendingUrlOpener]; +} + +// MARK: - Helpers + +- (void)assertExpectingBackgroundAndPendingUrlOpener +{ + XCTAssertFalse(self.api.expectingBackground, "Should set expecting background to false"); + XCTAssertEqualObjects(self.api.pendingUrlOpen, self.urlOpener, "Should set the pending url opener to the passed in sender"); +} + +- (NSURL *)sampleUrl +{ + return [NSURL URLWithString:@"http://example.com"]; +} + +- (FBSDKSuccessBlock)uninvokedSuccessBlock +{ + return ^(BOOL success, NSError *_Nullable error) { + XCTFail("Should not invoke the completion handler"); + }; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 3e85e3c133..8e7513ce33 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -140,6 +140,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing an `NSProcessInfo.processInfo` mock between tests @property (nullable, nonatomic, assign) id processInfoMock; +/// Used for stubbing any instance that conforms to the `UIViewControllerTransitionCoordinator` protocol +@property (nullable, nonatomic, assign) id transitionCoordinatorMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 202d3780df..135708f4e1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -105,6 +105,7 @@ - (void)setUp [self setUpSharedApplicationMock]; [self setUpLoggerClassMock]; [self setUpProcessInfoMock]; + [self setUpTransitionCoordinatorMock]; } - (void)tearDown @@ -194,6 +195,9 @@ - (void)tearDown [_processInfoMock stopMocking]; _processInfoMock = nil; + + [_transitionCoordinatorMock stopMocking]; + _transitionCoordinatorMock = nil; } - (void)setUpSettingsMock @@ -339,6 +343,12 @@ - (void)setUpProcessInfoMock OCMStub(ClassMethod([_processInfoMock processInfo])).andReturn(_processInfoMock); } +- (void)setUpTransitionCoordinatorMock +{ + self.transitionCoordinatorMock = [OCMockObject + mockForProtocol:@protocol(UIViewControllerTransitionCoordinator)]; +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeDylibResolver.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeDylibResolver.swift new file mode 100644 index 0000000000..02b5c863f5 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeDylibResolver.swift @@ -0,0 +1,26 @@ +// 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. + +@objcMembers +public class FakeDylibResolver: NSObject, FBSDKDynamicFrameworkResolving { + var stubSafariViewControllerClass: AnyClass? + + public func safariViewControllerClass() -> AnyClass? { + return stubSafariViewControllerClass + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h index 91ea2636ba..5f11eac0c9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h @@ -35,6 +35,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, copy) NSString *capturedCanOpenSourceApplication; @property (nullable, copy) NSString *capturedCanOpenAnnotation; @property BOOL stubbedCanOpenUrl; +@property BOOL stubbedIsAuthenticationUrl; + (void)resetTestEvidence; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m index cece7e745c..3d16b03bda 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m @@ -93,7 +93,7 @@ - (BOOL)canOpenURL:(NSURL *)url forApplication:(UIApplication *)application sour - (BOOL)isAuthenticationURL:(NSURL *)url { - return NO; + return _stubbedIsAuthenticationUrl; } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift index 0d56b0db5c..8054e641f7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/ViewControllerSpy.swift @@ -24,12 +24,15 @@ public class ViewControllerSpy: UIViewController { public var capturedDismissCompletion: (() -> Void)? public var dismissWasCalled = false public var capturedPresentViewController: UIViewController? - public var capturedPresentViewControllerAnimated: Bool? + public var capturedPresentViewControllerAnimated = false public var capturedPresentViewControllerCompletion: (() -> Void)? + /// Used for providing a value to return for the readonly `transitionCoordinator` property + public var stubbedTransitionCoordinator: UIViewControllerTransitionCoordinator? = nil + // Overriding with no implementation to stub the property public override var transitionCoordinator: UIViewControllerTransitionCoordinator? { - return nil + return stubbedTransitionCoordinator } private lazy var presenting = { From 908f45e65781994272b0f6d74058d07dd0b867cc Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 18 Nov 2020 21:20:19 -0800 Subject: [PATCH 125/227] FBSDKBridgeAPI Unit Tests 8/n Summary: Testing setting and invoking the bridge api session completion handler. Reviewed By: jawwad Differential Revision: D25037515 fbshipit-source-id: 2bcebc5f92b6c2c60b51b2605ab2ccb076563031 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 4 + .../Internal/BridgeAPI/FBSDKBridgeAPI.m | 2 +- .../FBSDKBridgeAPI+ApplicationOpenUrlTests.m | 12 +- ...KBridgeAPI+SessionCompletionHandlerTests.m | 173 ++++++++++++++++++ .../Internal/BridgeAPI/FBSDKBridgeAPITests.h | 1 + .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 3 + 6 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index d837a1016e..7a447b6d99 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -849,6 +849,7 @@ F44B04F0256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */; }; F44B04F1256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */; }; F44B051125645DAC0059A3A6 /* FakeDylibResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44B051025645DAC0059A3A6 /* FakeDylibResolver.swift */; }; + F44B056F256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F44B056E256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; @@ -1564,6 +1565,7 @@ F44B04A8256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBridgeAPIOpenUrlWithSafariTests.m; sourceTree = ""; }; F44B04EC256456140059A3A6 /* FBSDKDynamicFrameworkResolving.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKDynamicFrameworkResolving.h; sourceTree = ""; }; F44B051025645DAC0059A3A6 /* FakeDylibResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeDylibResolver.swift; sourceTree = ""; }; + F44B056E256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "FBSDKBridgeAPI+SessionCompletionHandlerTests.m"; sourceTree = ""; }; F468B29C24C2456F00979F8D /* FBSDKRestrictiveData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKRestrictiveData.h; sourceTree = ""; }; F468B29D24C2456F00979F8D /* FBSDKRestrictiveData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveData.m; sourceTree = ""; }; F468B2E024C25AB500979F8D /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTypeUtility.m; sourceTree = ""; }; @@ -2125,6 +2127,7 @@ F408C6BF2563091900372D61 /* FBSDKBridgeAPIOpenBridgeRequestTests.m */, F402AFE4255B4D1C00473083 /* FBSDKBridgeAPI+Testing.h */, F408C711256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift */, + F44B056E256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m */, ); path = BridgeAPI; sourceTree = ""; @@ -4202,6 +4205,7 @@ C51122A020A4BCEB0041DC94 /* FBSDKApplicationDelegateTests.m in Sources */, C51121CB20A27EF50041DC94 /* FBSDKEventBindingTests.m in Sources */, F413883E24C76F3B001BC075 /* FBSDKSafeCastTests.m in Sources */, + F44B056F256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m in Sources */, F4EB31BB2540A1B800736B67 /* SampleGraphRequestConnection.swift in Sources */, F943113424FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift in Sources */, F98D1D64251295E900276B68 /* RawAppEventsConfigurationResponseFixtures.swift in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index 2637110eb9..bc8aac0754 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -437,7 +437,7 @@ - (void)openURLWithAuthenticationSession:(NSURL *)url } } -- (void)setSessionCompletionHandlerFromHandler:(void (^)(BOOL, NSError *))handler +- (void)setSessionCompletionHandlerFromHandler:(FBSDKSuccessBlock)handler { __weak FBSDKBridgeAPI *weakSelf = self; _authenticationSessionCompletionHandler = ^(NSURL *aURL, NSError *error) { diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m index d416b74b61..64a4373d3c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+ApplicationOpenUrlTests.m @@ -843,7 +843,7 @@ - (void)verifyOpenUrlWithShouldStopPropagationOfUrl:(BOOL)shouldStopPropagationO self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *response) { XCTFail("Should not invoke the pending request completion block"); }; - id mock = [self stubHandleBridgeApiResponseAndReturn:canHandleBridgeApiResponse]; + [self stubHandleBridgeApiResponseAndReturn:canHandleBridgeApiResponse]; BOOL returnValue = [self.api application:UIApplication.sharedApplication openURL:self.sampleUrl @@ -930,18 +930,12 @@ - (void)verifyOpenUrlWithShouldStopPropagationOfUrl:(BOOL)shouldStopPropagationO expectedIsDismissingSafariVc, "Should set isDismissingSafariViewController to the expected value" ); - - [mock stopMocking]; - mock = nil; } /// Stubs `FBSDKBridgeAPI`'s `_handleBridgeAPIResponseURL:sourceApplication:` method to return the provided value -/// @returns (id) the partial mock for bridge api so that it can be canceled. -- (id)stubHandleBridgeApiResponseAndReturn:(BOOL)value +- (void)stubHandleBridgeApiResponseAndReturn:(BOOL)value { - id mock = OCMPartialMock(self.api); - OCMStub([mock _handleBridgeAPIResponseURL:OCMArg.any sourceApplication:OCMArg.any]).andReturn(value); - return mock; + OCMStub([self.partialMock _handleBridgeAPIResponseURL:OCMArg.any sourceApplication:OCMArg.any]).andReturn(value); } - (FBSDKBridgeAPIRequest *)sampleBridgeApiRequest diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m new file mode 100644 index 0000000000..4439f0b328 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m @@ -0,0 +1,173 @@ +// 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 "FBSDKBridgeAPITests.h" + +@implementation FBSDKBridgeAPITests (SessionCompletionTests) + +// MARK: - Setting Session Completion Handler + +- (void)testInvokingAuthSessionCompletionHandlerFromHandlerWithValidUrlWithoutError +{ + OCMStub( + [self.partialMock application:OCMArg.any + openURL:OCMArg.any + sourceApplication:OCMArg.any + annotation:OCMArg.any] + ); + + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertTrue(success); + XCTAssertNil(error); + }; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + [self.api setSessionCompletionHandlerFromHandler:handler]; + self.api.authenticationSessionCompletionHandler(self.sampleUrl, nil); + + OCMVerify( + [self.partialMock application:OCMArg.any + openURL:self.sampleUrl + sourceApplication:@"com.apple" + annotation:OCMArg.any] + ); + [self verifyAuthenticationPropertiesReset]; +} + +- (void)testInvokingAuthSessionCompletionHandlerFromHandlerWithInvalidUrlWithoutError +{ + NSURL *url = [NSURL URLWithString:@" "]; + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertFalse(success); + XCTAssertNil(error); + }; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + + OCMReject( + [self.partialMock application:OCMArg.any + openURL:OCMArg.any + sourceApplication:OCMArg.any + annotation:OCMArg.any] + ); + [self.api setSessionCompletionHandlerFromHandler:handler]; + self.api.authenticationSessionCompletionHandler(url, nil); + [self verifyAuthenticationPropertiesReset]; +} + +- (void)testInvokingAuthSessionCompletionHandlerFromHandlerWithoutUrlWithoutError +{ + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertFalse(success); + XCTAssertNil(error); + }; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + OCMReject( + [self.partialMock application:OCMArg.any + openURL:OCMArg.any + sourceApplication:OCMArg.any + annotation:OCMArg.any] + ); + + [self.api setSessionCompletionHandlerFromHandler:handler]; + self.api.authenticationSessionCompletionHandler(nil, nil); + [self verifyAuthenticationPropertiesReset]; +} + +- (void)testInvokingAuthSessionCompletionHandlerFromHandlerWithValidUrlWithError +{ + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertFalse(success); + XCTAssertEqualObjects(error, self.sampleError); + }; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + OCMReject( + [self.partialMock application:OCMArg.any + openURL:OCMArg.any + sourceApplication:OCMArg.any + annotation:OCMArg.any] + ); + + [self.api setSessionCompletionHandlerFromHandler:handler]; + self.api.authenticationSessionCompletionHandler(self.sampleUrl, self.sampleError); + [self verifyAuthenticationPropertiesReset]; +} + +- (void)testInvokingAuthSessionCompletionHandlerFromHandlerWithInvalidUrlWithError +{ + NSURL *url = [NSURL URLWithString:@" "]; + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertFalse(success); + XCTAssertEqualObjects(error, self.sampleError); + }; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + + OCMReject( + [self.partialMock application:OCMArg.any + openURL:OCMArg.any + sourceApplication:OCMArg.any + annotation:OCMArg.any] + ); + [self.api setSessionCompletionHandlerFromHandler:handler]; + self.api.authenticationSessionCompletionHandler(url, self.sampleError); + [self verifyAuthenticationPropertiesReset]; +} + +- (void)testInvokingAuthSessionCompletionHandlerFromHandlerWithoutUrlWithError +{ + FBSDKSuccessBlock handler = ^(BOOL success, NSError *_Nullable error) { + XCTAssertFalse(success); + XCTAssertEqualObjects(error, self.sampleError); + }; + self.api.authenticationSession = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSessionState = FBSDKAuthenticationSessionStarted; + + OCMReject( + [self.partialMock application:OCMArg.any + openURL:OCMArg.any + sourceApplication:OCMArg.any + annotation:OCMArg.any] + ); + [self.api setSessionCompletionHandlerFromHandler:handler]; + self.api.authenticationSessionCompletionHandler(nil, self.sampleError); + [self verifyAuthenticationPropertiesReset]; +} + +// MARK: - Helpers + +- (void)verifyAuthenticationPropertiesReset +{ + XCTAssertNil(self.api.authenticationSession); + XCTAssertNil(self.api.authenticationSessionCompletionHandler); + XCTAssertEqual(self.api.authenticationSessionState, FBSDKAuthenticationSessionNone); +} + +- (NSURL *)sampleUrl +{ + return [NSURL URLWithString:@"http://example.com"]; +} + +- (NSError *)sampleError +{ + return [NSError errorWithDomain:self.name code:0 userInfo:nil]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h index 22482b7520..c24283ec70 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h @@ -31,6 +31,7 @@ @interface FBSDKBridgeAPITests : FBSDKTestCase @property FBSDKBridgeAPI *api; +@property id partialMock; @property (readonly) NSURL *sampleUrl; extern NSString *const sampleSource; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m index 0df5319b41..8d328e30c0 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -26,11 +26,14 @@ - (void)setUp [FBSDKLoginManager resetTestEvidence]; _api = [FBSDKBridgeAPI new]; + _partialMock = OCMPartialMock(_api); } - (void)tearDown { _api = nil; + [_partialMock stopMocking]; + _partialMock = nil; [FBSDKLoginManager resetTestEvidence]; [super tearDown]; From 23da2e259003e2ec95696697cbec8cc2ae39d3fb Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 18 Nov 2020 21:20:19 -0800 Subject: [PATCH 126/227] FBSDKBridgeAPI Unit Tests 9/n Summary: $title Reviewed By: jawwad Differential Revision: D25060769 fbshipit-source-id: 3df98f69e9c2c538d16153733cbb62a7354eff72 --- .../BridgeAPI/FBSDKBridgeAPI+Testing.h | 6 + .../Internal/BridgeAPI/FBSDKBridgeAPITests.m | 222 +++++++++++++++++- .../Internal/Helpers/FBSDKTestCase.h | 6 + .../Internal/Helpers/FBSDKTestCase.m | 15 ++ .../Internal/Helpers/FakeLoginManager.h | 6 + .../Internal/Helpers/FakeLoginManager.m | 1 + 6 files changed, 248 insertions(+), 8 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h index 381d188d26..9a7ffbc00e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+Testing.h @@ -18,6 +18,7 @@ #import #import "FBSDKBridgeAPI.h" +#import "FBSDKContainerViewController.h" NS_ASSUME_NONNULL_BEGIN @@ -87,6 +88,11 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication; - (FBSDKSuccessBlock)_bridgeAPIRequestCompletionBlockWithRequest:(NSObject *)request completion:(FBSDKBridgeAPIResponseBlock)completionBlock; +- (void)_cancelBridgeRequest; + +- (void)safariViewControllerDidFinish:(UIViewController *)safariViewController; +- (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m index 8d328e30c0..2701a5d5bc 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.m @@ -127,8 +127,8 @@ - (void)testUpdatingShowAlertStateForDidBecomeActiveWithoutAuthSession - (void)testUpdatingShowAlertStateForDidBecomeActive { - AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; - self.api.authenticationSession = spy; + AuthenticationSessionSpy *authSessionSpy = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSession = authSessionSpy; self.api.authenticationSessionState = FBSDKAuthenticationSessionShowAlert; [self.api applicationDidBecomeActive:UIApplication.sharedApplication]; @@ -138,14 +138,14 @@ - (void)testUpdatingShowAlertStateForDidBecomeActive FBSDKAuthenticationSessionShowWebBrowser, "Becoming active when the state is 'showAlert' should set the state to be 'showWebBrowser'" ); - XCTAssertEqual(spy.cancelCallCount, 0, "Becoming active when the state is 'showAlert' should not cancel the session"); + XCTAssertEqual(authSessionSpy.cancelCallCount, 0, "Becoming active when the state is 'showAlert' should not cancel the session"); XCTAssertNotNil(self.api.authenticationSession, "Becoming active when the state is 'showAlert' should not destroy the session"); } - (void)testUpdatingCancelledBySystemStateForDidBecomeActive { - AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; - self.api.authenticationSession = spy; + AuthenticationSessionSpy *authSessionSpy = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSession = authSessionSpy; self.api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; [self.api applicationDidBecomeActive:UIApplication.sharedApplication]; @@ -159,13 +159,13 @@ - (void)testUpdatingCancelledBySystemStateForDidBecomeActive self.api.authenticationSession, "Becoming active when the state is 'canceledBySystem' should destroy the session" ); - XCTAssertEqual(spy.cancelCallCount, 1, "Becoming active when the state is 'canceledBySystem' should cancel the session"); + XCTAssertEqual(authSessionSpy.cancelCallCount, 1, "Becoming active when the state is 'canceledBySystem' should cancel the session"); } - (void)testCompletingWithCancelledBySystemStateForDidBecomeActive { - AuthenticationSessionSpy *spy = AuthenticationSessionSpy.makeDefaultSpy; - self.api.authenticationSession = spy; + AuthenticationSessionSpy *authSessionSpy = AuthenticationSessionSpy.makeDefaultSpy; + self.api.authenticationSession = authSessionSpy; self.api.authenticationSessionState = FBSDKAuthenticationSessionCanceledBySystem; self.api.authenticationSessionCompletionHandler = ^(NSURL *callbackURL, NSError *error) { XCTAssertNil(callbackURL, "A completion triggered by becoming active in a canceled state should not have a callback URL"); @@ -482,6 +482,194 @@ - (void)testRequestCompletionBlockWithHttpRequestCalledWithoutSuccess [self assertPendingPropertiesCleared]; } +// MARK: - Safari View Controller Delegate Methods + +- (void)testSafariVcDidFinishWithPendingUrlOpener +{ + FBSDKLoginManager *urlOpener = [FBSDKLoginManager new]; + self.api.pendingUrlOpen = urlOpener; + self.api.safariViewController = ViewControllerSpy.makeDefaultSpy; + + // Funny enough there's no check that the safari view controller from the delegate + // is the same instance stored in the safariViewController property + [self.api safariViewControllerDidFinish:self.api.safariViewController]; + + XCTAssertNil(self.api.pendingUrlOpen, "Should remove the reference to the pending url opener"); + XCTAssertNil( + self.api.safariViewController, + "Should remove the reference to the safari view controller when the delegate method is called" + ); + + OCMVerify([_partialMock _cancelBridgeRequest]); + XCTAssertTrue(urlOpener.openUrlWasCalled, "Should ask the opener to open a url (even though there is not one provided"); + XCTAssertNil(FBSDKLoginManager.capturedOpenUrl, "The url opener should be called with nil arguments"); + XCTAssertNil(FBSDKLoginManager.capturedSourceApplication, "The url opener should be called with nil arguments"); + XCTAssertNil(FBSDKLoginManager.capturedAnnotation, "The url opener should be called with nil arguments"); +} + +- (void)testSafariVcDidFinishWithoutPendingUrlOpener +{ + self.api.safariViewController = ViewControllerSpy.makeDefaultSpy; + + // Funny enough there's no check that the safari view controller from the delegate + // is the same instance stored in the safariViewController property + [self.api safariViewControllerDidFinish:self.api.safariViewController]; + + XCTAssertNil(self.api.pendingUrlOpen, "Should remove the reference to the pending url opener"); + XCTAssertNil( + self.api.safariViewController, + "Should remove the reference to the safari view controller when the delegate method is called" + ); + + OCMVerify([_partialMock _cancelBridgeRequest]); + XCTAssertNil(FBSDKLoginManager.capturedOpenUrl, "The url opener should not be called"); + XCTAssertNil(FBSDKLoginManager.capturedSourceApplication, "The url opener should not be called"); + XCTAssertNil(FBSDKLoginManager.capturedAnnotation, "The url opener should not be called"); +} + +// MARK: - ContainerViewController Delegate Methods + +- (void)testViewControllerDidDisappearWithSafariViewController +{ + UIViewController *viewControllerSpy = ViewControllerSpy.makeDefaultSpy; + self.api.safariViewController = viewControllerSpy; + FBSDKContainerViewController *container = [FBSDKContainerViewController new]; + + [self.api viewControllerDidDisappear:container animated:NO]; + + OCMVerify([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"**ERROR**:\n The SFSafariViewController's parent view controller was dismissed.\nThis can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view controller will not be prematurely dismissed."]); + OCMVerify([_partialMock safariViewControllerDidFinish:viewControllerSpy]); +} + +- (void)testViewControllerDidDisappearWithoutSafariViewController +{ + FBSDKContainerViewController *container = [FBSDKContainerViewController new]; + + OCMReject([self.loggerClassMock singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:OCMArg.any]); + OCMReject([_partialMock safariViewControllerDidFinish:OCMArg.any]); + + [self.api viewControllerDidDisappear:container animated:NO]; +} + +// MARK: - Bridge Response Url Handling + +- (void)testHandlingBridgeResponseWithInvalidScheme +{ + [self stubBridgeApiResponseWithUrlCreation]; + [self stubAppUrlSchemeWith:@"foo"]; + + BOOL result = [self.api _handleBridgeAPIResponseURL:self.sampleUrl sourceApplication:@""]; + + XCTAssertFalse(result, "Should not successfully handle bridge api response url with an invalid url scheme"); + [self assertPendingPropertiesCleared]; +} + +- (void)testHandlingBridgeResponseWithInvalidHost +{ + [self stubBridgeApiResponseWithUrlCreation]; + [self stubAppUrlSchemeWith:self.sampleUrl.scheme]; + + BOOL result = [self.api _handleBridgeAPIResponseURL:self.sampleUrl sourceApplication:@""]; + + XCTAssertFalse(result, "Should not successfully handle bridge api response url with an invalid url host"); + [self assertPendingPropertiesCleared]; +} + +- (void)testHandlingBridgeResponseWithMissingRequest +{ + [self stubBridgeApiResponseWithUrlCreation]; + [self stubAppUrlSchemeWith:self.validBridgeResponseUrl.scheme]; + + BOOL result = [self.api _handleBridgeAPIResponseURL:self.validBridgeResponseUrl sourceApplication:@""]; + + XCTAssertFalse(result, "Should not successfully handle bridge api response url with a missing request"); + [self assertPendingPropertiesCleared]; +} + +- (void)testHandlingBridgeResponseWithMissingCompletionBlock +{ + [self stubBridgeApiResponseWithUrlCreation]; + [self stubAppUrlSchemeWith:self.validBridgeResponseUrl.scheme]; + self.api.pendingRequest = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + + BOOL result = [self.api _handleBridgeAPIResponseURL:self.validBridgeResponseUrl sourceApplication:@""]; + + XCTAssertTrue(result, "Should successfully handle bridge api response url with a missing completion block"); + [self assertPendingPropertiesCleared]; +} + +- (void)testHandlingBridgeResponseWithBridgeResponse +{ + FBSDKBridgeAPIResponse *response = (FBSDKBridgeAPIResponse *)NSObject.new; + OCMStub( + ClassMethod( + [self.bridgeApiResponseClassMock bridgeAPIResponseWithRequest:OCMArg.any + responseURL:OCMArg.any + sourceApplication:OCMArg.any + error:[OCMArg setTo:nil]] + ) + ) + .andReturn(response); + + [self stubAppUrlSchemeWith:self.validBridgeResponseUrl.scheme]; + self.api.pendingRequest = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *_response) { + XCTAssertEqualObjects(_response, response, "Should invoke the completion with the expected bridge api response"); + }; + BOOL result = [self.api _handleBridgeAPIResponseURL:self.validBridgeResponseUrl sourceApplication:@""]; + + XCTAssertTrue(result, "Should successfully handle creation of a bridge api response"); + [self assertPendingPropertiesCleared]; +} + +- (void)testHandlingBridgeResponseWithBridgeError +{ + FBSDKBridgeAPIResponse *response = (FBSDKBridgeAPIResponse *)NSObject.new; + + // First attempt to create response populates error and returns nil response. + OCMStub( + ClassMethod( + [self.bridgeApiResponseClassMock bridgeAPIResponseWithRequest:OCMArg.any + responseURL:OCMArg.any + sourceApplication:OCMArg.any + error:[OCMArg setTo:self.sampleError]] + ) + ); + + // Second (different) attempt to create response takes error and returns response + OCMStub(ClassMethod([self.bridgeApiResponseClassMock bridgeAPIResponseWithRequest:OCMArg.any error:self.sampleError])) + .andReturn(response); + + [self stubAppUrlSchemeWith:self.validBridgeResponseUrl.scheme]; + self.api.pendingRequest = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *_response) { + XCTAssertEqualObjects(_response, response, "Should invoke the completion with the expected bridge api response"); + }; + BOOL result = [self.api _handleBridgeAPIResponseURL:self.validBridgeResponseUrl sourceApplication:@""]; + + XCTAssertTrue(result, "Should retry creation of a bridge api response if the first attempt has an error"); + [self assertPendingPropertiesCleared]; +} + +- (void)testHandlingBridgeResponseWithMissingResponseMissingError +{ + // First attempt to create response returns nil + [self stubBridgeApiResponseWithUrlCreation]; + + // Second (different) attempt to create response returns nil + OCMStub(ClassMethod([self.bridgeApiResponseClassMock bridgeAPIResponseWithRequest:OCMArg.any error:OCMArg.any])); + + [self stubAppUrlSchemeWith:self.validBridgeResponseUrl.scheme]; + self.api.pendingRequest = [FakeBridgeApiRequest requestWithURL:self.sampleUrl]; + self.api.pendingRequestCompletionBlock = ^(FBSDKBridgeAPIResponse *response) { + XCTFail("Should not invoke pending completion handler"); + }; + BOOL result = [self.api _handleBridgeAPIResponseURL:self.validBridgeResponseUrl sourceApplication:@""]; + + XCTAssertFalse(result, "Should return false when a bridge response cannot be created"); + [self assertPendingPropertiesCleared]; +} + // MARK: - Helpers - (void)assertPendingPropertiesCleared @@ -508,6 +696,19 @@ - (void)assertPendingPropertiesNotCleared ); } +/// Stubs `FBSDKBridgeAPI`'s `bridgeAPIResponseWithRequest:responseURL:sourceApplication:error:` to keep it from being called +- (void)stubBridgeApiResponseWithUrlCreation +{ + OCMStub( + ClassMethod( + [self.bridgeApiResponseClassMock bridgeAPIResponseWithRequest:OCMArg.any + responseURL:OCMArg.any + sourceApplication:OCMArg.any + error:[OCMArg setTo:nil]] + ) + ); +} + - (NSURL *)sampleUrl { return [NSURL URLWithString:@"http://example.com"]; @@ -523,6 +724,11 @@ - (NSError *)sampleError return value ? @"YES" : @"NO"; } +- (NSURL *)validBridgeResponseUrl +{ + return [NSURL URLWithString:@"http://bridge"]; +} + NSString *const sampleSource = @"com.example"; NSString *const sampleAnnotation = @"foo"; NSOperatingSystemVersion const iOS10Version = { .majorVersion = 10, .minorVersion = 0, .patchVersion = 0 }; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 8e7513ce33..53b9fd97c9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -143,6 +143,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for stubbing any instance that conforms to the `UIViewControllerTransitionCoordinator` protocol @property (nullable, nonatomic, assign) id transitionCoordinatorMock; +/// Used for sharing a `FBSDKBridgeAPIResponse` class mock between tests +@property (nullable, nonatomic, assign) id bridgeApiResponseClassMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; @@ -290,6 +293,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `NSProcessInfo`'s `isOperatingSystemVersionAtLeast:` and returns the provided value - (void)stubIsOperatingSystemVersionAtLeast:(NSOperatingSystemVersion)version with:(BOOL)returnValue; +/// Stubs `FBSDKInternalUtility`'s `appURLScheme` property to return the provided scheme +- (void)stubAppUrlSchemeWith:(nullable NSString *)scheme; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 135708f4e1..fd0105a585 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -32,6 +32,7 @@ #import "FBSDKCrashShield.h" #import "FBSDKFeatureManager.h" #import "FBSDKGraphRequestPiggybackManager.h" +#import "FBSDKInternalUtility.h" #import "FBSDKKeychainStore.h" #import "FBSDKModelManager.h" #import "FBSDKSKAdNetworkReporter.h" @@ -106,6 +107,7 @@ - (void)setUp [self setUpLoggerClassMock]; [self setUpProcessInfoMock]; [self setUpTransitionCoordinatorMock]; + [self setUpBridgeApiClassMock]; } - (void)tearDown @@ -198,6 +200,9 @@ - (void)tearDown [_transitionCoordinatorMock stopMocking]; _transitionCoordinatorMock = nil; + + [_bridgeApiResponseClassMock stopMocking]; + _bridgeApiResponseClassMock = nil; } - (void)setUpSettingsMock @@ -349,6 +354,11 @@ - (void)setUpTransitionCoordinatorMock mockForProtocol:@protocol(UIViewControllerTransitionCoordinator)]; } +- (void)setUpBridgeApiClassMock +{ + _bridgeApiResponseClassMock = OCMClassMock(FBSDKBridgeAPIResponse.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID @@ -587,6 +597,11 @@ - (void)stubIsOperatingSystemVersionAtLeast:(NSOperatingSystemVersion)version wi OCMStub([self.processInfoMock isOperatingSystemAtLeastVersion:version]).andReturn(returnValue); } +- (void)stubAppUrlSchemeWith:(nullable NSString *)scheme +{ + OCMStub([self.internalUtilityClassMock appURLScheme]).andReturn(scheme); +} + // MARK: - Helpers - (void)resetCachedSettings diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h index 5f11eac0c9..8c303d8223 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.h @@ -27,10 +27,16 @@ NS_ASSUME_NONNULL_BEGIN /// `FBSDKLoginManager`. @interface FBSDKLoginManager : NSObject +// The reason some of these properties are static is that there are cases where we dynamically +// check for the existence of the login manager at runtime. Since we don't have a handle to the +// instance we can make sure the properties are set on the type so that we can examine them there +// ultimately this is a pattern we need to get away from but this allows it to be tested while +// we refactor. @property (class, nullable, copy) NSURL *capturedOpenUrl; @property (class, nullable, copy) NSString *capturedSourceApplication; @property (class, nullable, copy) NSString *capturedAnnotation; @property (class) BOOL stubbedOpenUrlSuccess; +@property BOOL openUrlWasCalled; @property (nullable, copy) NSURL *capturedCanOpenUrl; @property (nullable, copy) NSString *capturedCanOpenSourceApplication; @property (nullable, copy) NSString *capturedCanOpenAnnotation; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m index 3d16b03bda..f08130a984 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeLoginManager.m @@ -73,6 +73,7 @@ - (BOOL)shouldStopPropagationOfURL:(NSURL *)url - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { + _openUrlWasCalled = YES; FBSDKLoginManager.capturedOpenUrl = url; FBSDKLoginManager.capturedSourceApplication = sourceApplication; FBSDKLoginManager.capturedAnnotation = annotation; From 53031844beef9d8900b359fcdf7e3272fdb4549a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 18 Nov 2020 21:20:19 -0800 Subject: [PATCH 127/227] FBSDKRestrictiveData Unit Tests Summary: Adds back missing RestrictiveData tests (they were removed from xcode project for some reason). Revisits RestrictiveDataFilterTests to conform them to FBSDKTestCase and remove their mocks in favor of the shared set. Reviewed By: jawwad Differential Revision: D25072139 fbshipit-source-id: 3a574942a7b97ea6cf2a84defa77f09e24ca4484 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 5 ++- .../FBSDKRestrictiveDataFilterTests.m | 37 +++++++++++-------- .../Integrity/FBSDKRestrictiveDataTests.m | 3 +- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 7a447b6d99..d117fb7d58 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -956,6 +956,7 @@ F4BF22AA241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; + F4D80B582565D6B3008CCAF0 /* FBSDKRestrictiveDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */; }; F4D8D8DC2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DD2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; @@ -1611,6 +1612,7 @@ F4BF2292241954B400BFB494 /* FBSDKMonitorStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStoreTests.m; sourceTree = ""; }; F4BF22A1241954D800BFB494 /* FBSDKMonitorStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorStore.h; sourceTree = ""; }; F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStore.m; sourceTree = ""; }; + F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataTests.m; sourceTree = ""; }; F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorNetworker.h; sourceTree = ""; }; F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworker.m; sourceTree = ""; }; F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworkerTests.m; sourceTree = ""; }; @@ -1773,6 +1775,7 @@ 5D497700244A3E5700BD45C6 /* Integrity */ = { isa = PBXGroup; children = ( + F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */, C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */, 5D497701244A3E6A00BD45C6 /* FBSDKIntegrityTests.m */, ); @@ -4168,7 +4171,6 @@ F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */, F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift in Sources */, - F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.m in Sources */, F44B051125645DAC0059A3A6 /* FakeDylibResolver.swift in Sources */, 45540DB125271A88008E853E /* FBSDKAppLinkResolverRequestBuilderTests.m in Sources */, F408C712256320F300372D61 /* FBSDKBridgeAPIRequestTests.swift in Sources */, @@ -4191,6 +4193,7 @@ F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, F402B062255C645600473083 /* FakeLoginManager.m in Sources */, + F4D80B582565D6B3008CCAF0 /* FBSDKRestrictiveDataTests.m in Sources */, F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */, 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m index 2788e21c63..ccd8495d81 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m @@ -24,13 +24,19 @@ #import "FBSDKInternalUtility.h" #import "FBSDKRestrictiveDataFilterManager.h" #import "FBSDKServerConfiguration.h" +#import "FBSDKServerConfigurationFixtures.h" #import "FBSDKServerConfigurationManager.h" +#import "FBSDKTestCase.h" typedef void (^FBSDKSKAdNetworkReporterBlock)(void); @interface FBSDKSKAdNetworkReporter (Testing) + (void)_loadConfigurationWithBlock:(FBSDKSKAdNetworkReporterBlock)block; @end +@interface FBSDKAppEvents (Testing) +@property (nonatomic, assign) BOOL disableTimer; +@end + @interface FBSDKRestrictiveDataFilterManager () + (NSString *)_getMatchedDataTypeWithEventName:(NSString *)eventName @@ -38,7 +44,7 @@ + (NSString *)_getMatchedDataTypeWithEventName:(NSString *)eventName @end -@interface FBSDKRestrictiveDataFilterTests : XCTestCase +@interface FBSDKRestrictiveDataFilterTests : FBSDKTestCase @end @implementation FBSDKRestrictiveDataFilterTests @@ -61,13 +67,16 @@ - (void)setUp } }]; - id mockServerConfiguration = OCMClassMock([FBSDKServerConfiguration class]); - OCMStub([mockServerConfiguration restrictiveParams]).andReturn(params); - id mockServerConfigurationManager = OCMClassMock([FBSDKServerConfigurationManager class]); - OCMStub([mockServerConfigurationManager cachedServerConfiguration]).andReturn(mockServerConfiguration); + FBSDKServerConfiguration *config = [FBSDKServerConfigurationFixtures configWithDictionary:@{ @"restrictiveParams" : params }]; + [self stubCachedServerConfigurationWithServerConfiguration:config]; + [self stubServerConfigurationFetchingWithConfiguration:config + error:nil]; + [self stubAllocatingGraphRequestConnection]; + [self stubLoadingAdNetworkReporterConfiguration]; - id mockAdNetworkReporter = OCMClassMock(FBSDKSKAdNetworkReporter.class); - OCMStub([mockAdNetworkReporter _loadConfigurationWithBlock:OCMArg.any]); + FBSDKAppEvents *appEvents = FBSDKAppEvents.singleton; + appEvents.disableTimer = YES; + [self stubAppEventsSingletonWith:appEvents]; [FBSDKRestrictiveDataFilterManager enable]; } @@ -75,31 +84,27 @@ - (void)setUp - (void)testFilterByParams { NSString *testEventName = @"restrictive_event_name"; - id mockAppStates = [OCMockObject niceMockForClass:[FBSDKAppEventsState class]]; - OCMStub([mockAppStates alloc]).andReturn(mockAppStates); - OCMStub([mockAppStates initWithToken:[OCMArg any] appID:[OCMArg any]]).andReturn(mockAppStates); - id mockAppEventsUtility = [OCMockObject niceMockForClass:[FBSDKAppEventsUtility class]]; - OCMStub([mockAppEventsUtility shouldDropAppEvent]).andReturn(NO); + OCMStub([self.appEventsUtilityClassMock shouldDropAppEvent]).andReturn(NO); // filtered by param key - [[mockAppStates expect] addEvent:[OCMArg checkWithBlock:^(id value) { + [[self.appEventStatesMock expect] addEvent:[OCMArg checkWithBlock:^(id value) { XCTAssertEqualObjects(value[@"_eventName"], testEventName); XCTAssertNil(value[@"dob"]); XCTAssertEqualObjects(value[@"_restrictedParams"], @"{\"dob\":\"4\"}"); return YES; }] isImplicit:NO]; [FBSDKAppEvents logEvent:testEventName parameters:@{@"dob" : @"06-29-2019"}]; - [mockAppStates verify]; + [self.appEventStatesMock verify]; // should not be filtered - [[mockAppStates expect] addEvent:[OCMArg checkWithBlock:^(id value) { + [[self.appEventStatesMock expect] addEvent:[OCMArg checkWithBlock:^(id value) { XCTAssertEqualObjects(value[@"_eventName"], testEventName); XCTAssertEqualObjects(value[@"test_key"], @66666); XCTAssertNil(value[@"_restrictedParams"]); return YES; }] isImplicit:NO]; [FBSDKAppEvents logEvent:testEventName parameters:@{@"test_key" : @66666}]; - [mockAppStates verify]; + [self.appEventStatesMock verify]; } - (void)testGetMatchedDataTypeByParam diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m index ba30b37052..4156e3b59a 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataTests.m @@ -20,8 +20,9 @@ #import "FBSDKInternalUtility.h" #import "FBSDKRestrictiveData.h" +#import "FBSDKTestCase.h" -@interface FBSDKRestrictiveDataTests : XCTestCase +@interface FBSDKRestrictiveDataTests : FBSDKTestCase @end From f2d3e6590f9fc04f1d7f5a9ec1c39e94f016fdbd Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 18 Nov 2020 21:20:19 -0800 Subject: [PATCH 128/227] Adding FBSDKInstrumentManagerTests Summary: $title Reviewed By: jawwad Differential Revision: D25073536 fbshipit-source-id: 0fd4db0d1740357d83e9b23c950ceb0ee6cecc05 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 4 + .../Internal/Helpers/FBSDKTestCase.h | 6 ++ .../Internal/Helpers/FBSDKTestCase.m | 20 ++++ .../Instrument/FBSDKInstrumentManagerTests.m | 97 +++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKInstrumentManagerTests.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index d117fb7d58..5201d356eb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -957,6 +957,7 @@ F4BF22AB241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4D80B582565D6B3008CCAF0 /* FBSDKRestrictiveDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */; }; + F4D80B812565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D80B802565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m */; }; F4D8D8DC2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DD2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; @@ -1613,6 +1614,7 @@ F4BF22A1241954D800BFB494 /* FBSDKMonitorStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorStore.h; sourceTree = ""; }; F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStore.m; sourceTree = ""; }; F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataTests.m; sourceTree = ""; }; + F4D80B802565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKInstrumentManagerTests.m; sourceTree = ""; }; F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorNetworker.h; sourceTree = ""; }; F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworker.m; sourceTree = ""; }; F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworkerTests.m; sourceTree = ""; }; @@ -1817,6 +1819,7 @@ children = ( 5DB612A723593AB600150851 /* FBSDKCrashShieldTests.m */, 5DAB01F023A1831A005495FB /* FBSDKCrashObserverTests.m */, + F4D80B802565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m */, ); path = Instrument; sourceTree = ""; @@ -4196,6 +4199,7 @@ F4D80B582565D6B3008CCAF0 /* FBSDKRestrictiveDataTests.m in Sources */, F4EB33CE2542323500736B67 /* SampleRawRemotePermissions.swift in Sources */, 5DBB0447227FEF700009E0A6 /* FBSDKBasicUtilityTests.m in Sources */, + F4D80B812565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m in Sources */, F952EA4F2339432100B20652 /* FBSDKMetadataIndexerTests.m in Sources */, 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, F44B04B7256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 53b9fd97c9..2862e21d94 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -146,6 +146,12 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a `FBSDKBridgeAPIResponse` class mock between tests @property (nullable, nonatomic, assign) id bridgeApiResponseClassMock; +/// Used for sharing a `FBSDKCrashObserver` class mock between tests +@property (nullable, nonatomic, assign) id crashObserverClassMock; + +/// Used for sharing a `FBSDKErrorReport` class mock between tests +@property (nullable, nonatomic, assign) id errorReportClassMock; + /// Stubs `FBSDKSettings.appID` and return the provided value - (void)stubAppID:(nullable NSString *)appID; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index fd0105a585..4d9d83609d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -29,7 +29,9 @@ #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTestUtility.h" +#import "FBSDKCrashObserver.h" #import "FBSDKCrashShield.h" +#import "FBSDKErrorReport.h" #import "FBSDKFeatureManager.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKInternalUtility.h" @@ -108,6 +110,8 @@ - (void)setUp [self setUpProcessInfoMock]; [self setUpTransitionCoordinatorMock]; [self setUpBridgeApiClassMock]; + [self setUpCrashObserverClassMock]; + [self setUpErrorReportClassMock]; } - (void)tearDown @@ -203,6 +207,12 @@ - (void)tearDown [_bridgeApiResponseClassMock stopMocking]; _bridgeApiResponseClassMock = nil; + + [_crashObserverClassMock stopMocking]; + _crashObserverClassMock = nil; + + [_errorReportClassMock stopMocking]; + _errorReportClassMock = nil; } - (void)setUpSettingsMock @@ -359,6 +369,16 @@ - (void)setUpBridgeApiClassMock _bridgeApiResponseClassMock = OCMClassMock(FBSDKBridgeAPIResponse.class); } +- (void)setUpCrashObserverClassMock +{ + _crashObserverClassMock = OCMClassMock(FBSDKCrashObserver.class); +} + +- (void)setUpErrorReportClassMock +{ + _errorReportClassMock = OCMClassMock(FBSDKErrorReport.class); +} + #pragma mark - Public Methods - (void)stubAppID:(NSString *)appID diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKInstrumentManagerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKInstrumentManagerTests.m new file mode 100644 index 0000000000..8535708ee1 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKInstrumentManagerTests.m @@ -0,0 +1,97 @@ +// 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 "FBSDKCoreKitTestUtility.h" +#import "FBSDKFeatureManager.h" +#import "FBSDKInstrumentManager.h" +#import "FBSDKTestCase.h" + +@interface FBSDKInstrumentManagerTests : FBSDKTestCase +@end + +@implementation FBSDKInstrumentManagerTests + +- (void)testEnablingWithAutoLogEventsEnabledFeaturesEnabled +{ + [self stubIsAutoLogAppEventsEnabled:YES]; + [self stubFeatureChecksCompleteWith:YES]; + + OCMStub(ClassMethod([self.crashObserverClassMock enable])); + OCMStub(ClassMethod([self.errorReportClassMock enable])); + + [FBSDKInstrumentManager enable]; + + OCMVerify([self.crashObserverClassMock enable]); + OCMVerify([self.errorReportClassMock enable]); +} + +- (void)testEnablingWithAutoLogEventsEnabledFeaturesDisabled +{ + [self stubIsAutoLogAppEventsEnabled:YES]; + [self stubFeatureChecksCompleteWith:NO]; + [self rejectFeatureEnabling]; + + [FBSDKInstrumentManager enable]; +} + +- (void)testEnablingWithAutoLogEventsDisabledFeaturesEnabled +{ + [self stubIsAutoLogAppEventsEnabled:NO]; + [self stubFeatureChecksCompleteWith:YES]; + [self rejectFeatureEnabling]; + + [FBSDKInstrumentManager enable]; +} + +- (void)testEnablingWithAutoLogEventsDisabledFeaturesDisabled +{ + [self stubIsAutoLogAppEventsEnabled:YES]; + [self stubFeatureChecksCompleteWith:NO]; + [self rejectFeatureEnabling]; + + [FBSDKInstrumentManager enable]; +} + +// MARK: - Helpers + +- (void)stubFeatureChecksCompleteWith:(BOOL)value +{ + OCMStub( + ClassMethod( + [self.featureManagerClassMock checkFeature:FBSDKFeatureCrashReport + completionBlock:([OCMArg invokeBlockWithArgs:@(value), nil])] + ) + ); + OCMStub( + ClassMethod( + [self.featureManagerClassMock checkFeature:FBSDKFeatureErrorReport + completionBlock:([OCMArg invokeBlockWithArgs:@(value), nil])] + ) + ); +} + +- (void)rejectFeatureEnabling +{ + OCMReject([self.crashObserverClassMock enable]); + OCMReject([self.errorReportClassMock enable]); +} + +@end From aea685e82975a54d95aad5547c49ea48ee33dc1a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 19 Nov 2020 14:20:29 -0800 Subject: [PATCH 129/227] Degender Silhouettes and improve `FBSDKIcon` API Summary: * Renames `FBSDKMaleSilhouetteIcon` to `FBSDKHumanSilhouetteIcon` * Deprecates color initializer in favor of passing the color upon image creation * Improves Swift names to be more descriptive * Adds unit tests and test xcasset catalog Reviewed By: jawwad Differential Revision: D25095373 fbshipit-source-id: a172b7ff06335ffa8820fed62b069ba714a95fb2 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 40 +++-- .../FBSDKCoreKit/FBSDKProfilePictureView.m | 5 +- .../Internal/Device/FBSDKDeviceDialogView.m | 11 +- .../Device/FBSDKSmartDeviceDialogView.m | 11 +- .../Internal/FBSDKCoreKit+Internal.h | 4 +- ...uetteIcon.h => FBSDKHumanSilhouetteIcon.h} | 4 +- ...uetteIcon.m => FBSDKHumanSilhouetteIcon.m} | 4 +- .../FBSDKCoreKit/Internal/UI/FBSDKIcon.h | 13 +- .../FBSDKCoreKit/Internal/UI/FBSDKIcon.m | 23 ++- .../Internal/UI/FBSDKDrawableTests.swift | 139 ++++++++++++++++++ .../TestAssets.xcassets/Contents.json | 6 + .../Contents.json | 21 +++ .../customColorSilhouette.png | Bin 0 -> 4215 bytes .../redLogo.imageset/Contents.json | 21 +++ .../redLogo.imageset/redLogo.png | Bin 0 -> 4925 bytes .../redSilhouette.imageset/Contents.json | 21 +++ .../redSilhouette.imageset/redSilhouette.png | Bin 0 -> 3687 bytes .../whiteSilhouette.imageset/Contents.json | 21 +++ .../whiteSilhouette.png | Bin 0 -> 3600 bytes 19 files changed, 303 insertions(+), 41 deletions(-) rename FBSDKCoreKit/FBSDKCoreKit/Internal/UI/{FBSDKMaleSilhouetteIcon.h => FBSDKHumanSilhouetteIcon.h} (93%) rename FBSDKCoreKit/FBSDKCoreKit/Internal/UI/{FBSDKMaleSilhouetteIcon.m => FBSDKHumanSilhouetteIcon.m} (97%) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/Contents.json create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/Contents.json create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/customColorSilhouette.png create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/Contents.json create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/redLogo.png create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redSilhouette.imageset/Contents.json create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redSilhouette.imageset/redSilhouette.png create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/whiteSilhouette.imageset/Contents.json create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/whiteSilhouette.imageset/whiteSilhouette.png diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 5201d356eb..8003781260 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -352,7 +352,7 @@ 81B71D411D19C87400933E93 /* FBSDKErrorConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D3AF44F1A9EA4BE00EEF724 /* FBSDKErrorConfiguration.m */; }; 81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DE1F3CC1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.m */; }; 81B71D431D19C87400933E93 /* FBSDKServerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 89830F2E1A7805E100226ABB /* FBSDKServerConfiguration.m */; }; - 81B71D441D19C87400933E93 /* FBSDKMaleSilhouetteIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3D011A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m */; }; + 81B71D441D19C87400933E93 /* FBSDKHumanSilhouetteIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3D011A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.m */; }; 81B71D461D19C87400933E93 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9894BFFA1B73D8B300FBA6DB /* SafariServices.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 81B71D481D19C87400933E93 /* FBSDKAppLinkUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E30916C1AA907BD004E91D5 /* FBSDKAppLinkUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81B71D491D19C87400933E93 /* FBSDKAppLinkResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E5557361A8D833100344F86 /* FBSDKAppLinkResolver.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -375,7 +375,7 @@ 81B71D5C1D19C87400933E93 /* FBSDKContainerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D195CC61B9FE2E000BD6BEC /* FBSDKContainerViewController.h */; }; 81B71D5D1D19C87400933E93 /* FBSDKAppEventsState.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0BC1641A8E892C00BE8BA4 /* FBSDKAppEventsState.h */; }; 81B71D5E1D19C87400933E93 /* FBSDKBridgeAPIProtocolType.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0AEC1A6F1DAB009137EF /* FBSDKBridgeAPIProtocolType.h */; }; - 81B71D5F1D19C87400933E93 /* FBSDKMaleSilhouetteIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 899C3D001A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h */; }; + 81B71D5F1D19C87400933E93 /* FBSDKHumanSilhouetteIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 899C3D001A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.h */; }; 81B71D601D19C87400933E93 /* FBSDKMutableCopying.h in Headers */ = {isa = PBXBuildFile; fileRef = 890414871A64893100617215 /* FBSDKMutableCopying.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81B71D611D19C87400933E93 /* FBSDKErrorRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D3AF4871A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.h */; }; 81B71D621D19C87400933E93 /* FBSDKPaymentObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0BC14A1A8D236200BE8BA4 /* FBSDKPaymentObserver.h */; }; @@ -485,8 +485,8 @@ 89830F341A78060A00226ABB /* FBSDKDialogConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 89830F321A78060A00226ABB /* FBSDKDialogConfiguration.m */; }; 899C3CF81A8BF73A00EA8658 /* FBSDKProfilePictureView.h in Headers */ = {isa = PBXBuildFile; fileRef = 899C3CF61A8BF73A00EA8658 /* FBSDKProfilePictureView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 899C3CF91A8BF73A00EA8658 /* FBSDKProfilePictureView.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3CF71A8BF73A00EA8658 /* FBSDKProfilePictureView.m */; }; - 899C3D021A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 899C3D001A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h */; }; - 899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3D011A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m */; }; + 899C3D021A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 899C3D001A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.h */; }; + 899C3D031A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 899C3D011A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.m */; }; 89C8B1991A8D7A15009B07F5 /* FBSDKUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 89C8B1971A8D7A15009B07F5 /* FBSDKUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 89C8B19A1A8D7A15009B07F5 /* FBSDKUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */; }; 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.swift */; }; @@ -958,6 +958,8 @@ F4BF22AC241954D800BFB494 /* FBSDKMonitorStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */; }; F4D80B582565D6B3008CCAF0 /* FBSDKRestrictiveDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */; }; F4D80B812565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D80B802565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m */; }; + F4D80C082566D469008CCAF0 /* FBSDKDrawableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4D80C072566D469008CCAF0 /* FBSDKDrawableTests.swift */; }; + F4D80C402566D856008CCAF0 /* TestAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4D80C3F2566D856008CCAF0 /* TestAssets.xcassets */; }; F4D8D8DC2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DD2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; F4D8D8DE2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */ = {isa = PBXBuildFile; fileRef = F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */; }; @@ -1372,8 +1374,8 @@ 89830F321A78060A00226ABB /* FBSDKDialogConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKDialogConfiguration.m; sourceTree = ""; }; 899C3CF61A8BF73A00EA8658 /* FBSDKProfilePictureView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKProfilePictureView.h; sourceTree = ""; }; 899C3CF71A8BF73A00EA8658 /* FBSDKProfilePictureView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKProfilePictureView.m; sourceTree = ""; }; - 899C3D001A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKMaleSilhouetteIcon.h; sourceTree = ""; }; - 899C3D011A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMaleSilhouetteIcon.m; sourceTree = ""; }; + 899C3D001A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKHumanSilhouetteIcon.h; sourceTree = ""; }; + 899C3D011A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKHumanSilhouetteIcon.m; sourceTree = ""; }; 89C8B1971A8D7A15009B07F5 /* FBSDKUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKUtility.h; sourceTree = ""; }; 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKUtility.m; sourceTree = ""; }; 89C8B19B1A8D7A27009B07F5 /* FBSDKUtilityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBSDKUtilityTests.swift; sourceTree = ""; }; @@ -1615,6 +1617,8 @@ F4BF22A2241954D800BFB494 /* FBSDKMonitorStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorStore.m; sourceTree = ""; }; F4D80B572565D6B2008CCAF0 /* FBSDKRestrictiveDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataTests.m; sourceTree = ""; }; F4D80B802565E1C2008CCAF0 /* FBSDKInstrumentManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKInstrumentManagerTests.m; sourceTree = ""; }; + F4D80C072566D469008CCAF0 /* FBSDKDrawableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKDrawableTests.swift; sourceTree = ""; }; + F4D80C3F2566D856008CCAF0 /* TestAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = TestAssets.xcassets; sourceTree = ""; }; F4D8D8DA2422887600C28384 /* FBSDKMonitorNetworker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKMonitorNetworker.h; sourceTree = ""; }; F4D8D8DB2422887600C28384 /* FBSDKMonitorNetworker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworker.m; sourceTree = ""; }; F4D8D8F9242293ED00C28384 /* FBSDKMonitorNetworkerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKMonitorNetworkerTests.m; sourceTree = ""; }; @@ -2069,6 +2073,7 @@ F420048C2416BD6D00AD7006 /* Monitoring */, F4EB317D2540952B00736B67 /* Network */, F4E50151243648A100C99262 /* ServerConfiguration */, + F4D80C242566D471008CCAF0 /* UI */, ); path = Internal; sourceTree = ""; @@ -2203,8 +2208,8 @@ 891687D11AB33CA200F55364 /* FBSDKIcon.m */, 893F44931A6444DF001DB0B6 /* FBSDKLogo.h */, 893F44941A6444DF001DB0B6 /* FBSDKLogo.m */, - 899C3D001A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h */, - 899C3D011A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m */, + 899C3D001A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.h */, + 899C3D011A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.m */, 89688B451AA62E3B00A98519 /* FBSDKUIUtility.h */, 89688B601AA64C5E00A98519 /* FBSDKViewImpressionTracker.h */, 89688B611AA64C5E00A98519 /* FBSDKViewImpressionTracker.m */, @@ -2364,6 +2369,7 @@ children = ( 5C59531F25548690000D0A3C /* FBSDKCoreKitTests-Bridging-Header.h */, 9D2697581A5DF40700143BFC /* Info.plist */, + F4D80C3F2566D856008CCAF0 /* TestAssets.xcassets */, ); name = "Supporting Files"; sourceTree = ""; @@ -2715,6 +2721,14 @@ path = Helpers; sourceTree = ""; }; + F4D80C242566D471008CCAF0 /* UI */ = { + isa = PBXGroup; + children = ( + F4D80C072566D469008CCAF0 /* FBSDKDrawableTests.swift */, + ); + path = UI; + sourceTree = ""; + }; F4E50151243648A100C99262 /* ServerConfiguration */ = { isa = PBXGroup; children = ( @@ -2928,7 +2942,7 @@ 81B71D5C1D19C87400933E93 /* FBSDKContainerViewController.h in Headers */, 81B71D5D1D19C87400933E93 /* FBSDKAppEventsState.h in Headers */, 81B71D5E1D19C87400933E93 /* FBSDKBridgeAPIProtocolType.h in Headers */, - 81B71D5F1D19C87400933E93 /* FBSDKMaleSilhouetteIcon.h in Headers */, + 81B71D5F1D19C87400933E93 /* FBSDKHumanSilhouetteIcon.h in Headers */, C5696FA4209CCEB4009C931F /* FBSDKSwizzler.h in Headers */, C5188E342231C4B500F4D8BC /* FBSDKBridgeAPI.h in Headers */, F42004702416BCC700AD7006 /* FBSDKMonitorEntry.h in Headers */, @@ -3069,7 +3083,7 @@ 9D195CC81B9FE2E000BD6BEC /* FBSDKContainerViewController.h in Headers */, 9D0BC1661A8E892C00BE8BA4 /* FBSDKAppEventsState.h in Headers */, 894C0AED1A6F1DAB009137EF /* FBSDKBridgeAPIProtocolType.h in Headers */, - 899C3D021A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.h in Headers */, + 899C3D021A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.h in Headers */, 890414891A64893100617215 /* FBSDKMutableCopying.h in Headers */, C5696FA3209CCEB4009C931F /* FBSDKSwizzler.h in Headers */, 9D3AF4891A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.h in Headers */, @@ -3669,6 +3683,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F4D80C402566D856008CCAF0 /* TestAssets.xcassets in Resources */, BF5D97E72432D8650096D7AA /* FBSDKTextClassifyRules.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3990,7 +4005,7 @@ 81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 81B71D431D19C87400933E93 /* FBSDKServerConfiguration.m in Sources */, F952EA492339405D00B20652 /* FBSDKMetadataIndexer.m in Sources */, - 81B71D441D19C87400933E93 /* FBSDKMaleSilhouetteIcon.m in Sources */, + 81B71D441D19C87400933E93 /* FBSDKHumanSilhouetteIcon.m in Sources */, C5C7B74F22D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, C554DB0B2304D11200A32E8B /* FBSDKErrorReport.m in Sources */, F46FA63C24533F450060C902 /* AccessToken.swift in Sources */, @@ -4120,7 +4135,7 @@ F4F98C5324CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, F952EA472339403900B20652 /* FBSDKMetadataIndexer.m in Sources */, FD8E438122FBF8F1008B6DD3 /* FBSDKErrorReport.m in Sources */, - 899C3D031A8C1ED200EA8658 /* FBSDKMaleSilhouetteIcon.m in Sources */, + 899C3D031A8C1ED200EA8658 /* FBSDKHumanSilhouetteIcon.m in Sources */, C5C7B74E22D84F64004A5A0C /* FBSDKFeatureManager.m in Sources */, F46FA62D24533F450060C902 /* AccessToken.swift in Sources */, ); @@ -4141,6 +4156,7 @@ 7E55573C1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m in Sources */, 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */, F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */, + F4D80C082566D469008CCAF0 /* FBSDKDrawableTests.swift in Sources */, 9D18A8DB1A95405A00A41042 /* FBSDKAppEventsStateTests.m in Sources */, F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.swift in Sources */, F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m index f47ec77225..9418b87975 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m @@ -24,8 +24,8 @@ #import "FBSDKProfilePictureView+Internal.h" #import "FBSDKAccessToken.h" + #import "FBSDKHumanSilhouetteIcon.h" #import "FBSDKInternalUtility.h" - #import "FBSDKMaleSilhouetteIcon.h" #import "FBSDKMath.h" #import "FBSDKProfile+Internal.h" #import "FBSDKUtility.h" @@ -369,7 +369,8 @@ - (void)_setPlaceholderImage _hasProfileImage = NO; dispatch_async(dispatch_get_main_queue(), ^{ - self->_imageView.image = [[[FBSDKMaleSilhouetteIcon alloc] initWithColor:fillColor] imageWithSize:self->_imageView.bounds.size]; + self->_imageView.image = [[FBSDKHumanSilhouetteIcon new] imageWithSize:self->_imageView.bounds.size + color:fillColor]; }); } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m index 555716a04a..ff18d8faa0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKDeviceDialogView.m @@ -63,6 +63,11 @@ - (void)setConfirmationCode:(NSString *)confirmationCode #pragma mark - Helpers +- (UIColor *)logoColor +{ + return [UIColor colorWithRed:66.0 / 255.0 green:103.0 / 255.0 blue:178.0 / 255.0 alpha:1]; +} + - (void)buildView { // This is a "static" view with just a cancel button so add all the constraints here @@ -105,8 +110,8 @@ - (void)buildView // build the logo. CGSize imageSize = CGSizeMake(kLogoSize, kLogoSize); - FBSDKLogo *logoHelper = [[FBSDKLogo alloc] initWithColor:[UIColor colorWithRed:66.0 / 255.0 green:103.0 / 255.0 blue:178.0 / 255.0 alpha:1]]; - UIImage *image = [logoHelper imageWithSize:imageSize]; + FBSDKLogo *logoHelper = [FBSDKLogo new]; + UIImage *image = [logoHelper imageWithSize:imageSize color:self.logoColor]; image = [image resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; imageView.translatesAutoresizingMaskIntoConstraints = NO; @@ -129,7 +134,7 @@ - (void)buildView // build the confirmation code (which replaces the spinner when the code is available). _confirmationCodeLabel = [[UILabel alloc] init]; _confirmationCodeLabel.translatesAutoresizingMaskIntoConstraints = NO; - _confirmationCodeLabel.textColor = logoHelper.color; + _confirmationCodeLabel.textColor = self.logoColor; _confirmationCodeLabel.font = [UIFont systemFontOfSize:kConfirmationCodeFontSize weight:UIFontWeightLight]; _confirmationCodeLabel.textAlignment = NSTextAlignmentCenter; [_confirmationCodeLabel sizeToFit]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m index 5733514279..1f7ee28bd6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Device/FBSDKSmartDeviceDialogView.m @@ -67,6 +67,11 @@ - (void)buildView #pragma mark - Helpers +- (UIColor *)_logoColor +{ + return [UIColor colorWithRed:66.0 / 255.0 green:103.0 / 255.0 blue:178.0 / 255.0 alpha:1]; +} + - (void)_buildView { // This is a "static" view with just a cancel button so add all the constraints here @@ -107,8 +112,8 @@ - (void)_buildView // build the logo. CGSize imageSize = CGSizeMake(kLogoSize, kLogoSize); - FBSDKLogo *logoHelper = [[FBSDKLogo alloc] initWithColor:[UIColor colorWithRed:66.0 / 255.0 green:103.0 / 255.0 blue:178.0 / 255.0 alpha:1]]; - UIImage *image = [logoHelper imageWithSize:imageSize]; + FBSDKLogo *logoHelper = [FBSDKLogo new]; + UIImage *image = [logoHelper imageWithSize:imageSize color:self._logoColor]; image = [image resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; imageView.translatesAutoresizingMaskIntoConstraints = NO; @@ -131,7 +136,7 @@ - (void)_buildView // build the confirmation code (which replaces the spinner when the code is available). _confirmationCodeLabel = [[UILabel alloc] init]; _confirmationCodeLabel.translatesAutoresizingMaskIntoConstraints = NO; - _confirmationCodeLabel.textColor = logoHelper.color; + _confirmationCodeLabel.textColor = self._logoColor; _confirmationCodeLabel.font = [UIFont systemFontOfSize:kConfirmationCodeFontSize weight:UIFontWeightLight]; _confirmationCodeLabel.textAlignment = NSTextAlignmentCenter; [_confirmationCodeLabel sizeToFit]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 92cc9bf72b..9c1672cc60 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -43,7 +43,7 @@ #import "FBSDKColor.h" #import "FBSDKContainerViewController.h" #import "FBSDKCrypto.h" - #import "FBSDKMaleSilhouetteIcon.h" + #import "FBSDKHumanSilhouetteIcon.h" #import "FBSDKMetadataIndexer.h" #import "FBSDKMonotonicTime.h" #import "FBSDKSKAdNetworkReporter.h" @@ -122,7 +122,7 @@ #import "FBSDKMonotonicTime.h" #import "UI/FBSDKCloseIcon.h" #import "UI/FBSDKColor.h" - #import "UI/FBSDKMaleSilhouetteIcon.h" + #import "UI/FBSDKHumanSilhouetteIcon.h" #import "UI/FBSDKUIUtility.h" #import "UI/FBSDKViewImpressionTracker.h" #import "WebDialog/FBSDKWebDialog.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKHumanSilhouetteIcon.h similarity index 93% rename from FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.h rename to FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKHumanSilhouetteIcon.h index cad25b6bde..20f9b7a3eb 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKHumanSilhouetteIcon.h @@ -24,8 +24,8 @@ #import "FBSDKIcon.h" -NS_SWIFT_NAME(FBMaleSilhouetteIcon) -@interface FBSDKMaleSilhouetteIcon : FBSDKIcon +NS_SWIFT_NAME(HumanSilhouetteIcon) +@interface FBSDKHumanSilhouetteIcon : FBSDKIcon @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKHumanSilhouetteIcon.m similarity index 97% rename from FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m rename to FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKHumanSilhouetteIcon.m index c7b81f5f18..7a7fde0fcc 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKHumanSilhouetteIcon.m @@ -20,9 +20,9 @@ #if !TARGET_OS_TV - #import "FBSDKMaleSilhouetteIcon.h" + #import "FBSDKHumanSilhouetteIcon.h" -@implementation FBSDKMaleSilhouetteIcon +@implementation FBSDKHumanSilhouetteIcon - (CGPathRef)pathWithSize:(CGSize)size { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.h index ca78c86442..a51d899d59 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.h @@ -19,13 +19,20 @@ #import NS_SWIFT_NAME(Icon) + @interface FBSDKIcon : NSObject -- (instancetype)initWithColor:(UIColor *)color NS_DESIGNATED_INITIALIZER; +- (UIImage *)imageWithSize:(CGSize)size +NS_SWIFT_NAME(image(size:)); + +- (UIImage *)imageWithSize:(CGSize)size scale:(CGFloat)scale +NS_SWIFT_NAME(image(size:scale:)); -@property (nonatomic, strong, readonly) UIColor *color; +- (UIImage *)imageWithSize:(CGSize)size color:(UIColor *)color +NS_SWIFT_NAME(image(size:color:)); -- (UIImage *)imageWithSize:(CGSize)size; +- (UIImage *)imageWithSize:(CGSize)size scale:(CGFloat)scale color:(UIColor *)color +NS_SWIFT_NAME(image(size:scale:color:)); - (CGPathRef)pathWithSize:(CGSize)size; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.m index b46a8d6c1b..87396ed19d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.m @@ -20,34 +20,33 @@ @implementation FBSDKIcon -#pragma mark - Object Lifecycle +#pragma mark - Public API -- (instancetype)initWithColor:(UIColor *)color +- (UIImage *)imageWithSize:(CGSize)size { - if ((self = [super init])) { - _color = [color copy]; - } - return self; + return [self imageWithSize:size scale:UIScreen.mainScreen.scale color:UIColor.whiteColor]; } -- (instancetype)init +- (UIImage *)imageWithSize:(CGSize)size scale:(CGFloat)scale { - return [self initWithColor:[UIColor whiteColor]]; + return [self imageWithSize:size scale:scale color:UIColor.whiteColor]; } -#pragma mark - Public API +- (UIImage *)imageWithSize:(CGSize)size color:(UIColor *)color +{ + return [self imageWithSize:size scale:UIScreen.mainScreen.scale color:color]; +} -- (UIImage *)imageWithSize:(CGSize)size +- (UIImage *)imageWithSize:(CGSize)size scale:(CGFloat)scale color:(UIColor *)color { if ((size.width == 0) || (size.height == 0)) { return nil; } - CGFloat scale = [UIScreen mainScreen].scale; UIGraphicsBeginImageContextWithOptions(size, NO, scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGPathRef path = [self pathWithSize:size]; CGContextAddPath(context, path); - CGContextSetFillColorWithColor(context, self.color.CGColor); + CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillPath(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift new file mode 100644 index 0000000000..d20b77557d --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift @@ -0,0 +1,139 @@ +// 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 XCTest + +class FBSDKDrawableTests: FBSDKTestCase { + let size = CGSize(width: 100, height: 100) + let placeholderImageColor = UIColor( + red: 157.0 / 255.0, + green: 177.0 / 255.0, + blue: 204.0 / 255.0, + alpha: 1.0 + ) + + func testBaseClassPathWithSize() { + XCTAssertNil(Icon().path(with: size)) + } + + func testDefaultScale() { + XCTAssertEqual( + HumanSilhouetteIcon().image(size: size).scale, + UIScreen.main.scale, + "Icons should default their scale to the scale of the main screen" + ) + } + + func testDefaultScaleWithColor() { + XCTAssertEqual( + HumanSilhouetteIcon().image(size: size, color: .red).scale, + UIScreen.main.scale, + "Scale should not be affected by the color" + ) + } + + func testCustomScale() { + XCTAssertEqual( + HumanSilhouetteIcon().image( + size: size, + scale: 2.0 + ).scale, + 2.0, + "Icons should accept a custom scale" + ) + } + + func testSystemColor() throws { + let potentialImage = HumanSilhouetteIcon().image( + size: size, + scale: 2.0, + color: .red + ) + + guard let image = potentialImage else { + return XCTFail("Should be able to create an image with a valid size") + } + + let redIcon = UIImage( + named: "redSilhouette.png", + in: Bundle(for: FBSDKTestCase.self), + compatibleWith: nil + ) + + XCTAssertEqual( + image.pngData(), + redIcon?.pngData(), + "Should create the expected image for the size and color" + ) + } + + // MARK: Human Silhouette Icon + + func testImageWithInvalidSize() { + XCTAssertNil(HumanSilhouetteIcon().image(size: .zero), + "An image must have a non-zero size") + } + + func testPlaceholderImageColor() { + let potentialImage = HumanSilhouetteIcon().image( + size: size, + scale: 2.0, + color: placeholderImageColor + ) + let customIcon = UIImage( + named: "customColorSilhouette.png", + in: Bundle(for: FBSDKTestCase.self), + compatibleWith: nil + ) + + guard let image = potentialImage else { + return XCTFail("Should be able to create an image with a valid size") + } + + XCTAssertEqual( + image.pngData(), + customIcon?.pngData(), + "Should create the expected image for the size and color" + ) + } + + // MARK: Logo Icon + + func testLogo() { + let potentialImage = FBLogo().image( + size: size, + scale: 2.0, + color: .red + ) + let storedImage = UIImage( + named: "redLogo.png", + in: Bundle(for: FBSDKTestCase.self), + compatibleWith: nil + ) + + guard let image = potentialImage else { + return XCTFail("Should be able to create an image with a valid size") + } + + XCTAssertEqual( + image.pngData(), + storedImage?.pngData(), + "Should create the expected image" + ) + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/Contents.json b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/Contents.json new file mode 100644 index 0000000000..73c00596a7 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/Contents.json b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/Contents.json new file mode 100644 index 0000000000..ea81a4b2ba --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "customColorSilhouette.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/customColorSilhouette.png b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/customColorSilhouette.imageset/customColorSilhouette.png new file mode 100644 index 0000000000000000000000000000000000000000..07e2056bbc8eeb55da4bd893f27fae5d199c0160 GIT binary patch literal 4215 zcmb7I2UC;H77pPhBoqxj0%C}vNDUaOfP@;Vp(srx6e*!s!9oeeNRa^2MIeAu1nGWA z5iAr1LX;v>L_t1O5RfVeT)5spaCi3Xv#0EHc6QF}&g>n6xgjT;AR7n-;xxkRSsr5V zkw77bW3_F~gF|2nwlvfM)eH)MJ5*o+c)MT_h+phTn2apZD~Cp5FTD%ahX_8Dqvm!f zlK;cQIqPKB@4>!9EH~1_S%)(%7C2CZ^?4H-7?K9oZ9kHVXq4k@WEu|6rH{KsV7>y! zQHwf$dx|Ww;_z8Oc8(8y9SKa`?lZrj@@&<>wEmg%!>TroH6b3Uf+?TjQHb9Q%78GB~Bj{Z{0At%Qhgd9%KLKH_HfN%E?zM z)fA%}e;_SHj2|O^8hXlC!1>We2R!lp_Mih+ue6ye+JV-+Z`;M;=niwa6|P8{x~vo8 z8Ds$q$gbd*kf)xQe)9VJ0w!T$XB>ZWOZV0_3$F1yya_*Gkyf}UwVv5Z zaP&wSyq4*Nit{8fpxYf+3?GJ*A@5HO{djKf{6zI(FGg=`i!2#Y>e)Z^fE!*uIx#ki z+Jn#)tDDaZ{<(#9AGZeI_jIv<0%oDCp~agV=Z3Tz7H;p{D2-bAu|uP+=$>OUE*c#^ zKE(JlLwH?qW0Em3@UDSpxlv9=(jNQvDmYVeT)Tn5>Vqhem>&xfZ|T08)!VKOh(B^r zA;ffyS(P$#J~rGgVCndH1=;VJ=nZ&YB58(}U3tW`{rt4d`lP{Z-SL4uU-25(nmYZC zyFBIC5nb!(^Tt>Me{;7lxdqFSVRf^;X&vmq_G6skSI2gJ$%9Ydcl&B@Rk0_hm6QNd zDRW_pFWPP%mVuA#za~E#?+$sFlx(LpyMaT}mLn=$Q?4>|Y)7WsKup|ICWTQm5xaD8 z*ETic>Q@m${{9|TZhXMRNjM!`VSKt))r7Aq)lA??U3l6~+=OJxxnF_NougBy3gqW# zpUUaRyF_kQHcQLI$!gk}$qOkb`)s^&jeg!dy(jvqN6v_O4wVCv#Z0EPe(({vF}RHl zZP%|wX3wFf@uNgAfBNsOHze_lfku^y0O&-S3>x?y0lXqa4@^C1*R7Xk~3KT~U zHoZ{F^0(6T)8%=^s~5fV(IJKJez1qgMjo<)n#c*p?o*tpkAIvYy-5(KoS}eD=yf5# zK}3~VS&ZVXec(lMqw*Mh0?uWxn$rw!1!uB%Nk52D8caF!E`=HzT_pWIiY=Y3B1gRQ z8sjP-tCrJE_=3XwJmdo;xQ$&sdFbG=qC(x)Wn8)_Uj{(lDK;Te_aUDLq)ka=TQYRz zWE=(`6+3fG7sukQ&KG6u1c_Z&fr@myK9gd3J=>Gnh1}zOLH89vpRiOgie@c3iVlD9 zbhK2QB9_#N;7Ip{cNjWlUGD8xWqO7P1H}6j@9a$cgM>;Zfli7U?komn5A?hZaI1*- zN#-d+Z4Z7$iCq2JXuB#jOGXySfUSv6$@RUH`%_YBW&HID=Fx27g%kSsl_G89>EC{f zcC+BL?SR@6qf@8#NvSeT)RaIl&T1q8a+roKnVlS652dPgJ5xhqSN3-5hjo;@VMAJt z`A3GK*tjc7a!~La6kM;*1cQHut2EoA{iRs%UwK44iUGPa{-z*fBH)ld47Bd=Hi|xa zPQhYJh2q8$0szxhu9Zg{W=9k`DSrtfb)7h4-4Jmf{<>$(U`KSsmk_%qlB`hP^7&&K z>p5{bwmd-05|3(oNuR2t?1Qo~7@~9n*&jC!&kl6I>ZIUCyay^!nkOduS-Jf}UNU%% z!?XgGR@KsHlZt0{m*#y{&NfsD(u7VE3jC(hpAz2eXu7+bB7u67PXF&e-r6rjObqld zRwgWTL&G(2s?(&2_*Y^16s7I+LIhhuL@O~|($6w4;bU)(2 zRo9oss#ZB}Iz5>k$bHWSE)4B|nVgdu7y}>DVp4pe(Lbc13rULDH5O%-20WL?bCYSR z@$~GJl1+OqR@@R#kw>ZjZLX{o>PAiTgbmvXTTyKf>fxzoDP(DR7+iXVBkTes=Uq8O z>2sWvMSWL?Wp5`NQ(l2xYAb9P5%*Kd?Y}`M0M9-nc8|1>48m5Wtge`wa|$STmJflR zLiTs(VW2XxplhNF_?E&%XC?zR-+TCjLDQl3bc+&H{mi%^!mSUv-hayDI4S2{1GP6u9xfm(KG>!c=|;sL=#!K0z*&rXQSetg7*leYSbe1>LAh~#PJ5j5 z#f3?3^qmdseO3_Y;6T%6fEfgWY9GDXO9gfm;fuTp9^5KmIb@==)HW&+O`F4sZPQR% zur(BoVgToJMiyzIWg$2YN!RWn#}PRM`J3CbN(&&(O}pOIW+bCLu8Wm{z!Zs#cR>|a z&rcORsHiEc63;Ll(TvhoY%+bkR&elqYqYvGIeFzmq4v~<%9umfiGhQWyy-kG_`WuH z4Q6}yfb1ST?67~HhsViLy$}{99-|dgDfD>M2R^|Ww&lFS%8fu1sv*)t{pw{S=q#Z& z<=(g+G#o{I`e(UG5U6{?)-}Tf3a#m~b-i1=@*p@>YcA+4%Pa&Zu!y z#E9pne~>uHe!e$I%d&OI@btr&VTYv~O^8=vd-PeviZBe#P2E)G2>KA7QM6f`x4Vo7 zy4cZFJ&@DzdBrJYGf!I~?|FKLwiHwAH%(GKZm3Zmsq1Yix`KkCxyr2{%Io-#ik>$6 z0y!8J_P=VmsBr=V{T$IM>75vG){p0LPX?m$h`g@?U2NOh%)u=%AFst$E{K|ASVkvOBAAu# zgp82^O4nsuadW@NU%g59oz6&#PX47-4B?9P@%q`WY_rmq3nXym_=Jz;5^mr*!rnjk z{>ueLC`B`1B7=My{^Bvtz~hHoac7h$U$4`TC1sBpAqALnTqk*BKh!+c`X5JUy6UMM zS8AsqzxKZu2%Z$v~eA?6HSIo`3k-+uk}2by}jvs`A;CmDyC zEU3zvGdjO)CPwgIYUx4*uQy+-edz9I%$X-(gp`gUoel3)js0hdwV|87i$`XH4A!)K z^KgsqE2gBOHaz$xH00rw`R}cl!cGVe`1+f1N(!^U?TY9zS6I;)iCcc&(Cn-MR^*`k zl^}bJgb^|ZbiJB9YoTzWHR^L<0K$ye^&SluuYElpRfP%;QI>5IT$*^n8?Fb20i=P= z*^eA31&Ns%FK#GLCm~s-@r0hsF{>Fa7#bdJ8zzbEy$c9yn1P+awpnX7zL2z>mq$w# z0JkR`zVoU=@>{SwT)>5R*s#O&#|AQE>*-Tv(^x|^MjOOaa`{&GLgc5k53B(zRA3(3 z_OGea#U4UHH6-mre3vlSz8-iD`ayR2V$=KrXRH8Zjk;pUy}+IGK|PqI8@=~<8c9UT zl(Ta$z!$Jp_WKa5{Qf(?yODoR^6x{GpYrCHwr<^iZqY-Tia%C=FRf$Wz`4v;>Y2{6 zS>aUN{BT|5opJA|HPvan=B50&0=Xv1#8JP+){}Q?Dt?x!kC8#`mtPQUrPA+?7jKRZ zPu*R;_{diG)fl{`CB)88pxM2uXL7+nA@z?!W8tGKrCCDn|;Zg#dL`1QnAKFm=eF}qa<%N~Q!8XvF?31UA@r~#t@suqY z7*Aj3oN16pqiVLIs-2XTmVI&ac0so!F(s{R1@{wu`|@VU>V2$zPnfghE#a{DS;M@6 z-8hv%4}07-Y1PfhuN!amW+%KcfZNIBRUU8l*kmr(EWf*Zq3LUF>K50cs=rmoC^WB@ zP54;7;=f)Hp}Mckh*tmnh((6^Gss8S_dRpnjEnKfX^-ZZ>-Gp6P5iqTzjm{PeDsg^ z7_m+Jbjf3%(>NIvPqAvM(!6~W*X29eKW(#3#* zapc>Y{92-wM{slA$EyEjFgX-O^df8gP-HOGsNAce5VlRR z-g?YKm7bez`K9)pat8FSbLB7glQe*Qfq2g=82MF}IL}Ls(t=v@2Du^a`4-;&7^YPi zGCL>$*H9&Ef5keZ_d8#}jA&w!FpBu#-P-WTFI06eDt}-$zxz|%gJT6Zjk{U%_Q9xRh{Ke1S32*141SILrFs?K*gHEKpBD;Z1a6NINEjRxnIT2{y~-*Xg? zb@svTYj7@d4|piURMLyX=kG`aXO#6n&xn{sR`_jC<6`gGEwWz^Yisl%k&4ZfTZ#^t zoQ_?**C_6-+gSLqKYb(dA0pWMc!n8OP>BC7-m!t*=|tTuH;WGBx)M@^QmyZHiJx@5 z#=aMJxieZ)=dWlmRPLCXpi3puij22y2u%>~pL}>VKM0@&^v0RK5;~o;yL#rewgQ1!K`>f{5DT=zBp~K4t@pM_jHGa8 z$mi*3d+tHiH9o&DoL(-01Ja}Xi+zdjL2aw&i3`gr7$KSdqmKb2eRI7U9U}QZJGyrd literal 0 HcmV?d00001 diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/Contents.json b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/Contents.json new file mode 100644 index 0000000000..ffa2bf4f70 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "redLogo.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/redLogo.png b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/redLogo.imageset/redLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..e60ad08a1655360b4be8092145a46bc2c33c67a6 GIT binary patch literal 4925 zcmXw72{hDS*q$+r!3<-NZ7>P>XWz;88|zTWmL-)e*>}mBL0Q94NMz5FJz8uT4931M zkq99>Su6Rb?|k1q=ef_l@B7~8F6W+m-gDz_80sSEx#&S45JC^9WkO-{Kfs`ry3(>L zheBXK6I~5Z)gbx@r9L6&QX>c!j>N`sT-0FZOVl&a8s#6_ zmyInFD8^E=KwgA@t2720QRnY?HBq%zpx7-3rLX;IGKZ?O+WAMGZSW?TZezRvu!{tR##N* z@c0dl5UCTk69wmM-eozf28xX|pwtEeg3Zn^|+tlG?OO`3I$!|h$XGU9+ z9W+-ILgz15V>8%FBQ61MIyAh|Ap2rrfYu^v3M=0Jw34T~eaq3-P`t6{6A!i9LvO+1 z@x*EBG`FzluOz@bJ$G!&tf-2d(dLyH{I3=zYsy8mXizys#D%jfUiW@i0kZk3Rqu$TK8y^R)fS-ARl`?yn? zx*yt_tM#-lwhosM9{4^}_RvZbQT)xX4Vu-FX^)3K8aQq`=oOH)?0cZ5h<{PQzBkFK zUHJ5Ki)4?ypL@Mhwvx^`k*`jH4l!QSo7usczh1iVaLs8|R3`2VQ|Q1wKQlR9pD$Pa z52`Az^G`v}tsVVX`Ky~+*i^soeNje?7y$FDHA?F*?e_Q7$@~enN#(@lu2U~Rlm=u~ z$OH8>zrp-stT*RM?RCh@^!)|_1C35Oktr4?u}$fFF@HAs);1T4u4_CwREa66m_=Vq zl)P<~T=+qDlCHSmS7$Gi@@MoIU1QwNL3YTWR(Io`EP#djW54emInr?IRdwh*)wQ-1 z+wdCp;q@aw{I=!~oyy|VP4E#k0e^HRdP1+rWCQjDeTbsPr?VJ5`Q2B@>xwP9V2OLu zZ?;iJBkBq6BSz%y{r4?fvoJD@SVHv8o2qvy-s%7(rsLxJ>azRinQmNJf&PJk{urX8;v|PneCzoyB)ak8g%Z|(4jB>VY zv_Pgq@c7=qTdxxM+U!%4 z(@b_OWpMf3&y=O;NSh4xNyf&^Ub?FqesP2A0{93+{WJSP%;<80?W4RE#=G##EiBWl z6H3G7pwznpiSnczY|%(oj70!mRq30Zt)JN{@Jun80U1A-kjL{MhnBT!GuvCml&?Zf zbkmp#r4wtBHrHpH}l63`zb%tU(LQl_!S2}a?{uW<`T zvurXRnCNg9a?x&l6EDxO8qIkQ-)BAa@HA(opAwMEqBwrZIVS6b)G*SQ7?iF27P z9}C64V0s_9sP#3et20%HYRo5p?c!@V|9~gB30jhGk28=o3s9EM+v`gV~bDK-7D!r-i%PS}B_M(K@@w^30e<4v*plsDL-9}*M% zkyQ7=N(0ccE^Kc4ON|(TsGNRb%4~TYsU& zxLOCHW$uIkCqjDchs5Mz-Cj;Dp@w{v5&9$Y#CXP4Q-t~aRG)M?0J(L24pTi6J;LX+ zl9!f;)1;ihlbl1?v2qBhIR8}{x7N%Zc~mDl?_sbzR9;7pahoe{Hz`2qQ&Z#_(TRx4 zdvacnnG^mPb!Ix%yl3DT6kKEY^vzGR}O(0xeMPf>!;yj|0 zrQ>yyy Qn8XLsz1Z&<+MI2X$QDzsOQaa7pZSE}}$z|xp$;n{T?e;0y;ax_*}#V0_bXuYc3 zfH^u!9P##x54^x$b*OG>*6Oi(l6);T*8K9=YwVymI;zvBbq}i4O@dyUgwj2WYvLVg zuH#3nSlUNTVo637N*`+EY#H2(>BIbuQ*Z}72sNRT z%z<n*SU;F7(2B>N-%96NhJ_88mZzWXVC z9X?{(ZQZqUPDvEc&ke=5wLu`*>wih%)+@JCHgnc)qnBlwMyRSZn4t4>-DJ%=fIFnO(xjZ(~fX)P9M1t@>}b zrvkNyAc6tn?r8U-Tq(Xu)23z_;4*= z2hK+jk_c~TdAfe9?)Ix{LGnC5(U9xci^gnms_$PyUdqNifRRnYFi=ucHFBD~bt zf%pHx#zA|q?r>GI9DQir9nj}I%nb-h9g{4)JD^NOwx)^T!u$mXnMQcsK>;^~|3x#A z6)2%*pdcM=9yC@L*uBPAPf^=u2QFOs=Vu^u2<9~00cBPSSSk-}(4qcFYsWbi!!Rsq z)Nc3_h{Gq;Q1*ZL>^B0I5E37z?|I<;7a(afy&7n&I-quQA#;v2y#(}fOy^^4{{^&O z+3jOb^Jm_?N(1J`q{Tb&5ifhtH}gBGW>~x>#gwp8d*IEk) zk$DJ$erFxi!ZRyMEZ)Yt2gN6T16dC?DGNLThwj%-| zBLyn2FI=_iz25E>nQW2af{WA~7&(z0d9arXH^qz>t;$41CZB#qLW=HxpA%Y0W?}^=YDbZxCWt7($KhQvFsEBIw3T`i;dlSj zCk*9~f(g69go%l-54oU8vk1cVmRK-~7h|D_HJ*bhE+aI2zmZlylt(*qV(ta$e65+R zp7}l4(a-VIt8PDX0z}6^=o|$6JzyBFZS!M9JQ#HWb3PyPl?`7s1oDN=JPpkfUir?6 z`F7&yfr7-1MQC<3t%Xv#;U7cDBrQ-X7YKK^=)1v3H9!hz2Wg4h`>TW~&_x#g5OoIc z-{VE}NdoP=z2B}bl=2I*(|slaB!+$=O%*6 za&vWpS9Mm?+=5$7xYY;X6${qmYtdaQtzZ+IaM?$5m*_4mti{Q52*|YxPz0z(bCx~4 z#v<&S!FG7+<%kydjh?R{Z!4ros8}AgoL|OZFk$f!bInF&>m7pfUa?o6M-A@^ zh4)R;T5r@PT8dw5m|;o4}R;?#TM#fQ9A@;FAo z4qwkpVE2;?O@9LEhOz!$+PfXF0VhmS@vG~gQ#(5vhB~4R0CA!ChD7k_RVK3io59|> zwZsZM!lnpKS?U9PzZ+yHuE~%Z`;~=9|U@9#w-BE`GKq!Rz88O!7+bIjr*Q0A_#xLR$Tb4F%N$H z0d{N6miE0=q71NKxz`s+9=fDCW~F#ONj=F_8An;RfI4ueQ~6XaO&}b;UL65S1~&Mk zNuVBD!qi^>y~8=S9y2N)yj{zTC;o(X8Sy7|XbhRq%L?w>o}3jfUSf*t1nu1#V<)?O zX)=F@5!~$<_GM)efX224t0gHcs$i;Vw5Rq20A8(Q2Q2~z<`Jl&q};+R97@O<`2?d} zVJ^tBmx`pO9QM$x=$Q9wK5>9^i(*C zco8DtDs0UrOxb%du&iYePU~j*%omD#fo_(7BT*0%4?%VOxY&1KD?A!bATo?3gCp$l zAHn-#a;nNvg6`>6oR}1kwMqaZ1*C#g62dEk^879QI`=al_jdeP$t%eHE)BRs_?^m% zyBB*jy0DSSnp>r%P7QEE)RfNG%Q6*&;&_ijT>XJi-3{iu*F5n4P^~1slCG6D%;Lp8 zU-!3gwjcD(;8AdFc78A%!PtIX%1c0-BSuYIdwNS6(0_eg+NmcMBK~n&IQGl28YC>n znlAo6@JZm5G2M4_B_yc+Cwq8jiChyx=Vst&|oCjD|bjOo0c27W5Z zHTOh5Psf&ylVB8kc0sn_ik!SN=UO%xE=@ldy&UK$p%1x^!;?24%X%66TszFK>TGjG zA&i_vMa|*PHJ4>y=C^BjccCOfXR5bNCukL00}}_3DMEK_xDXeh7f`s)TTB_Q2Mdb) zu8A8|d-obP@zNT~H3TZ&c+!>EHyq{czI1KiJ@uq2?_5H0!BWbrq=9t(tUhU5PVXLK aYns*ttIZ2%G?ZU0ke;@oR+WZrD6$Gaf=(h{|Nb%pf(SA!IFUsVsR) zDrFmMN=THlZ>dp|h!*eh`+48L-*a8x^F815Irrzjzn{;2UH5e^Iv%hQM=PKO1O&vX z6tXjvJ2wL<4Bac;tFA!_7U^tbAyCz$I1d%5aEeEyfPjqpX27V(=&l|zAc19@6kz_|G78%mivKG*MIa2Z$))H!tl)wqb1TK^c|AI_HXmy)Zt%o*3QT1HP$~p z{@mR`1W8HgmUhtMd)#Ofi+$CRa$103cT5!46<#n|_)igGcz>k=y9(fHK|#W zz1-1a;*D(MCZkxhswYQ1Ia!A@?ZNm*J|_pLDQ}lzsuXr<=cw1#U0|O7YTNb+)|$QZ z;#2pBC05xUwnq?#OjQm+I&Mc0COBi`-J_Qe|0y?oFyKXmiH}rr!thRk+0_#DGj!Aw9uTUN!4&3uwz;w*T#J8I4S(5%H$QBnQP>=Lyxaol9`N0&myajdy00NUmL|)KiH1 zsKsOo2fN}XtQteJMNa?Rm5$ftrr8cOz43p|;E==*-*5c+VDPbtGp1Z!7bf2Q?XUEb z^wSRGS&p7~xa3rW#4{&qgiVH-qYVg`3@B(BedQx=KXjt;)v%k$F>!S(pm2iN>u+@X zQnLXrnk3$gq=+$w#(+^_FL7V3x|Jf_Hg;`N#1mAA=8Cqh{3L0p3st`gT0h&Z#}^{~ zRBIt&e6`}ndU*6q(|&IBV6p$h?MCZ+CF;(uB)n%KDXDI_QU~r;c!c(poqcY83(Hzc+;iMq?Wd9B z9ZmIpurB{G;dd*_e$Uo>raz*wAhOryzQ#2aJe z)d*yNV#ksM4>ZWD#dn?5V-K7Fe&}DTaFN%{nRZVGYS|U&0e#ypDi~2g=6aH{X85Q_ zo5W{sF=TsGW$N4K!G&Tx1}@p!AW5qc99Zf2{c&q`!oNpm)a_2`LyK#RXCjQ6mDC=I z{B9{BOp8IYpJPKRn4t%D*nR~7BmUHeotcl})b^1ZWW{1PvE ztSZfP8?38Fh$N%anRQHDC2coUp*Aax|HUktFP{AtsT)wM;uTMsb^yiacnZ0q5iN}Y zuG~yW%hE-i&wzLMQ-@-)PzV0<|oxbh6 zk@muig^)jFe^2(-NU~hX#FG(aFC;wl7k+bBNEdtH)2=h8i7AljPjVU!0>z-c%D03} zUr7v+v6?0TM(xWWA6GiD-IOf!-Ma0N@$mo z)#$fY^%gpA!O@KG#Ig&$-O~_G$%Vejt(0_4Z?yppm3N5Od-chlm zc)T#O6xpeBU0AfUTT9|T37~=#^j(hNId_JoB;pd5g5&yYz=fvc@q)uZZyK{jPs0a^ zl?*dI@d?Qm!hRrw?Pm!f==;Uhd;$Bx7Myrkx5&&t6f@0EZKz5oWmwrn;KOOeE z_Lj@SeM=yjX}@ey1UtJ&RG+T5TGW5Yi>Js1h<4}d)LOp#{fTajEo(YFfGVdj48jLS@5dfDp zoiWJ=fJEn|waiyiaCt=F?LGbFUwmJiZ~P^%{z?eGhQOz$AE3R@@iQ`2=8{0zqsGFW zovQzb-4sQ4Hvf7yk79{I{kKzlcBv;v9*ecj*G}?s0BP zLG3vbm3HU?nAO{PGn?`iEgr6WS9-Z@y^5-J*=)z$F!5x~9Z~meHDJo#HjYw;D0ca) z>ZCr3WxZ*eu36~!U}pG$<&>vvse7+53k}Pe$pRw*oCvNJA;E(Ta$KO^p7VvF8bM z*ld+Tn$Fc&HNZtID?k)E5I-?;d#-E@WfL&euk$=%q_W(oZ~W)z_M}o|Fn=)W`g)Av zHUm%T*My0WgS4MZZ-+{|og2?z93HE9e$0o+BWtafan5Cg-hk~hHh3@Bwy$mI zR&zerEaRNRVva(>>c-1nofoHy>4KT=g~C0uCL@FxW&e+F57XL%UI@AIlr+Tqo#*xD zGswELS*)C&h6QE3&sV~)JH$^iqMm5_aFOl5^cUsmI)e!YlXs;nNN-f0627)EVlC5h zGfXs;@^p`t0EyRSNyrxJ3fEVy)gDV{d`Y+_Px#l8CT z5Mg3nv|nOA=Hl*=83Yie|1F!rk4i9ztz!$d62#a4#N90O&R*8e%X~_6Xf>rew}o9z zrMjt$Vd67H_~Hz;_DTiU59oQV`HT#>#WwH1&o*7FiF#IVZDn;lUBb?-^ngG}(*9Ht zzB1#8OP$YZk>3rt3>8E1vo%V5C34_*bkpd+9oBP7g!Q}KYH`i$)Q@$vb>6YRmF^Dl zA04)=pXp8d)>nSDG`as2XWBG8@0JMPlo3u(jh*NHNUk%-U%mSesLuVQW6?T7ACaa zm|0nm`zm9{{x~bsW<#?kzld$f^j#a>Te9=wp>Y>7vSSgmmz6&%w-&xQdnAz@=B@o( z2ew^UozbM^_s)&7d|q!pvZZ+%+bX!S?tX?ca5fIBtNt=&U~nwU{7X9teLkx4$7tVn z@8`tzC;YY1de4uBT6*KU7e27Ms_H$^?a>#v+XIR?-bC)g@1DlDWr<0p<>BRdHFY8q z>UAofVr@AHcq*^2CryvJ?fvva8M-@OIF!$+AIdawWaSi!d@`A$j!jCMJNFWC0&u$W=V)!RP z2{-|jBwzb?iFH6kFU-gmL?V?a(c|TU5t2kIu`kH(W911whrfaM+wP);?=`h55f_-@ hXLknCEGUfe{gpe)!9$-#J;?n&AtuW}Tp-#7K_I;1djcg{iG5*x6!IciShF<1lD)@`B~t%s z)|#y|kjl2s(y1hZuJtA8a)CqasdM}>hkY>~WKvJN8QF@+htzfEjv_jf9c^{lMd2=Y zJ~su+<=?;#5aY3+!N(FoQf#g0QLf_yG|nuALk4c8sc7^~r6*y#!85nUd{(r=7Q=Tp zAME~kA2QR1JAzb%Ri0kIG$91j8hk0rhmw67i!^>VHp?GNEI$G<-- zJ_`iko9U<$!uz#F`mX5np1dlD&u$Rw&OqB9gVr&ai64Psr2w>jIe%! z$u7~xbwwVI%Nkb(a;dsZXJ&+#Rm1ovTDijP6(qLk=rhYJmdMC+x&0@sAm(xpkAljG zP~!D6ClSxhlZ5F{d^XC_BBO(30Lg3~A|36}C@bj^jL+=p&Y{xl4K!}LNV~uJW&hN_ zD@VLpHI~|TscxgMDy6*TP@(MP2)6f(u^)(G;FvI`|I1lqa)e2Ed3oliS7frk&Bs0%RQ%K0)uA^j)0YRL5z6n=sCq5N$W^9X$WH10vkSwA8;n_V zRUZ`HVyGDjx;8+&dkndY z4{C6v=~~L09LVbNje`!2e(5(pX?R?_Ey~DRduuRcBcAh|j{ay&sgxi6*qJ~rd06VB zspedqgTt&F;K#V+Lp^WjC2FoW%H*mJIq zdtqz){tL@5clE#$^b3unJD(59SQa|HV}lmMmFDbWsJ>?6N~LFZ{UYZry% zx1=5{h1|4nmzeuqq-Zjg#6XP>k81a8P9z1i43C2 z8*0gwwAQE?2;~mG}ov;GfV_mj^M|Ps$u=?aOBH{^w00es~wPrq(;j zc|In=w>V!CKr$qilv=A}85M<1C0QVdi7BwezRf35JOC3ZW*l`L_1XP!Rv)RV2kcvV z5fImCQ`nYU%NI?1?uls2_~vFTe`h6yN)Ol!*4P?r=qNULl%7hBaXE2qO@ubRv5Mcr z(^+^S&TDOmyW)rGRA$U9xNk_n%rELT+iw^Ivb&3^3Q1<2POE#T(@KGb=b2Od9m8VP z;sZKlXEJ4cwDNOM*;n1{LecSLuQx@XU9dM7cK zmzN!^KA%u#kAlH52&qFB?uALuU+*3>kdW1sd7k)q-K)(1Vhiz_!`v4o3Y=M9OOmdhy zY12=Cfs#U#)f!4=a-!$x+bgoI6bOI=6ni{!U~?HL_D(EHtmr~hiX}eWKFkIMUPHmr zDbCwU$gb-+wglZG95nj&KMmQs#9vDR9{Q*%D*gzd*w=UnoJ%y^QR1W-v*PZ=vAbFA ze6!Z0h=T&?l*=4?;A(+z-Oh`J+Mbm9C>IdT5f#=G0@ zhrtqrlu)uHZ%X7Fi%?~VN)%oRP<%Z+RlZSxK5ePl!0oo;&Rl%~p zZuO0E185MFw8~;y|H0G%WT(K(v&;F$KLSHrI>h|8$L=12=6D%Nzm(b-oT&02(Z|M9 zO+)-!Z7XFzCwmtrVh0ka+-pSXN~w)C&$<>nE>`yx)BGC`r)wYOm&q`=l@a8B=9w)M zIL(IWQga;=v09oJenCg^N8w|s2WIO|N0t{R=tX`GF^h${vc{TX=O>>nnbmR97|Ty( zQMd!7vaB)Nni!W>e$W_n%XNj#&edM30_jkA6kG~j5kxX5?jOeSvgS&_m#d#WZZ3CY z(PYnA3tHxEBNqqXc)1$&T9E$YG0Xc1baqZLxHOY38A~?8lho2o1b~Rb%Jx=$crQtF-0& zCV&|l*PzRgO)_bE*L^}VH+=W|i#zG<2OGV=mUo};^)$J!{qnxQ*%SX;5snR_mH}XI zcke|vkL)u7BXgfKr)~yno0NU$JLT>X(-^d7wjSZF__HioY*#|dSar!6O0qxmxXi1sO)mSKm==rB1X|3m*lrt_j9;TJb_YF? z^9s7}9z>sz`4MTqBWk%qVgxO!&-qwniJAh;I!pG_WO4Ihq@L(}{e~~B(4p_@F=bi$ zlT%mBw{=T~BxcmVpYeCRV^KTdloC_QC8iy`U(bDBeRGoQoX4-bF|dF6IJP%;CB%_{ z1V#QW&krZD%7smn*`ZT$bk?Ywos;L*{^9TrPTNRe)r74<0pAmv)26hfz3*CR;9e0i zAg?|{xHfD1?o`9mUm7O{j%kTS9JNH*asuBowMMj`2b5fUhyAf{#DW_}%fM0|j0FkW zf6vfoU#zo~H^~x10{3(oQ+4bPi_2M@ogz&UW7}$66;m%Lxb$TfZHm&Exm3?rg&*uQaS+;=RuB$-U^ Date: Thu, 19 Nov 2020 14:20:29 -0800 Subject: [PATCH 130/227] Adding Close Icon Tests Summary: $title Reviewed By: jawwad Differential Revision: D25096412 fbshipit-source-id: 2384857d3fa38095d7e0ea5408fa3f2375e573f8 --- .../FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m | 18 ++++++++++--- .../FBSDKCoreKitTests-Bridging-Header.h | 8 ++++++ .../Internal/UI/FBSDKDrawableTests.swift | 25 ++++++++++++++++++ .../closeIcon.imageset/Contents.json | 21 +++++++++++++++ .../closeIcon.imageset/closeIcon.png | Bin 0 -> 11143 bytes 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/Contents.json create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/closeIcon.png diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m index b02e4e54cf..46f22ac705 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m @@ -28,7 +28,17 @@ @implementation FBSDKCloseIcon - (UIImage *)imageWithSize:(CGSize)size { - CGFloat scale = [UIScreen mainScreen].scale; + return [self imageWithSize:size + primaryColor:UIColor.whiteColor + secondaryColor:UIColor.blackColor + scale:UIScreen.mainScreen.scale]; +} + +- (UIImage *)imageWithSize:(CGSize)size + primaryColor:(UIColor *)primaryColor + secondaryColor:(UIColor *)secondaryColor + scale:(CGFloat)scale +{ UIGraphicsBeginImageContextWithOptions(size, NO, scale); CGContextRef context = UIGraphicsGetCurrentContext(); @@ -60,12 +70,12 @@ - (UIImage *)imageWithSize:(CGSize)size // outer circle rect = CGRectIntegral(CGRectInset(rect, step, step)); - [[UIColor whiteColor] setFill]; + [primaryColor setFill]; CGContextFillEllipseInRect(context, rect); // inner circle rect = CGRectIntegral(CGRectInset(rect, step, step)); - [[UIColor blackColor] setFill]; + [secondaryColor setFill]; CGContextFillEllipseInRect(context, rect); // cross @@ -73,7 +83,7 @@ - (UIImage *)imageWithSize:(CGSize)size CGFloat lineWidth = step * 5 / 4; rect.origin.y = CGRectGetMidY(rect) - lineWidth / 2; rect.size.height = lineWidth; - [[UIColor whiteColor] setFill]; + [primaryColor setFill]; CGContextTranslateCTM(context, size.width / 2, size.height / 2); CGContextRotateCTM(context, M_PI_4); CGContextTranslateCTM(context, -size.width / 2, -size.height / 2); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 6cfb893d51..4b4fe47d98 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -20,6 +20,7 @@ #import "FBSDKAppEventsConfigurationFixtures.h" #import "FBSDKBridgeAPI+Testing.h" +#import "FBSDKCloseIcon.h" #import "FBSDKEventDeactivationManager.h" #import "FBSDKSKAdNetworkEvent.h" #import "FBSDKServerConfigurationFixtures.h" @@ -34,3 +35,10 @@ @interface FBSDKAppEventsConfigurationManager (Testing) + (void)_processResponse:(id)response error:(NSError *)error; @end + +@interface FBSDKCloseIcon (Testing) +- (UIImage *)imageWithSize:(CGSize)size + primaryColor:(UIColor *)primaryColor + secondaryColor:(UIColor *)secondaryColor + scale:(CGFloat)scale; +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift index d20b77557d..cf377e13e4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/UI/FBSDKDrawableTests.swift @@ -136,4 +136,29 @@ class FBSDKDrawableTests: FBSDKTestCase { "Should create the expected image" ) } + + // MARK: Close Icon + + func testCloseIcon() { + guard let image = FBCloseIcon().image( + with: size, + primaryColor: .red, + secondaryColor: .green, + scale: 2.0 + ) else { + return XCTFail("Should be able to create an image with a valid size") + } + + let storedImage = UIImage( + named: "closeIcon.png", + in: Bundle(for: FBSDKTestCase.self), + compatibleWith: nil + ) + + XCTAssertEqual( + image.pngData(), + storedImage?.pngData(), + "Should create the expected image" + ) + } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/Contents.json b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/Contents.json new file mode 100644 index 0000000000..101b8da9a1 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "closeIcon.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/closeIcon.png b/FBSDKCoreKit/FBSDKCoreKitTests/TestAssets.xcassets/closeIcon.imageset/closeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..7802500d99fbb7e3fa6075a77c41bfc2ee79e1ed GIT binary patch literal 11143 zcmc(Fhf|Zmw|0O40qI={J@g_-?}Q#Yh*UwkNGAx=OF&9M2%&dTkPb@kO_0zRMo&kLnD7xH001C{sVf`YBj%rg@a~@# zCY8DOfaPVNrUl_}ZJm9JI9oJoj}F0EqPnfcsD7UgWUo|EI2s#Rb6mPd_#Q z5cLWG{BIqdd;C{W_wtYPUx@P_>%X<{``%;!k2dB#&i}9fqrs-$irfQ%hq|d306@e3 zPq1JHki+{<@GE6q!+X3R@IS@w{>gPO|L|TYtZcKU{qK6*Hhop#PD}3Hwp-p&$=4Pa!!~ z7tgV}Uq&(1Z{TC-CxurJ_FVVc8gJUY4vasI2kp0Q4eg#huMy7hI-7lYkl|k8K4m6c zb1rtW0g}Lu4`o~Vzk{#Qotobre=dIVsyX-?{jR|eL>5hLsXT+@>dx7>HU1_w7aW$W z%4}#vk^d0utj9fI80|Nt)i?b0VCYEH5TBep$`=l74i8OEv@b8V2c{>iTT10zN)8>} zUbMs$pQl-{RYpa3OZmfrJZj8_jd~B2>ZHv0^J!23QO=ZYT&Q?odoxpH*Ymd|_q{T9XFW+LWwOZd?GZk2>V9KE+bUcQwm6Cv`i%_Z%8 z_7*1J?DVg**fu(d*s-^vDn#7z$uT`B^jjn+YqDvC1<0ducBfKEdYiFESKiHM1g}O@ zEbGRnY<6#cct51eW$|uEjK*OdlQiy^eSJZnu=>S(sB+%X=O|>T-6wArHl5YB1FD(+ z5YI{)!?x4?q`YR19IdkV>^g@FFg!j1VMu`@Sz=ji)H4)u9|Uacu_!6>`LbaEy|NA! zv!ii5wiAS!g!r_43C(&p6x4rDo@^~Yj$)>m@7J~X44yD)rw9i zVo_3%El5_7Ev8aIvZ)XT*q)6THs^rC4ju>yo8u{F6DTf3ScYh-C_BEj%Chz}lE>;U z7crNzaG$c+)4w(;9qv|0Cu1`;3H&4S3#2zABt&J-RlJEIuc3mq9SRg&6wV%V4hMtI zxAGa8d*U`SL;?<9)f_AWSU-QlRbMc6=2#vpHQ#AW)p5_`- z^iuP^;!jtJ!@X#=dOK^*C~_^e@F^f5hiZ5mU-2#}b(7cOLD4+dw7xPqM|X63iLGZW zwjdsRB3<<()=0j{BtQ7c$9_W+BQ-AP>cgd13m|Ga!71S3~X z8yOmirN|wenfM7KV@dJF;B65v)RSj2S3GpvkfG&x{VZw7?t;zt9!fTPzaV`iHsyl! z<}c5@xJWpEo56MQE-w1D9nylvceOi_QxO>^NQkEk>&`nRnNtdER{RQ8brMq&0^=Ss zNhgW+;D*^WLG!lYP-@wjL%MX|`=ILYEFH>3L56xP1!(!3iWn6_dr;;oHhOyY0@S#? z@ZHakUWf&3c{zmm*bEKZbnlr3mCTxlu}g!^?93>8eX2QhC_;ZcfEls*lsJlZ$F$!Z z<NKxg~Y3UVUMLgGV&GirGZZ_m0G*Do;f`IiA1;IPsSza*1D8{0Thc2v`7e{8__sN3}5i# zO?|^>ITs5D4s?EOb_3U=!aRS$^*M&D5BF1np@tbYaI(NeC5K!^gK{WhB2jH$M4GYP%d$1#!Ito-%HO}Z<9xCG{n?kbKYMvG`i5Y>`Roe z8FKL=H+)N@4m;ykK1{#zX_)9yLin2o2%vDA3LTEM;<8b^p8n_<^VNaY-T;xBa`bkw z+{CMxdRbx-d2aEtw|&$sF<@QN&&@J?dQG%ta_QwzFknat9g(WMpGt~_Q;;1K3TJmS z9qL*_ViWMIF)Z&$_yRS@s&;FuUFHXo&ha&CJ$a@_+b`kc)@LV2nXO_woz1VCZ?Xix zfQ&pg^im7rAp34u@4>Lt@G#4aO)j=RkPl<+$Zn<%PoG6>#l^0Q(Qex-ANKtT^702e zJlsUM$iq%SNY zd3Dl}q*8@{_AH}>h;{~~-XQoO1P)}}Y^D_2T#-UCE#`pYMaT}hIZ3<`xvw_h30)P- zV`av@2y@XdQPgRHPCUMD#?~#T@_2vCrRViT^?$iRIli>?#>Z#mFiOi0%s!0;MT6~A zl{}+V%eE!XLC3$?7(f_fM)zI}&Z5CV;IuvcOlm2tx?RSD7OG6q0O2Q7u6&lU`Tmrv z4*X`Ffb|*S^^&-`=LXX;w_{ayjH}IjX^-391er$$J2`ZQrI|eg2R6Wmk0UdTirOf) zmFMs4DjSl+!7_d_`XwlrdMo!;ujRbIO5w?LxT`Jw>=ZKkNm$lrIYQI7LIj(ozIKdq z(ojIR7HmULPv?+sCI$=?_bF2y=@EW^*b}e)40JY@NgY+$UxjM(SFKNRt;E(GX?$T_ zPxqt%{F@-cxj|7AktdVF@_nezW{BK8Uh3>!>+tU0y04WPHMYfRm=njDe+syimXmSz zj7M-WzRtX_t+7)dXwAu`xdxT)U5 z6yZG21uC&~Q(w8Lh{!8i98xhePa_>tKhi^@KtEphY^&Cc!_VPaFC2OUDw!+|diXhM zdLZH>=j)d}s3RAsG|7=NP!Sj_MAH4dyr0~1BfhZfj6pQ z?aTs$-mh_(`z`7i9PuT(#S8!iCT^zp*O^7HtGPdsmVN22+QoF?D?E94qZmrJ$wA<@ zXn~dS4U#W#QB0$tXQd;kOqMw(v5z{XlVwc6WQY2VsE{?2xJfF9&1%}Dj4yT*yXHBHWpy6kqLgR&(~sWYh~{3T%1 zs?UTb!6P-Ocr7slLvEHJ75ZxE&3o{?m5-XhbZMzyd{T%@ufF(*#aO8v+S@v(bSBzb zz>nFgRJg`*8ZkXhWPmRb|oyCV21uHV(CRXNr=VxEfRTskGyKosS zeMKGa-@?XU4h1=)wrBX!$%#tdr3grmh_MWUx`Qcv$d>m*Q({QS$f~Pz6YOC_h$Z!}9G^IFN45?S(faQrML-}wy^;>8lRoty>f5u4UF?&uqTT;z>#6F;?e z#P$(jijMOBI>SaZ@-QGy*4ig0BGZ8Ji&WKKIBa0%SEOM(T~mW%ff$ zMj2Z^MP0iUbUFTFna2k52w!_!pmK7|LCr?r{P=;e-?H~e#WT3NX(=mAdP6S+WMNL*M%J=U;7c!2XSz z4Plv*%uU4}T_qx8C7CLb#*uvdgHPh+!TYhYM{>evj*UiKX)E6{qaZy#gR!~;FQpCo z^Tjq;VI=Tk9Z8ttkoS_$;GS=S^y^Sh?o%ZrJ1YX#bB!)ZZH|g44EZ-k;vG+t$m=;= zU@v0DkGA4W3CO$&?mi;o(w@IS)+Fp(l?GTjRDAys9CuB~LZDazDp z?tB6H^)C+#B(BWyUs82}&E4R|vU}(P!uzqC)D?HVM|=jo9k!Hc>GBM8siKIosS{7r zojpcchEm;x0?I9{PUYpCguTm<;8NQ%NC_HT`jiAs7LZf5Nbx34j*cvXq4cN9Jx}>_ z<%JTB^8PayS*j4eE5t0p9-{Q_$a=WMd~!q2VoL+9gHrMyfTF>qL+w9y^~l1TKS)4w zDZ6xUavY%|UW{_Ph6LlX}7JAn#6*n4ZWME##m4B zq>NiO&4gvnTxi8(zqTQjieCg}ZCG+ka9+QH&d?_h2YqidJ5HX>^ugM^yU>Z7FeZDg z#FCX*khc9pqe$stL3ROXuPH7n!r2S(zEEcSB^nh0VxNyYQh$b)KT&GRk{uG?3z zE(_=dILUSgw|DogRDl)Dv;adv*=tUcnW_9~#6v{WGa7Lk_L*5ECjS&fV9@6dZgVn8 za9_Qd=MFvY2y8K^tjHpq8+P96PN-H-**bOTQ;`4VDMG)$H*aO(T!r!JWpaTKP>ckj znBT1~&L0;4rBb*IZeOU9-HH6*Hcz=v04JoWxNXRYO;e;9U_H%=iB=jx1UojSF@mJc z`K9yYPYbEJy{hO!BD(w-mVaA{a^UL=1Q3mCI6eEkdK4IAPi-!)PElXBJ^Bo#1b?q( zu$@3n&6`gT0eN$RhYi3#(ty^5_E3xu?iLHwX+{?zQjS0HRV+&ujm@$A$81up_}_LX zVl%wLvPG8w{TT-X+P9d zkAoZ76~Za_&>)Y4fL|S4T*J2CA`wykiGXOGR7{7aAaaxinwo8U7Ng9}+q5jhvG5*M zK)J!})9Nn!tg`Ho&*4{WIYyy}B|m`uf#L~9^@&0iTNKa~X*yo>G<3sONV@J+8YZPe z($999Sa_}_ODqQgS@`(02R)3!w4rgyq1~&C-w}LJrL;w-vyW7Wzdvs%)Lsq*v%`w| zp|AABxT}K}h)BN0D_D4fPBnnPd1+(sBNysOqlB2azws6b-G#wtZybz^LVcHB<*=yw zrUbLW#4*rTt}LoqIr}rpUm$*U8FVie^Y$a}N_UD`8B$Z>U&E@OMOrlZuFm?RCsYz0! zYO=mKR`H(-dII>Mou?r5&e@!iIyuw4GvqfeoQ!RNL#5uNvzbJS6~RSfy)~#~66U|$ z!&1)0%l|;JUYvf-B4Rm}<)l|)v?#Q3G}6SP<)qD6{Ri*Hd#eAqitWetS{azn`9Y%K zF+n##mIK5ey_WDuZoJn36-+1hSnYA*AENTh^+gut*=H@4fxc3Emv54AD}*;%u`o|4MvSFRR1qP@|Hw(>qY0(0D@ZK8xRzNXMo;KMC7)XK zyNO;G4dPv4EzKThbn*{Uu07X-ioPxJm$`!h(>WQ^FVAwl97Zg5HiqW{Mt5tb{g=*7 zM_Z{5K z+|eG@+7u*`D-qQ{MnO>r$xt$z_!;vHG=Tw+ItPf*20=t+7t$j>7kcrxk0zYiT${wU zQ617H?l#R=hd0Ve_4r*J9}tmDSe*>~g6Q;-5{+lZ!S&-2i3rx_3=Wf=E!J48RIU}Ogm2`(^`X^LDj!D1m(JgI4ZX_3s^eWAmjrK)ULVmZ`5x>9YRu9=woXX;hh!Lkg3k5@8o#~}&0d@)xukr&sf?1?5=yJoiI))d9p55Ol>{OE;LiPA!; z&XYw@#Rjm1!>%^TX@{{b<+gAWM)DwoIwb3LrjRbq_Mhda*KEN?_x$cq&261HKay&y zG83nRm3RjuvV!mDiofjG27yqOt7e>9wKrPkvToH|2R}7Ydx|9Z+YTsT-i5#L)OFp$ zr4lkxi)=0Ca?gM#`rxe{ZrD*f?T_&@feh-NQQHbR@}tf;W|C}=$*e6k)SfEIx{Nz| zh4O`Ss=qI3L6NTzG=1~~f;g4jV zl$RWEwsJ$z?F2#~cjWC*!t}0DU+70t1~XBurZyRsT@;bSSGZIXbws=(nbDWOGE>O< zYjL&b(hs8Lwwi2h_5v7xr$Wr3B)OQyUCyvAC`DkH?rxsxb_-jjp^L~9%80JibU1QT zGMa>6?F+*9!@gwny{$7lR1ff>)J5+gZku&2iexYBmWQf? zf_g?t*WWfmWo4kF+%!TBBJ7lqB2zMDucI#Y@5S}V?EF0}Xiq`SAFH|X8o+NaH(wR; zeTxWyMTA%_l=8*Q&9+$I||-8Pmi`;WS)`aep*yxjS8sFfaD*z-W_&{+~obqZBS{| z@*GRD$2|fDai{rCra_@l^%^~L^(Rj3Wn-S|XzGHho5kg5Uq=d$@z$x{Ev28@=vV!# zR*OXF*U4dD9Sm zuB(KA9bCp5OP9}0p0M_-_ODtFB|$7u;Xa5P$g1mEgh4otjygZAx-$9L4{RG z8-6V3c5c+hrlr(k(xxBi6-}9G8LirL8RF=qC9jnklbvnbMvEjnBltg4i8w=D!D#nS zetUD#X}mO#X1Nf2r+<}#9#IvUa$t%@czH2he$gXKH@-bV;{eIuveP*SD5n>1RM7Ps z9=gqj=t>N9zB3T5dvD=4NOo0@P9~sKo2;7D2D1(I>1Ni-=C|h_=aY(3zRDGt8E#x;EY(@NY9A)(*U_ZLiiH^1>D(%f6eT3#4 ze2XB-f@I*)4H;!bVt(QtI)~%LE=Xm*OrGY5Cung{I4LyyXB}z#kJSlnSzcH(M^wOg zB*X$8einKvBA4-paS^=mMyDqO8J0V=EwqidYETw+CC0TWa~}urehdJV8-WANNY+p6+O+O%8K|5Ef7zVIntf<& zxvIBaDMtYliv{nGi9mj5f}hj7yz|O3dmwDKD(?b!L!g2#Zt*kvf86^g$o2Z0IFT%= zb$1HvNj!5|2%V=2{r8~#8flxoAzjJj=CZy-yPE!0Ms3!984T7ZE9dO_iK~^q9V*%$ zMYh4;)Unb%B!exv+3xfRiD5;RZ-u6^ZFqv0!mL4iRRd={kK0;^59Q8pEz5`3y>{4P z^+<4%`V&%kD0}*&WwE;4+>7)4yO{7?mx=9X?RQ`P{7$)&;L2cr{T*U$2mq=Q0)(Ig zBF?AV(aVlF!E)zH@>_!2^Rk4tmK*bl<8^U=Q`(!;<1-$~;ej&KLZryH7(_CT zS*rfrCrGUo)BMNp`l({S-KoVbnBz?eu+1-~jb9M5aWS@c#TByr?xKeY_KIK)SYB z%#&O0Zm0s7PWVb{R5voYHC^}T+RjJWcwTF1>nL>n13IGp$5!Rx;9ZnopS{Mr%?|wm zEXm{6^iB#V^GSHdwusjZ!fWfqtJ*${c>VoU-+C%E-G1{XU&jTcP2n;5Qt?}WR5C$ zOpn^Yxynp`(%7=Fg#)z+dE!Z~u9(++^?6*P_5MQHqSTRSmMFIVRCg%HY&8H6X5cm| z8*c^&g+u#!umw$3R1<-I^+<`y?HxME>`8xg$HT3H%J`F}9f1yzO_{nPQ}YGUWuiwL z?^<*IXttT?+?HS2@hgi_StoyX4|qSMza-VT&ewxjf!@>zEyH9w>Aca9BUdFlavA8= z*Yfz+en5j*5+u-_+Vx;l!Pe7Sh*L>^wK{T5ONUuw!rwl2{z*SP zfBQ!qjlWAsdWHZ+RL2=m6ik;G z!6@K!Uy^*d`~4c;T=@PK3F`{D&?X9&h`_tQL6AP*F}63V@;5_JZA?49)h2}i-LLdC{Ql9LEehcRC3D4v$>7cgfeM+#<-d+~WAmWIka03LM#g za>5i_N12DbPx;E}=fUfuKgn9tyd=`@#!e~g>GxunN$an$rW!yy`U7L*o=LVv^(U<# zwaN}d_|+7wGB2ZHKYoQIE}OyV+C0#l`(<;CU<8_Z&xkS!$o}yDJoe|? zOpL~l|E7?umUsG0_WXHqQ|=*u3QouhZE|=mUEXFbGRCijQOa6Gmk91V5;kC4 z(0dWv#m}q89tHSas(@yA0#N-R41+g6L-#0m^~0_(vEgmh||>BT`u@M zIHb9e^hgMyIgwZglX=cs zkT<+O`ugF70<8~G?^Y#tu`O<=jZfx8fxjLE*igxxJM;mnUefG zm~SmJ4=M3-Mvau@50iawCtf&RTYeamiB0h9o>wU`iCf@eRrV-_nNsWv=|~5($r=kx zr^zI^#{(`bl6|1yVdV?-{{H8baY*?g7xL`2OfN=zhl$fWAC2ETg~cefa$n&2C7*=5@*riH!zn*g`2=6&0J`CJ7cjm-x<2 z`_Zz5qvbV`mz9Y==+S>15yPzc4TK6dhn?|q4Jr+6p6@iY4+0iOAi^tQ+o{|d-l|Lf;x)DmZ;xY*c3G|FBPsLU2{75}w4g7lC+5-{N&*oSO zEKl_70jp6Z)KA>xLn-E=_WBdqC*Pt6Rnm9%V=lJ(MEyrkJOgeU40poa2eH^EIIiOC&zqA>OqHN!Vvhuagbhy=1$!#0uI; zW0NBdJ5!OlDsKnqQofvsI=GPP6zlUP#+E5(pTTFnJ&lj1FC+@N%8f1)NN7~|ThD#H zxWK3mrC;3l^dh?2z0E6k9SR3YK#4rU>5B2b0qizI=@<)YO$S-oLR$kwl#W>l@L*b0 zU^h`~JHt3)1ftV1(&2+%9*1qR{e-AKNNR}9%P6%y-WJtM_|<1gzF0y^?$!KO%h_H2 zK5gp!+L^vNfAMd8pY89DCTF;8(!pdn!jWWO!}XpKhkbGB{rGUChD}(1*F#l>ve1w! z>22a`7`t>)JM50cZsnI)zIkl26W~tz?at{Ul@ zMgj)FKesp@gl&waW-`}oG7o(eoqsnJwv%a_j`LUD+s|_8ag{id%B`qh=eox1dtZ_r z5rsXEefA#%el<4ixHuCILOajSjXw`mxuIKbHAyiF+^6eZ{iA)kz&PO8Vg#W?0=tyyF>55py{S}ZsK*<>$my`sIix%baUl}tb&iQFo+Dk0tOvfRqhASwD7TlBh21h z*zVl@{;pe|d)~=Yc6rZ6qN!>bgoPG5G>F0s2EUOXIue@7bW1fBGkC;dBIIknC$s%*lL(U(X;`%V^nBA8ixmvnE1?zms4J>D&VUXvekoUnBQc%Jw-q`%f7y2X zLhf7p(+;gEEl|BSXwE`Y#p)?JhOL_5DV`&VW&I#|`$FE?&8D|jq}GZy?nldVRzYHH zNd;N|1j3*17zZ_a?-;yuUd&lNG5s_0Vvr$_2b($!si5+n iRqubZX#xS>GX2nTZ$^&9zWn!>DojO3xl+*z@&5p0xymm9 literal 0 HcmV?d00001 From 72eb6322687e06e8f20df0e5da0217555946f5da Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 20 Nov 2020 16:41:22 -0800 Subject: [PATCH 131/227] Convert FBSDKSKAdNetworkRuleTests.m to Swift Summary: Converted FBSDKSKAdNetworkRuleTests.m to Swift (Also fixed a minor swiftlint suppression typo) Reviewed By: joesus Differential Revision: D25043695 fbshipit-source-id: 4d85dc801695e19d74c88c36b0de9d46af9ea794 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 8 +- .../FBSDKCoreKitTests-Bridging-Header.h | 1 + .../Codeless/FBSDKSampleEventBinding.swift | 2 +- .../SKAdNetwork/FBSDKSKAdNetworkRuleTests.m | 170 ------------------ .../FBSDKSKAdNetworkRuleTests.swift | 151 ++++++++++++++++ 5 files changed, 157 insertions(+), 175 deletions(-) delete mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 8003781260..a09ce3857b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -998,7 +998,7 @@ F916581724F6BB5100BB759A /* FBSDKSKAdNetworkConversionConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F9DE56B924F61B090009CD69 /* FBSDKSKAdNetworkConversionConfiguration.m */; }; F91BA4DD216D6CF200CDDFE0 /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B081A702194009137EF /* FBSDKCrypto.m */; }; F91BA4F4216D6CF300CDDFE0 /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B081A702194009137EF /* FBSDKCrypto.m */; }; - F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */; }; + F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.swift */; }; F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F93680D4249D490600446E35 /* FBSDKSettingsTests.m */; }; F94310F424F8D608002441F1 /* FBSDKSKAdNetworkRule.h in Headers */ = {isa = PBXBuildFile; fileRef = F94310F224F8D608002441F1 /* FBSDKSKAdNetworkRule.h */; }; F94310F524F8D608002441F1 /* FBSDKSKAdNetworkRule.m in Sources */ = {isa = PBXBuildFile; fileRef = F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */; }; @@ -1637,7 +1637,7 @@ F4F98C4A24CB820A00F0D6EC /* FBSDKSafeCast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKSafeCast.m; sourceTree = ""; }; F4FE997D24D906B9008879A4 /* FBSDKJSONValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKJSONValue.m; sourceTree = ""; }; F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkConversionConfigurationTests.m; sourceTree = ""; }; - F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkRuleTests.m; sourceTree = ""; }; + F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FBSDKSKAdNetworkRuleTests.swift; sourceTree = ""; }; F93680D4249D490600446E35 /* FBSDKSettingsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FBSDKSettingsTests.m; path = Internal/FBSDKSettingsTests.m; sourceTree = ""; }; F94310F224F8D608002441F1 /* FBSDKSKAdNetworkRule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSKAdNetworkRule.h; sourceTree = ""; }; F94310F324F8D608002441F1 /* FBSDKSKAdNetworkRule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKSKAdNetworkRule.m; sourceTree = ""; }; @@ -2752,7 +2752,7 @@ children = ( F916581424F6BAB200BB759A /* FBSDKSKAdNetworkConversionConfigurationTests.m */, F9CEF1EA24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m */, - F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m */, + F931C06F24F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.swift */, F943113324FB2E67002441F1 /* FBSDKSKAdNetworkEventTests.swift */, ); path = SKAdNetwork; @@ -4181,7 +4181,7 @@ F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */, 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */, F402B071255C740C00473083 /* ViewControllerSpy.swift in Sources */, - F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.m in Sources */, + F931C07024F960D00088AD5F /* FBSDKSKAdNetworkRuleTests.swift in Sources */, 7E253D811A8EAEF500CCCFE7 /* FBSDKInternalUtilityTests.m in Sources */, C5F6EC861FA24FAF009EB258 /* FBSDKPaymentObserverTests.m in Sources */, F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 4b4fe47d98..ce0801b902 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -23,6 +23,7 @@ #import "FBSDKCloseIcon.h" #import "FBSDKEventDeactivationManager.h" #import "FBSDKSKAdNetworkEvent.h" +#import "FBSDKSKAdNetworkRule.h" #import "FBSDKServerConfigurationFixtures.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift index a05f07d4c6..3c365fb5c4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Codeless/FBSDKSampleEventBinding.swift @@ -18,7 +18,7 @@ @objcMembers class FBSDKSampleEventBinding: NSObject { - class func getSampleDictionary() -> [String: Any] { // swiftlint:ignore:this function_body_length + class func getSampleDictionary() -> [String: Any] { // swiftlint:disable:this function_body_length return [ "event_bindings": [ [ diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m deleted file mode 100644 index ba5f739aaf..0000000000 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.m +++ /dev/null @@ -1,170 +0,0 @@ -// 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 - -#if !TARGET_OS_TV - - #import "FBSDKCoreKit+Internal.h" - #import "FBSDKSKAdNetworkEvent.h" - #import "FBSDKSKAdNetworkRule.h" - #import "FBSDKTestCase.h" - -@interface FBSDKSKAdNetworkRuleTests : FBSDKTestCase - -@end - -@implementation FBSDKSKAdNetworkRuleTests - -- (void)testInit -{ - // Valid cases - NSDictionary *validData = @{ - @"conversion_value" : @(2), - @"events" : @[ - @{ - @"event_name" : @"fb_mobile_purchase", - }, - @{ - @"event_name" : @"Donate", - } - ], - }; - FBSDKSKAdNetworkRule *rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:validData]; - XCTAssertEqual(2, rule.conversionValue); - XCTAssertEqual(2, rule.events.count); - FBSDKSKAdNetworkEvent *event1 = [FBSDKTypeUtility array:rule.events objectAtIndex:0]; - FBSDKSKAdNetworkEvent *event2 = [FBSDKTypeUtility array:rule.events objectAtIndex:1]; - XCTAssertTrue([event1.eventName isEqualToString:@"fb_mobile_purchase"]); - XCTAssertNil(event1.values); - XCTAssertTrue([event2.eventName isEqualToString:@"Donate"]); - XCTAssertNil(event2.values); - - validData = @{ - @"conversion_value" : @(2), - @"events" : @[ - @{ - @"event_name" : @"fb_mobile_purchase", - @"values" : @[ - @{ - @"currency" : @"USD", - @"amount" : @(100) - } - ] - } - ], - }; - rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:validData]; - XCTAssertEqual(2, rule.conversionValue); - XCTAssertEqual(1, rule.events.count); - XCTAssertEqual(1, rule.events.count); - event1 = [FBSDKTypeUtility array:rule.events objectAtIndex:0]; - XCTAssertTrue([event1.eventName isEqualToString:@"fb_mobile_purchase"]); - XCTAssertTrue([event1.values isEqualToDictionary:@{@"USD" : @(100)}]); - - // Invalid cases - id invalidData = nil; - XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); - invalidData = @[]; - XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); - invalidData = @{ - @"conversion_value" : @(2), - }; - XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); - invalidData = @{ - @"events" : @[ - @{ - @"event_name" : @"fb_mobile_purchase", - @"values" : @[ - @{ - @"currency" : @"USD", - @"amount" : @(100) - } - ] - } - ], - }; - XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); - invalidData = @{ - @"conversion_value" : @(2), - @"events" : @[ - @{ - @"event_name" : @"fb_mobile_purchase", - @"values" : @[ - @{ - @"currency" : @(100), - @"amount" : @"USD" - } - ] - } - ], - }; - XCTAssertNil([[FBSDKSKAdNetworkRule alloc] initWithJSON:invalidData]); -} - -- (void)testRuleMatch -{ - NSDictionary *ruleData = @{ - @"conversion_value" : @(2), - @"events" : @[ - @{ - @"event_name" : @"fb_skadnetwork_test1", - }, - @{ - @"event_name" : @"fb_mobile_purchase", - @"values" : @[ - @{ - @"currency" : @"USD", - @"amount" : @(100) - } - ] - } - ], - }; - FBSDKSKAdNetworkRule *rule = [[FBSDKSKAdNetworkRule alloc] initWithJSON:ruleData]; - - NSSet *matchedEventSet = [NSSet setWithArray:@[@"fb_mobile_purchase", @"fb_skadnetwork_test1", @"fb_adnetwork_test2"]]; - NSSet *unmatchedEventSet = [NSSet setWithArray:@[@"fb_mobile_purchase", @"fb_skadnetwork_test2"]]; - XCTAssertTrue( - [rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:@{ - @"fb_mobile_purchase" : @{@"USD" : @(1000)} - }] - ); - XCTAssertFalse([rule isMatchedWithRecordedEvents:[NSSet new] recordedValues:[NSDictionary new]]); - XCTAssertFalse([rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:[NSDictionary new]]); - XCTAssertFalse( - [rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:@{ - @"fb_mobile_purchase" : @{@"USD" : @(50)} - }] - ); - XCTAssertFalse( - [rule isMatchedWithRecordedEvents:matchedEventSet recordedValues:@{ - @"fb_mobile_purchase" : @{@"JPY" : @(1000)} - }] - ); - XCTAssertFalse( - [rule isMatchedWithRecordedEvents:unmatchedEventSet recordedValues:@{ - @"fb_mobile_purchase" : @{@"USD" : @(1000)} - }] - ); -} - -@end - -#endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.swift new file mode 100644 index 0000000000..a22125fd23 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/SKAdNetwork/FBSDKSKAdNetworkRuleTests.swift @@ -0,0 +1,151 @@ +// 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. + +#if !os(tvOS) + +class FBSDKSKAdNetworkRuleTests: FBSDKTestCase { + func testValidCase1() { + let validData: [String: Any] = [ + "conversion_value": 2, + "events": [ + [ + "event_name": "fb_mobile_purchase", + ], + [ + "event_name": "Donate", + ], + ], + ] + + guard let rule = FBSDKSKAdNetworkRule(json: validData) else { return XCTFail("Unwraping Error") } + XCTAssertEqual(2, rule.conversionValue) + XCTAssertEqual(2, rule.events.count) + + let event1 = rule.events[0] + XCTAssertEqual(event1.eventName, "fb_mobile_purchase") + XCTAssertNil(event1.values) + + let event2 = rule.events[1] + XCTAssertEqual(event2.eventName, "Donate") + XCTAssertNil(event2.values) + } + + func testValidCase2() { + let validData: [String: Any] = [ + "conversion_value": 2, + "events": [ + [ + "event_name": "fb_mobile_purchase", + "values": [ + [ + "currency": "USD", + "amount": 100, + ], + ], + ], + ], + ] + + guard let rule = FBSDKSKAdNetworkRule(json: validData) else { return XCTFail("Unwraping Error") } + XCTAssertEqual(2, rule.conversionValue) + XCTAssertEqual(1, rule.events.count) + XCTAssertEqual(1, rule.events.count) + + let event = rule.events[0] + XCTAssertEqual(event.eventName, "fb_mobile_purchase") + XCTAssertEqual(event.values, ["USD": 100]) + } + + func testInvalidCases() { + var invalidData: [String: Any] = [:] + XCTAssertNil(FBSDKSKAdNetworkRule(json: invalidData)) + + invalidData = ["conversion_value": 2] + XCTAssertNil(FBSDKSKAdNetworkRule(json: invalidData)) + + invalidData = [ + "events": [ + [ + "event_name": "fb_mobile_purchase", + "values": [ + [ + "currency": "USD", + "amount": 100, + ], + ], + ], + ], + ] + XCTAssertNil(FBSDKSKAdNetworkRule(json: invalidData)) + + invalidData = [ + "conversion_value": 2, + "events": [ + [ + "event_name": "fb_mobile_purchase", + "values": [ + [ + "currency": 100, + "amount": "USD", + ], + ], + ], + ], + ] + XCTAssertNil(FBSDKSKAdNetworkRule(json: invalidData)) + } + + func testRuleMatch() { + let ruleData: [String: Any] = [ + "conversion_value": 2, + "events": [ + [ + "event_name": "fb_skadnetwork_test1", + ], + [ + "event_name": "fb_mobile_purchase", + "values": [ + [ + "currency": "USD", + "amount": 100, + ], + ], + ], + ], + ] + + guard let rule = FBSDKSKAdNetworkRule(json: ruleData) else { return XCTFail("Unwraping Error") } + let matchedEventSet: Set = ["fb_mobile_purchase", "fb_skadnetwork_test1", "fb_adnetwork_test2"] + let unmatchedEventSet: Set = ["fb_mobile_purchase", "fb_skadnetwork_test2"] + + XCTAssertTrue(rule.isMatched(withRecordedEvents: matchedEventSet, + recordedValues: ["fb_mobile_purchase": ["USD": 1000]])) + XCTAssertFalse(rule.isMatched(withRecordedEvents: [], + recordedValues: [:])) + XCTAssertFalse(rule.isMatched(withRecordedEvents: matchedEventSet, + recordedValues: [:])) + XCTAssertFalse(rule.isMatched(withRecordedEvents: matchedEventSet, + recordedValues: ["fb_mobile_purchase": ["USD": 50]])) + XCTAssertFalse(rule.isMatched(withRecordedEvents: matchedEventSet, + recordedValues: ["fb_mobile_purchase": ["JPY": 1000]])) + XCTAssertFalse(rule.isMatched(withRecordedEvents: unmatchedEventSet, + recordedValues: ["fb_mobile_purchase": ["USD": 1000]])) + } +} + +#endif From 6115ba23352e17ff8a8068bdf9d73420c5b17f44 Mon Sep 17 00:00:00 2001 From: Jawwad Ahmad Date: Fri, 20 Nov 2020 17:00:26 -0800 Subject: [PATCH 132/227] Fix Xcode override warnings for methods re-defined in a category Summary: Fixes the following 2 warnings Method '-sampleUrl' in category from .../FBSDKBridgeAPI+SessionCompletionHandlerTests.o overrides method from class in .../FBSDKBridgeAPITests.o Method '-sampleError' in category from .../FBSDKBridgeAPI+SessionCompletionHandlerTests.o overrides method from class in .../FBSDKBridgeAPITests.o Reviewed By: joesus Differential Revision: D25135544 fbshipit-source-id: 625c23f1e0b92c731dc8126a244555ccc4b9dfe1 --- .../FBSDKBridgeAPI+SessionCompletionHandlerTests.m | 10 ---------- .../Internal/BridgeAPI/FBSDKBridgeAPITests.h | 1 + 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m index 4439f0b328..0e50ad5af6 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPI+SessionCompletionHandlerTests.m @@ -160,14 +160,4 @@ - (void)verifyAuthenticationPropertiesReset XCTAssertEqual(self.api.authenticationSessionState, FBSDKAuthenticationSessionNone); } -- (NSURL *)sampleUrl -{ - return [NSURL URLWithString:@"http://example.com"]; -} - -- (NSError *)sampleError -{ - return [NSError errorWithDomain:self.name code:0 userInfo:nil]; -} - @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h index c24283ec70..3e1e136bd5 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/BridgeAPI/FBSDKBridgeAPITests.h @@ -33,6 +33,7 @@ @property FBSDKBridgeAPI *api; @property id partialMock; @property (readonly) NSURL *sampleUrl; +@property (readonly) NSError *sampleError; extern NSString *const sampleSource; extern NSString *const sampleAnnotation; From 54be5147faf14fc4e8cde868c6d7a19788632830 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Sat, 21 Nov 2020 14:12:47 -0800 Subject: [PATCH 133/227] Removing link field from profile fetching when permission not granted Summary: Conditionally removes adds the 'link' field to the profile request based on whether the access token contains the `user_link` permission. Reviewed By: jingping2015 Differential Revision: D25098226 fbshipit-source-id: fb7b7585332363c066ac914301ec1d87e2d59901 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h | 2 + FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 10 ++- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 69 ++++++++++++++----- .../Internal/Helpers/SampleAccessToken.swift | 18 ++++- .../FBSDKLoginKit/FBSDKLoginManager.h | 16 ++--- 5 files changed, 87 insertions(+), 28 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h index d1b1551599..372b0f9ea8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h @@ -145,6 +145,8 @@ NS_SWIFT_NAME(current); /** A URL to the user's profile. + IMPORTANT: This field will only be populated if your user has granted your application the 'user_link' permission + Consider using `FBSDKAppLinkResolver` to resolve this to an app link to link directly to the user's profile in the Facebook app. */ diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index a0cebd3dcd..c2919b6a49 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -268,7 +268,10 @@ + (NSURL *)imageURLForProfileID:(NSString *)profileId + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileBlock)completion { - NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; + NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name"; + if ([token.permissions containsObject:@"user_link"]) { + graphPath = [graphPath stringByAppendingString:@",link"]; + } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:nil @@ -287,12 +290,15 @@ + (void)loadProfileWithToken:(FBSDKAccessToken *)token || ((NSString *) result[@"id"]).length == 0) { return; } + NSString *urlString = [FBSDKTypeUtility stringValue:result[@"link"]]; + NSURL *linkUrl = [FBSDKTypeUtility URLValue:[NSURL URLWithString:urlString]]; + FBSDKProfile *profile = [[FBSDKProfile alloc] initWithUserID:result[@"id"] firstName:result[@"first_name"] middleName:result[@"middle_name"] lastName:result[@"last_name"] name:result[@"name"] - linkURL:[NSURL URLWithString:result[@"link"]] + linkURL:linkUrl refreshDate:[NSDate date]]; *profileRef = [profile copy]; }; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index 65780f7fbf..8c3b5b5aec 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -327,37 +327,73 @@ - (void)testCreatingSquareImageURLWithNegativeSize ); } -- (void)testCorrectGraphPathForFBProfileLoad +// MARK: - Profile Loading + +- (void)testGraphPathForProfileLoadWithLinkPermission { id profileMock = OCMClassMock([FBSDKProfile class]); + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"user_link"]]; NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; __block BOOL graphRequestMethodInvoked = false; OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY graphRequest:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { - __unsafe_unretained FBSDKGraphRequest *req; - [invocation getArgument:&req atIndex:4]; + __unsafe_unretained FBSDKGraphRequest *request; + [invocation getArgument:&request atIndex:4]; + graphRequestMethodInvoked = true; + XCTAssertEqualObjects(request.graphPath, graphPath); + }); + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY]).andForwardToRealObject(); + [FBSDKProfile loadProfileWithToken:token completion:nil]; + XCTAssertTrue(graphRequestMethodInvoked); +} + +- (void)testGraphPathForProfileLoadWithoutLinkPermission +{ + id profileMock = OCMClassMock([FBSDKProfile class]); + NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name"; + __block BOOL graphRequestMethodInvoked = false; + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY graphRequest:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { + __unsafe_unretained FBSDKGraphRequest *request; + [invocation getArgument:&request atIndex:4]; graphRequestMethodInvoked = true; - XCTAssertTrue([[req graphPath] isEqualToString:graphPath]); + XCTAssertEqualObjects(request.graphPath, graphPath); }); OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY]).andForwardToRealObject(); [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil]; XCTAssertTrue(graphRequestMethodInvoked); } -- (void)testActualProfileLoaded +- (void)testLoadingProfile { id result = @{ @"id" : SampleUserProfile.valid.userID, @"first_name" : SampleUserProfile.valid.firstName, @"middle_name" : SampleUserProfile.valid.middleName, @"last_name" : SampleUserProfile.valid.lastName, - @"name" : SampleUserProfile.valid.name}; + @"name" : SampleUserProfile.valid.name, + @"link" : SampleUserProfile.valid.linkURL}; + [self stubGraphRequestWithResult:result error:nil connection:nil]; + + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { + XCTAssertEqualObjects(profile.firstName, SampleUserProfile.valid.firstName); + XCTAssertEqualObjects(profile.middleName, SampleUserProfile.valid.middleName); + XCTAssertEqualObjects(profile.lastName, SampleUserProfile.valid.lastName); + XCTAssertEqualObjects(profile.name, SampleUserProfile.valid.name); + XCTAssertEqualObjects(profile.userID, SampleUserProfile.valid.userID); + XCTAssertEqualObjects(profile.linkURL, SampleUserProfile.valid.linkURL); + } graphRequest:self.graphRequestMock]; +} + +- (void)testLoadingProfileWithInvalidLink +{ + id result = @{ @"id" : SampleUserProfile.valid.userID, + @"first_name" : SampleUserProfile.valid.firstName, + @"middle_name" : SampleUserProfile.valid.middleName, + @"last_name" : SampleUserProfile.valid.lastName, + @"name" : SampleUserProfile.valid.name, + @"link" : @" "}; [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { - XCTAssertTrue([profile.firstName isEqualToString:SampleUserProfile.valid.firstName]); - XCTAssertTrue([profile.middleName isEqualToString:SampleUserProfile.valid.middleName]); - XCTAssertTrue([profile.lastName isEqualToString:SampleUserProfile.valid.lastName]); - XCTAssertTrue([profile.name isEqualToString:SampleUserProfile.valid.name]); - XCTAssertTrue([profile.userID isEqualToString:SampleUserProfile.valid.userID]); + XCTAssertNil(profile.linkURL); } graphRequest:self.graphRequestMock]; } @@ -386,11 +422,12 @@ - (void)testProfileNotRefreshedIfNotStale [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:nil completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { - XCTAssertTrue([profile.firstName isEqualToString:SampleUserProfile.valid.firstName]); - XCTAssertTrue([profile.middleName isEqualToString:SampleUserProfile.valid.middleName]); - XCTAssertTrue([profile.lastName isEqualToString:SampleUserProfile.valid.lastName]); - XCTAssertTrue([profile.name isEqualToString:SampleUserProfile.valid.name]); - XCTAssertTrue([profile.userID isEqualToString:SampleUserProfile.valid.userID]); + XCTAssertEqualObjects(profile.firstName, SampleUserProfile.valid.firstName); + XCTAssertEqualObjects(profile.middleName, SampleUserProfile.valid.middleName); + XCTAssertEqualObjects(profile.lastName, SampleUserProfile.valid.lastName); + XCTAssertEqualObjects(profile.name, SampleUserProfile.valid.name); + XCTAssertEqualObjects(profile.userID, SampleUserProfile.valid.userID); + XCTAssertEqualObjects(profile.linkURL, SampleUserProfile.valid.linkURL); } graphRequest:self.graphRequestMock]; } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift index 0cd7fe2f16..0c372b3a47 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift @@ -47,10 +47,24 @@ public class SampleAccessToken: NSObject { ) } + public static func validToken(withPermissions permissions: [String]) -> AccessToken { + return AccessToken( + tokenString: "123", + permissions: permissions, + declinedPermissions: [], + expiredPermissions: [], + appID: "123", + userID: "user123", + expirationDate: nil, + refreshDate: nil, + dataAccessExpirationDate: nil + ) + } + public static func validToken( withPermissions permissions: [String], - declinedPermissions: [String], - expiredPermissions: [String] + declinedPermissions: [String] = [], + expiredPermissions: [String] = [] ) -> AccessToken { return AccessToken( tokenString: "123", diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index 7e8de2365d..f9f17caa54 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -156,14 +156,14 @@ NS_SWIFT_NAME(logIn(permissions:from:handler:)); NS_SWIFT_NAME(logIn(url:handler:)); /** - Requests user's permission to reathorize application's data access, after it has expired due to inactivity. - @param fromViewController the view controller to present from. If nil, the topmost view controller will be - automatically determined as best as possible. - @param handler the callback. - Use this method when you need to reathorize your app's access to user data via Graph API, after such an access has expired. - You should provide as much context to the user as possible as to why you need to reauthorize the access, the scope of - access being reathorized, and what added value your app provides when the access is reathorized. - You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. + Requests user's permission to reathorize application's data access, after it has expired due to inactivity. +@param fromViewController the view controller to present from. If nil, the topmost view controller will be +automatically determined as best as possible. +@param handler the callback. +Use this method when you need to reathorize your app's access to user data via Graph API, after such an access has expired. +You should provide as much context to the user as possible as to why you need to reauthorize the access, the scope of +access being reathorized, and what added value your app provides when the access is reathorized. +You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. This method will present UI the user. You typically should call this if `[FBSDKAccessToken isDataAccessExpired]` returns true. */ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController From 9e36081cde87186d489278271600a5bda26c697a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 13:27:02 -0800 Subject: [PATCH 134/227] Adding Configurable Login Methods Summary: * Adds `Nonce` type for validation. * Adds bridging header for login tests * Adds new methods to `LoginManager` * Adds Swift convenience methods to `LoginConfiguration` and `LoginManager` ### Login Configuration By default login configuration has empty permissions, enables the beta login experience, and provides a default unique nonce. ``` let configuration = LoginConfiguration() ``` In Swift you may set one, some, or all of these values in a convenience initializer. ``` let configuration = LoginConfiguration(betaLoginExperience: .enabled) ``` Or, for example ``` let configuration = LoginConfiguration( permissions: [.email, .userBirthday], betaLoginExperience: .restricted, nonce: "abc123" ) ``` In Objective-C you can use one of several initializers to create a new `FBSDKLoginConfiguration` with the values you want: ``` FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@ [@"email"] betaLoginExperience:FBSDKBetaLoginExperienceEnabled nonce:@"123"]; ``` Note that default config creation is non-failable whereas the custom initializers may fail if an invalid nonce is provided or an invalid combination of permissions and beta preference is provided. ### LoginManager The added methods on `LoginManager` allow for passing a `LoginConfiguration` that contains permissions, beta expereince preferences, and a nonce. To get an idea of how the updated call-sites will look: ``` // Login with default configuration values and a default view controller let configuration = LoginConfiguration() loginManager.logIn(configuration: configuration) { result in switch result { case .success: print("success") case .cancelled: print("cancelled") case .failed(let error): print("\(error)") } } // Login with detailed configuration values and a specific view controller guard let configuration = LoginConfiguration( permissions: [.email, .userBirthday], betaLoginExperience: .restricted, nonce: "abc123" ) else { // Show some error return } loginManager.logIn( viewController: self, configuration: configuration ) { result in switch result { case .success: print("success") case .cancelled: print("cancelled") case .failed(let error): print("\(error)") } } ``` Reviewed By: ppansy Differential Revision: D25221017 fbshipit-source-id: d98d8f08c7f96f334077c1cc14990e326ad68d28 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 54 +++++++++ .../FBSDKLoginKit/FBSDKLoginConfiguration.h | 81 +++++++++++++ .../FBSDKLoginKit/FBSDKLoginConfiguration.m | 103 +++++++++++++++++ FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h | 1 + .../FBSDKLoginKit/FBSDKLoginManager.h | 36 +++++- .../FBSDKLoginKit/FBSDKLoginManager.m | 22 +++- .../Internal/FBSDKNonceUtility.h | 36 ++++++ .../Internal/FBSDKNonceUtility.m | 34 ++++++ .../Swift/LoginConfiguration.swift | 45 ++++++++ .../FBSDKLoginKit/Swift/LoginManager.swift | 86 ++++++++++++-- .../include/FBSDKLoginConfiguration.h | 1 + .../FBSDKLoginKitTests-Bridging-Header.h | 22 ++++ .../FBSDKLoginManagerTests.m | 2 +- .../LoginConfigurationTests.swift | 108 ++++++++++++++++++ .../FBSDKLoginKitTests/NonceTests.swift | 49 ++++++++ 15 files changed, 662 insertions(+), 18 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift create mode 120000 FBSDKLoginKit/FBSDKLoginKit/include/FBSDKLoginConfiguration.h create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index e580b89d8a..1b9ee96e37 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -157,14 +157,28 @@ F462DC0F23B958E100FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC1023B95BA600FFCECA /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */; }; F462DC1123B95BA700FFCECA /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */; }; + F4647479256AEF8E00502449 /* NonceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4647478256AEF8E00502449 /* NonceTests.swift */; }; + F4647490256B031600502449 /* FBSDKLoginConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F464748E256B031600502449 /* FBSDKLoginConfiguration.m */; }; + F4647491256B031600502449 /* FBSDKLoginConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = F464748E256B031600502449 /* FBSDKLoginConfiguration.m */; }; + F4647492256B031600502449 /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4647493256B031600502449 /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F464749B256B048500502449 /* LoginConfigurationTests.swift */; }; F46FA65A245347580060C902 /* FBLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA659245347570060C902 /* FBLoginButton.swift */; }; F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA659245347570060C902 /* FBLoginButton.swift */; }; F46FA65D245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; F46FA65E245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; + F4AA32822574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; + F4AA32832574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; + F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */; }; + F4EC46052575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */; }; + F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; + F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; F4ECC67923EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67A23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67B23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67C23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4FD14202576D71B00FDC766 /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; + F4FD14282576D71C00FDC766 /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -386,8 +400,16 @@ C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCodeTests.m; sourceTree = ""; }; C6E63D2224F8219A0015FC7C /* FBSDKReferralManagerLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerLogger.h; sourceTree = ""; }; C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerLogger.m; sourceTree = ""; }; + F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKLoginKitTests-Bridging-Header.h"; sourceTree = ""; }; + F4647478256AEF8E00502449 /* NonceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonceTests.swift; sourceTree = ""; }; + F464748E256B031600502449 /* FBSDKLoginConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginConfiguration.m; sourceTree = ""; }; + F464748F256B031600502449 /* FBSDKLoginConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKLoginConfiguration.h; sourceTree = ""; }; + F464749B256B048500502449 /* LoginConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginConfigurationTests.swift; sourceTree = ""; }; F46FA659245347570060C902 /* FBLoginButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBLoginButton.swift; sourceTree = ""; }; F46FA65C245347820060C902 /* LoginManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginManager.swift; sourceTree = ""; }; + F4AA32812574448C005EDF04 /* LoginConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginConfiguration.swift; sourceTree = ""; }; + F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKNonceUtility.h; sourceTree = ""; }; + F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKNonceUtility.m; sourceTree = ""; }; F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitImport.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -564,6 +586,8 @@ 9D1148FB1B97C42200A6A2B8 /* FBSDKLoginManagerLoginResult+Internal.h */, 9D03E8281A72DCE300207493 /* FBSDKLoginUtility.h */, 9D03E8291A72DCE300207493 /* FBSDKLoginUtility.m */, + F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */, + F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */, C6E63D2224F8219A0015FC7C /* FBSDKReferralManagerLogger.h */, C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */, ); @@ -614,6 +638,8 @@ 0B9DBF06207C051800662776 /* FBSDKDeviceLoginManagerResult.m */, 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */, 9D65ACA71A803FF200E375C2 /* FBSDKLoginButton.m */, + F464748F256B031600502449 /* FBSDKLoginConfiguration.h */, + F464748E256B031600502449 /* FBSDKLoginConfiguration.m */, 9D03E8321A72DF5800207493 /* FBSDKLoginConstants.h */, 9D03E8331A72DF5800207493 /* FBSDKLoginConstants.m */, 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */, @@ -649,6 +675,9 @@ 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */, 9D9DB8E91A114E500086167B /* Supporting Files */, C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */, + F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */, + F464749B256B048500502449 /* LoginConfigurationTests.swift */, + F4647478256AEF8E00502449 /* NonceTests.swift */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -666,6 +695,7 @@ children = ( F46FA65C245347820060C902 /* LoginManager.swift */, F46FA659245347570060C902 /* FBLoginButton.swift */, + F4AA32812574448C005EDF04 /* LoginConfiguration.swift */, ); path = Swift; sourceTree = ""; @@ -728,9 +758,11 @@ 818EB4381D1A283100252851 /* FBSDKLoginButton.h in Headers */, 818EB4391D1A283100252851 /* FBSDKLoginTooltipView.h in Headers */, C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */, + F4647493256B031600502449 /* FBSDKLoginConfiguration.h in Headers */, 818EB43A1D1A283100252851 /* FBSDKLoginUtility.h in Headers */, 818EB43B1D1A283100252851 /* FBSDKLoginCompletion.h in Headers */, 818EB43C1D1A283100252851 /* FBSDKLoginManager.h in Headers */, + F4EC46052575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */, 0B9DBEFF207C04FF00662776 /* FBSDKDeviceLoginManagerResult+Internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -749,6 +781,7 @@ 9D03E8341A72DF5800207493 /* FBSDKLoginConstants.h in Headers */, C66FC2FE255376D200A7909C /* FBSDKIDToken.h in Headers */, 9D9DB8DF1A114E500086167B /* FBSDKLoginKit.h in Headers */, + F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */, 9D03E8251A72D89100207493 /* FBSDKLoginManagerLoginResult.h in Headers */, F4ECC67923EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, C6CE2BC224EB732C00CF2EB6 /* FBSDKReferralManager+Internal.h in Headers */, @@ -756,6 +789,7 @@ 0B9DBF00207C04FF00662776 /* FBSDKDeviceLoginCodeInfo+Internal.h in Headers */, 9D65ACA81A803FF200E375C2 /* FBSDKLoginButton.h in Headers */, 9DBA6A2E1A80253F00B4DE6A /* FBSDKLoginTooltipView.h in Headers */, + F4647492256B031600502449 /* FBSDKLoginConfiguration.h in Headers */, C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */, 9D03E82A1A72DCE300207493 /* FBSDKLoginUtility.h in Headers */, 6B5D2DEE1A8EB1D200D3EF09 /* FBSDKLoginCompletion.h in Headers */, @@ -880,6 +914,7 @@ }; 9D9DB8E31A114E500086167B = { CreatedOnToolsVersion = 6.1; + LastSwiftMigration = 1220; }; 9D9DB95F1A116A860086167B = { CreatedOnToolsVersion = 6.1; @@ -1074,6 +1109,7 @@ files = ( 0B9DBF7A207C201900662776 /* FBSDKLoginConstants.m in Sources */, 0B9DBF34207C060F00662776 /* FBSDKDeviceLoginCodeInfo.m in Sources */, + F4FD14202576D71B00FDC766 /* FBSDKNonceUtility.m in Sources */, 0B9DBF36207C060F00662776 /* FBSDKDeviceLoginManager.m in Sources */, 0B9DBF37207C060F00662776 /* FBSDKDeviceLoginManagerResult.m in Sources */, ); @@ -1085,6 +1121,7 @@ files = ( 0B9DBF79207C201000662776 /* FBSDKLoginConstants.m in Sources */, 0B9DBF42207C07C600662776 /* FBSDKDeviceLoginCodeInfo.m in Sources */, + F4FD14282576D71C00FDC766 /* FBSDKNonceUtility.m in Sources */, 0B9DBF44207C07C600662776 /* FBSDKDeviceLoginManager.m in Sources */, 0B9DBF45207C07C600662776 /* FBSDKDeviceLoginManagerResult.m in Sources */, ); @@ -1101,6 +1138,7 @@ 818EB4281D1A283100252851 /* FBSDKLoginError.m in Sources */, F46FA65E245347820060C902 /* LoginManager.swift in Sources */, 818EB4291D1A283100252851 /* FBSDKLoginManager.m in Sources */, + F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C625B49C24F97DF0003DCE23 /* FBSDKReferralManagerLogger.m in Sources */, F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */, C66FC340255377F400A7909C /* FBSDKIDToken.m in Sources */, @@ -1109,9 +1147,11 @@ 818EB42B1D1A283100252851 /* FBSDKLoginTooltipView.m in Sources */, 818EB42C1D1A283100252851 /* FBSDKLoginUtility.m in Sources */, 0B9DBF13207C051800662776 /* FBSDKDeviceLoginManagerResult.m in Sources */, + F4647491256B031600502449 /* FBSDKLoginConfiguration.m in Sources */, C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */, 818EB42D1D1A283100252851 /* FBSDKTooltipView.m in Sources */, 0B9DBF19207C051800662776 /* FBSDKDeviceLoginManager.m in Sources */, + F4AA32832574448C005EDF04 /* LoginConfiguration.swift in Sources */, 818EB42E1D1A283100252851 /* _FBSDKLoginRecoveryAttempter.m in Sources */, 818EB42F1D1A283100252851 /* FBSDKLoginManagerLogger.m in Sources */, 0B9DBF0B207C051800662776 /* FBSDKDeviceLoginCodeInfo.m in Sources */, @@ -1129,6 +1169,7 @@ 6B5D2DEA1A8D91B200D3EF09 /* FBSDKLoginError.m in Sources */, F46FA65D245347820060C902 /* LoginManager.swift in Sources */, 9D03E8221A72D7E700207493 /* FBSDKLoginManager.m in Sources */, + F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */, F46FA65A245347580060C902 /* FBLoginButton.swift in Sources */, C66FC2FF255376D200A7909C /* FBSDKIDToken.m in Sources */, @@ -1137,9 +1178,11 @@ 9DBA6A2A1A80252F00B4DE6A /* FBSDKLoginTooltipView.m in Sources */, 9D03E82B1A72DCE300207493 /* FBSDKLoginUtility.m in Sources */, 0B9DBF12207C051800662776 /* FBSDKDeviceLoginManagerResult.m in Sources */, + F4647490256B031600502449 /* FBSDKLoginConfiguration.m in Sources */, C68C1C6C24F07688005067E1 /* FBSDKReferralManagerResult.m in Sources */, 9DDFBB731A829503006C9208 /* FBSDKTooltipView.m in Sources */, 0B9DBF18207C051800662776 /* FBSDKDeviceLoginManager.m in Sources */, + F4AA32822574448C005EDF04 /* LoginConfiguration.swift in Sources */, 9D3AF4941A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.m in Sources */, 6B34A7ED1ABA4E7300AF9858 /* FBSDKLoginManagerLogger.m in Sources */, 0B9DBF0A207C051800662776 /* FBSDKDeviceLoginCodeInfo.m in Sources */, @@ -1150,7 +1193,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */, 9D641F841A7B69160048F563 /* FBSDKLoginManagerTests.m in Sources */, + F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, C66FC2A72553748C00A7909C /* FBSDKIDTokenTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, @@ -1309,6 +1354,11 @@ baseConfigurationReference = 812E0D1C1D23843800291B71 /* FBSDKLoginKitTests.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + SWIFT_OBJC_BRIDGING_HEADER = "FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -1317,6 +1367,10 @@ baseConfigurationReference = 812E0D1C1D23843800291B71 /* FBSDKLoginKitTests.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ENABLE_MODULES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + SWIFT_OBJC_BRIDGING_HEADER = "FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h"; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h new file mode 100644 index 0000000000..8162e19c3d --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h @@ -0,0 +1,81 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, FBSDKBetaLoginExperience) +{ + FBSDKBetaLoginExperienceEnabled, + FBSDKBetaLoginExperienceRestricted, +} NS_SWIFT_NAME(BetaLoginExperience); + +/// A configuration to use for modifying the default behavior of a login attempt. +NS_SWIFT_NAME(LoginConfiguration) +@interface FBSDKLoginConfiguration : NSObject + +/// The nonce that the configuration was created with. +/// A unique nonce will be used if none is provided to the initializer. +@property (nonatomic, readonly, copy) NSString *nonce; + +/// The beta login experience preference. Defaults to `.enabled`. +@property (nonatomic, readonly) FBSDKBetaLoginExperience betaLoginExperience; + +/// The requested permissions for the login attempt. Defaults to an empty set. +@property (nonatomic, readonly, copy) NSSet *requestedPermissions; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + Attempts to initialize a new configuration with the expected parameters. + + @param permissions the requested permissions for the login attempt. Permissions must be an array of strings that do not contain whitespace. + The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. + @param betaLoginExperience determines whether the login attempt should use the beta experience. + @param nonce an optional nonce to use for the login attempt. A valid nonce must be a non-empty string without whitespace. + Creation of the configuration will fail if the nonce is invalid. + */ +- (nullable instancetype)initWithPermissions:(NSArray *)permissions + betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience + nonce:(NSString *)nonce +NS_REFINED_FOR_SWIFT; + +/** + Attempts to initialize a new configuration with the expected parameters. + + @param permissions the requested permissions for the login attempt. Permissions must be an array of strings that do not contain whitespace. + The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. + @param betaLoginExperience determines whether the login attempt should use the beta experience. + */ +- (nullable instancetype)initWithPermissions:(NSArray *)permissions + betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +NS_REFINED_FOR_SWIFT; + +/** + Attempts to initialize a new configuration with the expected parameters. + + @param betaLoginExperience determines whether the login attempt should use the beta experience. + */ +- (nullable instancetype)initWithBetaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +NS_REFINED_FOR_SWIFT; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m new file mode 100644 index 0000000000..9a94019703 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m @@ -0,0 +1,103 @@ +// 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 "TargetConditionals.h" + +#if !TARGET_OS_TV + +#import "FBSDKLoginConfiguration.h" + +#import "FBSDKNonceUtility.h" + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +@implementation FBSDKLoginConfiguration + +- (nullable instancetype)initWithBetaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +{ + return [[FBSDKLoginConfiguration alloc] initWithPermissions:@[] + betaLoginExperience:betaLoginExperience]; +} + +- (nullable instancetype)initWithPermissions:(NSArray *)permissions + betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +{ + return [[FBSDKLoginConfiguration alloc] initWithPermissions:permissions + betaLoginExperience:betaLoginExperience + nonce:NSUUID.UUID.UUIDString]; +} + +- (nullable instancetype)initWithPermissions:(NSArray *)permissions + betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience + nonce:(NSString *)nonce +{ + if (![FBSDKNonceUtility isValidNonce:nonce]) { + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + formatString:@"Invalid nonce:%@ provided to login configuration. Returning nil.", nonce]; + return nil; + } + + NSSet *permissionsSet = [NSSet setWithArray:permissions]; + BOOL arePermissionsValid = [FBSDKLoginConfiguration _arePermissionsValid:permissionsSet + forBetaLoginExperienceStatus:betaLoginExperience]; + if (!arePermissionsValid) { + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + formatString:@"Invalid combination of permissions and beta experience preference provided to login configuration. The only permissions allowed when the `betaLoginExperince` is `.restricted` are 'email' and 'public_profile'. Returning nil."]; + return nil; + } + + if ((self = [super init])) { + _requestedPermissions = permissionsSet; + _betaLoginExperience = betaLoginExperience; + _nonce = nonce; + } + + return self; +} + +- (instancetype)init +{ + if ((self = [super init])) { + _requestedPermissions = [NSSet set]; + _betaLoginExperience = FBSDKBetaLoginExperienceEnabled; + _nonce = NSUUID.UUID.UUIDString; + } + + return self; +} + ++ (BOOL) _arePermissionsValid:(NSSet *)permissions + forBetaLoginExperienceStatus:(FBSDKBetaLoginExperience)betaLoginExperience +{ + if (betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { + NSSet *validPermissions = [NSSet setWithArray:@[@"email", @"public_profile"]]; + NSSet *combined = [permissions setByAddingObjectsFromSet:validPermissions]; + + return (permissions.count == 0) || (combined.count <= validPermissions.count); + } + + return YES; +} + +@end + +#endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h index 7ae9c67e20..eef290a08e 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h @@ -26,6 +26,7 @@ #if !TARGET_OS_TV #import "FBSDKLoginButton.h" + #import "FBSDKLoginConfiguration.h" #import "FBSDKLoginManager.h" #import "FBSDKLoginManagerLoginResult.h" #import "FBSDKLoginTooltipView.h" diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index f9f17caa54..45b052791d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -18,6 +18,8 @@ #import +#import "FBSDKLoginConfiguration.h" + NS_ASSUME_NONNULL_BEGIN #if TARGET_OS_TV @@ -32,9 +34,11 @@ NS_ASSUME_NONNULL_BEGIN // The way to fix this is to remove extensions of ObjC types in Swift. @class LoginManagerLoginResult; +@class FBSDKLoginConfiguration; typedef NS_ENUM(NSUInteger, LoginBehavior) { LoginBehaviorBrowser }; typedef NS_ENUM(NSUInteger, DefaultAudience) { DefaultAudienceFriends }; + typedef void (^LoginManagerLoginResultBlock)(LoginManagerLoginResult *_Nullable result, NSError *_Nullable error); @@ -48,6 +52,11 @@ typedef void (^LoginManagerLoginResultBlock)(LoginManagerLoginResult *_Nullable handler:(nullable LoginManagerLoginResultBlock)handler NS_SWIFT_NAME(logIn(permissions:from:handler:)); +- (void)logInFromViewController:(nullable UIViewController *)viewController + configuration:(FBSDKLoginConfiguration *)configuration + completion:(LoginManagerLoginResultBlock)completion +NS_SWIFT_NAME(logIn(from:configuration:completion:)); + @end #else @@ -140,10 +149,33 @@ NS_SWIFT_NAME(LoginManager) on a previous login will return an error. */ - (void)logInWithPermissions:(NSArray *)permissions - fromViewController:(nullable UIViewController *)fromViewController - handler:(nullable FBSDKLoginManagerLoginResultBlock)handler + fromViewController:(nullable UIViewController *)fromViewController + handler:(nullable FBSDKLoginManagerLoginResultBlock)handler NS_SWIFT_NAME(logIn(permissions:from:handler:)); +/** + Logs the user in or authorizes additional permissions. + + @param viewController the view controller from which to present the login UI. + @param configuration the login configuration to use. + @param completion the login completion handler. + + Use this method when asking for permissions. You should only ask for permissions when they + are needed and the value should be explained to the user. You can inspect the result's `declinedPermissions` to also + provide more information to the user if they decline permissions. + + This method will present a UI to the user. To reduce unnecessary app switching, you should typically check if + `FBSDKAccessToken.currentAccessToken` already contains the permissions you need. If it does, you probably + do not need to call this method. + + You can only perform one login call at a time. Calling a login method before the completion handler is called + on a previous login will result in an error. + */ +- (void)logInFromViewController:(nullable UIViewController *)viewController + configuration:(FBSDKLoginConfiguration *)configuration + completion:(FBSDKLoginManagerLoginResultBlock)completion +NS_SWIFT_NAME(logIn(from:configuration:completion:)); + /** Logs the user in with the given deep link url. Will only log user in if the given url contains valid login data. @param url the deep link url diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 1d76f71768..47caea6614 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -82,16 +82,26 @@ - (instancetype)init return self; } -- (void)logInWithPermissions:(NSArray *)permissions - fromViewController:(UIViewController *)fromViewController - handler:(FBSDKLoginManagerLoginResultBlock)handler +- (void)logInFromViewController:(UIViewController *)viewController + configuration:(FBSDKLoginConfiguration *)configuration + completion:(FBSDKLoginManagerLoginResultBlock)completion { if (![self validateLoginStartState]) { return; } - self.fromViewController = fromViewController; - NSSet *permissionSet = [NSSet setWithArray:permissions]; - [self logInWithPermissions:permissionSet handler:handler]; + self.fromViewController = viewController; + [self logInWithPermissions:configuration.requestedPermissions handler:completion]; +} + +- (void)logInWithPermissions:(NSArray *)permissions + fromViewController:(UIViewController *)viewController + handler:(FBSDKLoginManagerLoginResultBlock)handler +{ + FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:permissions + betaLoginExperience:FBSDKBetaLoginExperienceEnabled]; + [self logInFromViewController:viewController + configuration:config + completion:handler]; } - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FBSDKLoginManagerLoginResultBlock)handler diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.h new file mode 100644 index 0000000000..02246bfa05 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.h @@ -0,0 +1,36 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(Nonce) +@interface FBSDKNonceUtility: NSObject + +/** + Checks if a string represents a valid nonce. + */ ++ (BOOL)isValidNonce:(NSString *)nonce; + ++ (instancetype)new NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m new file mode 100644 index 0000000000..829e492b2c --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m @@ -0,0 +1,34 @@ +// 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 "FBSDKNonceUtility.h" + +#import "FBSDKCoreKit+Internal.h" + +@implementation FBSDKNonceUtility + ++ (BOOL)isValidNonce:(NSString *)nonce +{ + NSString *string = [FBSDKTypeUtility stringValue:nonce]; + NSRange whiteSpaceRange = [string rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]]; + BOOL containsWhitespace = (whiteSpaceRange.location != NSNotFound); + + return (([string length] > 0) && !containsWhitespace); +} + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift new file mode 100644 index 0000000000..e9ca6c5703 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift @@ -0,0 +1,45 @@ +// Copyright (c) 2016-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 Foundation + +@available(tvOS, unavailable) +public extension LoginConfiguration { + + /** + Attempts to allocate and initialize a new configuration with the expected parameters. + + - parameter permissions: The requested permissions for the login attempt. + The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. + Defaults to an empty `Permission` array. + - parameter beta: Determines whether the login attempt should use the beta experience. Defaults to `.enabled` + - parameter nonce: An optional nonce to use for the login attempt. A valid nonce must be an alphanumeric string without whitespace. + Creation of the configuration will fail if the nonce is invalid. Defaults to a `UUID` string. + */ + convenience init?( + permissions: Set = [], + betaLoginExperience: BetaLoginExperience = .enabled, + nonce: String = UUID().uuidString + ) { + self.init( + __permissions: permissions.map { $0.name }, + betaLoginExperience: betaLoginExperience, + nonce: nonce + ) + } +} diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift index 5e8e8f0c7f..5671af88df 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift @@ -79,30 +79,98 @@ public extension LoginManager { /** Logs the user in or authorizes additional permissions. - Use this method when asking for read permissions. You should only ask for permissions when they - are needed and explain the value to the user. You can inspect the `declinedPermissions` in the result to also + Use this method when asking for permissions. You should only ask for permissions when they + are needed and the value should be explained to the user. You can inspect the result's `declinedPermissions` to also provide more information to the user if they decline permissions. - This method will present UI the user. You typically should check if `AccessToken.current` already - contains the permissions you need before asking to reduce unnecessary app switching. + This method will present a UI to the user. To reduce unnecessary app switching, you should typically check if + `AccessToken.current` already contains the permissions you need. If it does, you probably + do not need to call this method. + + You can only perform one login call at a time. Calling a login method before the completion handler is called + on a previous login will result in an error. - parameter permissions: Array of read permissions. Default: `[.PublicProfile]` - parameter viewController: Optional view controller to present from. Default: topmost view controller. - parameter completion: Optional callback. */ - func logIn(permissions: [Permission] = [.publicProfile], - viewController: UIViewController? = nil, - completion: LoginResultBlock? = nil) { + func logIn( + permissions: [Permission] = [.publicProfile], + viewController: UIViewController? = nil, + completion: LoginResultBlock? = nil + ) { self.logIn(permissions: permissions.map { $0.name }, from: viewController, handler: sdkCompletion(completion)) } + /** + Logs the user in or authorizes additional permissions. + + Use this method when asking for permissions. You should only ask for permissions when they + are needed and the value should be explained to the user. You can inspect the result's `declinedPermissions` to also + provide more information to the user if they decline permissions. + + This method will present a UI to the user. To reduce unnecessary app switching, you should typically check if + `AccessToken.current` already contains the permissions you need. If it does, you probably + do not need to call this method. + + You can only perform one login call at a time. Calling a login method before the completion handler is called + on a previous login will result in an error. + + - parameter viewController: Optional view controller to present from. Default: topmost view controller. + - parameter configuration the login configuration to use. + - parameter completion: Optional callback. + */ + func logIn( + viewController: UIViewController? = nil, + configuration: LoginConfiguration, + completion: @escaping LoginResultBlock + ) { + let _completion = { (result: LoginManagerLoginResult?, error: Error?) in + let result = LoginResult(result: result, error: error) + completion(result) + } + self.logIn(from: viewController, configuration: configuration, completion: _completion) + } + + /** + Logs the user in or authorizes additional permissions. + + Use this method when asking for permissions. You should only ask for permissions when they + are needed and the value should be explained to the user. You can inspect the result's `declinedPermissions` to also + provide more information to the user if they decline permissions. + + This method will present a UI to the user. To reduce unnecessary app switching, you should typically check if + `AccessToken.current` already contains the permissions you need. If it does, you probably + do not need to call this method. + + You can only perform one login call at a time. Calling a login method before the completion handler is called + on a previous login will result in an error. + + - parameter configuration the login configuration to use. + - parameter completion: Optional callback. + */ + func logIn( + configuration: LoginConfiguration, + completion: @escaping LoginResultBlock + ) { + let _completion = { (result: LoginManagerLoginResult?, error: Error?) in + let result = LoginResult(result: result, error: error) + completion(result) + } + self.logIn(from: nil, configuration: configuration, completion: _completion) + } + private func sdkCompletion(_ completion: LoginResultBlock?) -> LoginManagerLoginResultBlock? { - guard let completion = completion else { + guard let original = completion else { return nil } + return convertedResultHandler(original) + } + + private func convertedResultHandler(_ original: @escaping LoginResultBlock) -> LoginManagerLoginResultBlock { return { (result: LoginManagerLoginResult?, error: Error?) in let result = LoginResult(result: result, error: error) - completion(result) + original(result) } } } diff --git a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKLoginConfiguration.h b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKLoginConfiguration.h new file mode 120000 index 0000000000..57ba266e9d --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKLoginConfiguration.h @@ -0,0 +1 @@ +../FBSDKLoginConfiguration.h \ No newline at end of file diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h new file mode 100644 index 0000000000..c2adc2e24f --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -0,0 +1,22 @@ +// 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 "FBSDKLoginConfiguration.h" +#import "FBSDKNonceUtility.h" diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 2860ec4fb8..9ee29ac52c 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -219,7 +219,7 @@ - (void)testOpenURLReauthNoPermissionsIsNotCancelled XCTAssertNotNil(result.token); }] validateReauthentication:[OCMArg any] withResult:[OCMArg any]]; - [target setRequestedPermissions:nil]; + [(FBSDKLoginManager *)target setRequestedPermissions:nil]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift new file mode 100644 index 0000000000..c94c158a57 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift @@ -0,0 +1,108 @@ +// 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 XCTest + +class LoginConfigurationTests: XCTestCase { + + func testDefaults() { + guard let config = LoginConfiguration() else { + return XCTFail("Should be able to create a config with default arguments") + } + + XCTAssertEqual( + config.requestedPermissions, + [], + "A config should be created with default requested permissions" + ) + XCTAssertEqual( + config.betaLoginExperience, + .enabled, + "Beta login experience should default to enabled when unspecified" + ) + XCTAssertNotNil( + config.nonce, + "A config should be created with a default nonce" + ) + } + + func testCreatingWithNonceString() { + let nonce = "12345" + let config = LoginConfiguration(nonce: nonce) + XCTAssertEqual( + config?.nonce, + nonce, + "Should create a configuration with the provided nonce string" + ) + } + + func testCreatingWithInvalidNonce() { + XCTAssertNil( + LoginConfiguration(nonce: " "), + "Should not create a login configuration with an invalid nonce" + ) + } + + func testCreatingWithBetaLoginExperience() { + [ + BetaLoginExperience.enabled, + .restricted + ].forEach { preference in + let config = LoginConfiguration(betaLoginExperience: preference) + XCTAssertEqual( + config?.betaLoginExperience, + preference, + "Should create a configuration with the provided beta login experience preference" + ) + } + } + + func testCreatingWithRequestedPermissions() { + let permissions = Set([Permission.email, .userLikes]) + let config = LoginConfiguration(permissions: permissions) + + XCTAssertEqual( + config?.requestedPermissions, + Set(permissions.map { $0.name }), + "Should create a configuration with the provided beta login experience preference" + ) + } + + func testCreatingWithPermissionsForRestrictedBetaLoginExperience() { + let allowedPermissions = Set([Permission.email]) + let disallowedPermissions = Set([Permission.userBirthday, .userPosts]) + + var configuration = LoginConfiguration( + permissions: disallowedPermissions, + betaLoginExperience: .restricted + ) + XCTAssertNil( + configuration, + "Should not create a configuration with permissions that are disallowed based on the beta login experience preference" + ) + + configuration = LoginConfiguration( + permissions: allowedPermissions, + betaLoginExperience: .restricted + ) + XCTAssertNotNil( + configuration, + "Should create a configuration with permissions that are allowed based on the beta login experience preference" + ) + } +} diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift new file mode 100644 index 0000000000..7fc8b44535 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift @@ -0,0 +1,49 @@ +// 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 XCTest + +class NonceTests: XCTestCase { + + func testInvalidNonces() { + [ + "", + "foo bar" + ].forEach { nonce in + XCTAssertFalse( + Nonce.isValidNonce(nonce), + "Should not consider: \(nonce) to be a valid nonce" + ) + } + } + + func testValidNonces() { + [ + "123", + "foo", + "asdfasdfasdfasdfasdfasdfasdf" + ].forEach { nonce in + XCTAssertTrue( + Nonce.isValidNonce(nonce), + "Should consider: \(nonce) to be a valid nonce" + ) + } + } + + +} From ca3d7b516374e5ab603e4469a594ee97ae69dec7 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 13:27:02 -0800 Subject: [PATCH 135/227] Updating LoginButton to use configurable login Summary: Adds ability to set a beta login experience preference and a custom nonce to a LoginButton Reviewed By: ppansy Differential Revision: D25229583 fbshipit-source-id: 769d619aa237c221498eb6729beaaf05b3378fff --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h | 9 +++++++++ FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m | 17 +++++++++++++++++ .../FBSDKLoginKit/FBSDKLoginConfiguration.h | 1 + 3 files changed, 27 insertions(+) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h index c3adca5d32..6846fa6f8c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h @@ -98,6 +98,15 @@ NS_SWIFT_NAME(FBLoginButton) Gets or sets the desired tooltip color style. */ @property (assign, nonatomic) FBSDKTooltipColorStyle tooltipColorStyle; +/** + Gets or sets the desired beta login experience to use for login attempts. Defaults to `.enabled` + */ +@property (assign, nonatomic) FBSDKBetaLoginExperience betaLoginExperience; +/** + Gets or sets an optional nonce to use for login attempts. A valid nonce must be a non-empty string without whitespace. + An invalid nonce will not be set. Instead, default unique nonces will be used for login attempts. + */ +@property (assign, nonatomic, nullable) NSString *nonce; @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index 98ddb4acc6..e02d436b54 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -29,6 +29,7 @@ #endif #import "FBSDKLoginTooltipView.h" + #import "FBSDKNonceUtility.h" static const CGFloat kFBLogoSize = 16.0; static const CGFloat kFBLogoLeftMargin = 6.0; @@ -77,6 +78,15 @@ - (UIFont *)defaultFont } } +- (void)setNonce:(NSString *)nonce +{ + if ([FBSDKNonceUtility isValidNonce:nonce]) { + _nonce = nonce; + } else { + _nonce = nil; + } +} + #pragma mark - UIView - (void)didMoveToWindow @@ -279,6 +289,13 @@ - (void)_buttonPressed:(id)sender } }; + FBSDKLoginConfiguration *loginConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions + betaLoginExperience:self.betaLoginExperience + nonce:self.nonce]; + [_loginManager logInFromViewController:[FBSDKInternalUtility viewControllerForView:self] + configuration:loginConfig + completion:handler]; + [_loginManager logInWithPermissions:self.permissions fromViewController:[FBSDKInternalUtility viewControllerForView:self] handler:handler]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h index 8162e19c3d..4db5f9daf2 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN +/// The login experience style to use for a login attempt typedef NS_ENUM(NSUInteger, FBSDKBetaLoginExperience) { FBSDKBetaLoginExperienceEnabled, From e5e7067f58fb8019afdf5b18e479b86b74ef1e1a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 13:27:02 -0800 Subject: [PATCH 136/227] ID Token signature verification Summary: According to the openid connect spec (https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation), the client must validate the ID token. One of the required verification steps is to validate the signature using the specified algorithm, in our case this will be RS256. The diff add signature verification for ID token. An ID token can only be created if it has a valid signature. Reviewed By: ppansy Differential Revision: D24716889 fbshipit-source-id: 203116fdc8564453214a642b27abaf1f297fd280 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 40 ++-- ...DKIDToken.h => FBSDKAuthenticationToken.h} | 34 ++- .../FBSDKLoginKit/FBSDKAuthenticationToken.m | 194 ++++++++++++++++++ FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h | 1 + .../FBSDKLoginKit/Internal/FBSDKIDToken.m | 85 -------- .../Internal/FBSDKLoginCompletion.m | 8 +- .../include/FBSDKAuthenticationToken.h | 1 + .../FBSDKAuthenticationTokenTests.m | 145 +++++++++++++ .../FBSDKLoginKitTests/FBSDKIDTokenTests.m | 66 ------ 9 files changed, 393 insertions(+), 181 deletions(-) rename FBSDKLoginKit/FBSDKLoginKit/{Internal/FBSDKIDToken.h => FBSDKAuthenticationToken.h} (58%) create mode 100644 FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m delete mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m create mode 120000 FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m delete mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 1b9ee96e37..9d98dfa794 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -135,11 +135,11 @@ C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; - C66FC2A72553748C00A7909C /* FBSDKIDTokenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC29D2553748C00A7909C /* FBSDKIDTokenTests.m */; }; - C66FC2FE255376D200A7909C /* FBSDKIDToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKIDToken.h */; }; - C66FC2FF255376D200A7909C /* FBSDKIDToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKIDToken.m */; }; - C66FC338255377BF00A7909C /* FBSDKIDToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKIDToken.h */; }; - C66FC340255377F400A7909C /* FBSDKIDToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKIDToken.m */; }; + C66FC2A72553748C00A7909C /* FBSDKAuthenticationTokenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC29D2553748C00A7909C /* FBSDKAuthenticationTokenTests.m */; }; + C66FC2FE255376D200A7909C /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C66FC2FF255376D200A7909C /* FBSDKAuthenticationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */; }; + C66FC338255377BF00A7909C /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C66FC340255377F400A7909C /* FBSDKAuthenticationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -173,6 +173,10 @@ F4EC46052575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */; }; F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; + F4EC48462576C64600D2F47B /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4EC48572576C64700D2F47B /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4EC48662576C6B200D2F47B /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F4EC486E2576C6B300D2F47B /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67923EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67A23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67B23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -387,9 +391,9 @@ 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; - C66FC29D2553748C00A7909C /* FBSDKIDTokenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKIDTokenTests.m; sourceTree = ""; }; - C66FC2FC255376D100A7909C /* FBSDKIDToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKIDToken.h; sourceTree = ""; }; - C66FC2FD255376D100A7909C /* FBSDKIDToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKIDToken.m; sourceTree = ""; }; + C66FC29D2553748C00A7909C /* FBSDKAuthenticationTokenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenTests.m; sourceTree = ""; }; + C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationToken.h; sourceTree = ""; }; + C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationToken.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -566,8 +570,6 @@ 9D03E8271A72DCA700207493 /* Internal */ = { isa = PBXGroup; children = ( - C66FC2FC255376D100A7909C /* FBSDKIDToken.h */, - C66FC2FD255376D100A7909C /* FBSDKIDToken.m */, C6CE2BC124EB732C00CF2EB6 /* FBSDKReferralManager+Internal.h */, 0B9DBEFD207C04FF00662776 /* FBSDKDeviceLoginCodeInfo+Internal.h */, 0B9DBEF7207C04FF00662776 /* FBSDKDeviceLoginManagerResult+Internal.h */, @@ -622,6 +624,8 @@ 9D9DB8DB1A114E500086167B /* FBSDKLoginKit */ = { isa = PBXGroup; children = ( + C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */, + C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */, C681486124F866EA004EED1A /* FBSDKReferralCode.h */, C681486B24F866EA004EED1A /* FBSDKReferralCode.m */, C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */, @@ -668,7 +672,7 @@ 9D9DB8E81A114E500086167B /* FBSDKLoginKitTests */ = { isa = PBXGroup; children = ( - C66FC29D2553748C00A7909C /* FBSDKIDTokenTests.m */, + C66FC29D2553748C00A7909C /* FBSDKAuthenticationTokenTests.m */, C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */, 6B6276321A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.h */, 6B6276331A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m */, @@ -710,8 +714,10 @@ 0B9DBF7B207C201F00662776 /* FBSDKLoginConstants.h in Headers */, 0B9DBF38207C061D00662776 /* FBSDKDeviceLoginCodeInfo.h in Headers */, 0B9DBF3A207C061D00662776 /* FBSDKDeviceLoginManager.h in Headers */, + F4EC48462576C64600D2F47B /* FBSDKAuthenticationToken.h in Headers */, 0B9DBF3B207C061D00662776 /* FBSDKDeviceLoginManagerResult.h in Headers */, F4ECC67B23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, + F4EC48662576C6B200D2F47B /* FBSDKLoginConfiguration.h in Headers */, 0B9DBF7C207C211900662776 /* FBSDKCoreKit+Internal.h in Headers */, 0B9DBF3C207C061D00662776 /* FBSDKDeviceLoginCodeInfo+Internal.h in Headers */, F462DC0E23B958E000FFCECA /* FBSDKLoginKit.h in Headers */, @@ -727,8 +733,10 @@ 0B9DBF78207C200500662776 /* FBSDKLoginConstants.h in Headers */, 0B9DBF48207C07C600662776 /* FBSDKDeviceLoginCodeInfo.h in Headers */, 0B9DBF4A207C07C600662776 /* FBSDKDeviceLoginManager.h in Headers */, + F4EC48572576C64700D2F47B /* FBSDKAuthenticationToken.h in Headers */, 0B9DBF4B207C07C600662776 /* FBSDKDeviceLoginManagerResult.h in Headers */, F4ECC67C23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, + F4EC486E2576C6B300D2F47B /* FBSDKLoginConfiguration.h in Headers */, 0B9DBF7D207C212500662776 /* FBSDKCoreKit+Internal.h in Headers */, 0B9DBF4C207C07C600662776 /* FBSDKDeviceLoginCodeInfo+Internal.h in Headers */, F462DC0F23B958E100FFCECA /* FBSDKLoginKit.h in Headers */, @@ -746,7 +754,7 @@ 0B9DBF0F207C051800662776 /* FBSDKDeviceLoginManager.h in Headers */, 818EB4321D1A283100252851 /* _FBSDKLoginRecoveryAttempter.h in Headers */, C6CE2BC324EB73B500CF2EB6 /* FBSDKReferralManager.h in Headers */, - C66FC338255377BF00A7909C /* FBSDKIDToken.h in Headers */, + C66FC338255377BF00A7909C /* FBSDKAuthenticationToken.h in Headers */, C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */, 818EB4331D1A283100252851 /* FBSDKCoreKit+Internal.h in Headers */, 818EB4341D1A283100252851 /* FBSDKLoginConstants.h in Headers */, @@ -779,7 +787,7 @@ C6CE2BBF24EB72F200CF2EB6 /* FBSDKReferralManager.h in Headers */, 9DBC4C3C1A782E2000816FE8 /* FBSDKCoreKit+Internal.h in Headers */, 9D03E8341A72DF5800207493 /* FBSDKLoginConstants.h in Headers */, - C66FC2FE255376D200A7909C /* FBSDKIDToken.h in Headers */, + C66FC2FE255376D200A7909C /* FBSDKAuthenticationToken.h in Headers */, 9D9DB8DF1A114E500086167B /* FBSDKLoginKit.h in Headers */, F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */, 9D03E8251A72D89100207493 /* FBSDKLoginManagerLoginResult.h in Headers */, @@ -1141,7 +1149,7 @@ F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C625B49C24F97DF0003DCE23 /* FBSDKReferralManagerLogger.m in Sources */, F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */, - C66FC340255377F400A7909C /* FBSDKIDToken.m in Sources */, + C66FC340255377F400A7909C /* FBSDKAuthenticationToken.m in Sources */, 818EB42A1D1A283100252851 /* FBSDKLoginManagerLoginResult.m in Sources */, C681486F24F86806004EED1A /* FBSDKReferralCode.m in Sources */, 818EB42B1D1A283100252851 /* FBSDKLoginTooltipView.m in Sources */, @@ -1172,7 +1180,7 @@ F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */, F46FA65A245347580060C902 /* FBLoginButton.swift in Sources */, - C66FC2FF255376D200A7909C /* FBSDKIDToken.m in Sources */, + C66FC2FF255376D200A7909C /* FBSDKAuthenticationToken.m in Sources */, 9D03E8261A72D89100207493 /* FBSDKLoginManagerLoginResult.m in Sources */, C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */, 9DBA6A2A1A80252F00B4DE6A /* FBSDKLoginTooltipView.m in Sources */, @@ -1196,7 +1204,7 @@ F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */, 9D641F841A7B69160048F563 /* FBSDKLoginManagerTests.m in Sources */, F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, - C66FC2A72553748C00A7909C /* FBSDKIDTokenTests.m in Sources */, + C66FC2A72553748C00A7909C /* FBSDKAuthenticationTokenTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h similarity index 58% rename from FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h rename to FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h index 8b0cd7d7c4..9f167516ff 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h @@ -18,35 +18,49 @@ #import +#import "FBSDKLoginConfiguration.h" + +NS_ASSUME_NONNULL_BEGIN + /** Represent an ID Token used for OpenID connect (OIDC) protocal */ -NS_SWIFT_NAME(IDToken) -@interface FBSDKIDToken : NSObject +NS_SWIFT_NAME(AuthenticationToken) +@interface FBSDKAuthenticationToken : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; /** - The decoded header of the ID token + The "global" authentication token that represents the currently logged in user. + + The `currentAuthenticationToken` represents the authentication token of the + current user and can be used by a client to verify an authentication attempt. */ -@property (nonatomic, copy, readonly) NSDictionary *header; +@property (class, nonatomic, copy, nullable) FBSDKAuthenticationToken *currentAuthenticationToken; /** - The decoded claims of the ID token + The raw token string from the authentication response */ -@property (nonatomic, copy, readonly) NSDictionary *claims; +@property (nonatomic, copy, readonly) NSString *tokenString; /** - The signature of the ID token + The nonce from the decoded authentication response */ -@property (nonatomic, copy, readonly) NSString *signature; +@property (nonatomic, copy, readonly) NSString *nonce; + +/** + The beta login experience preference used for the login attempt that resulted in the creation of the token + */ +@property (nonatomic, readonly) FBSDKBetaLoginExperience betaLoginExperience; /** Initializes a new instance if the ID token is valid. Otherwise returns nil. An ID Token is verified based of the OpenID connect standard. - @param idTokenString the raw ID token string + @param tokenString the raw ID token string */ -- (instancetype)initWithTokenString:(NSString *)idTokenString; +- (instancetype)initWithTokenString:(NSString *)tokenString; @end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m new file mode 100644 index 0000000000..10529d4526 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m @@ -0,0 +1,194 @@ +// 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 "FBSDKAuthenticationToken.h" + +#import + +#if SWIFT_PACKAGE +@import FBSDKCoreKit; +#else + #import +#endif + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +#import + +#import + +static FBSDKAuthenticationToken *g_currentAuthenticationToken; + +@implementation FBSDKAuthenticationToken +{ + NSString *_cert; + NSDictionary *_claims; + NSString *_signature; +} + +- (instancetype)initWithTokenString:(NSString *)tokenString +{ + if (!tokenString || tokenString.length == 0) { + return nil; + } + + NSArray *segments = [tokenString componentsSeparatedByString:@"."]; + if (segments.count != 3) { + return nil; + } + + if (self = [super init]) { + NSString *encodedHeader = [FBSDKTypeUtility array:segments objectAtIndex:0]; + NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; + _signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; + + if (![self verifySignature:_signature + header:encodedHeader + claims:encodedClaims]) { + return nil; + } + + [self setClaimsWithEncodedString:encodedClaims]; + } + + return self; +} + ++ (FBSDKAuthenticationToken *)currentAuthenticationToken +{ + return g_currentAuthenticationToken; +} + ++ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token +{ + if (token != g_currentAuthenticationToken) { + g_currentAuthenticationToken = token; + } +} + +- (void)setClaimsWithEncodedString:(NSString *)encodedClaims +{ + NSError *error; + NSData *claimsData = [FBSDKBase64 decodeAsData:encodedClaims]; + + if (claimsData) { + NSDictionary *decodedClaims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; + if (!error) { + // TODO(T78739428): verify claims + + _claims = decodedClaims; + } + } +} + +- (BOOL)verifySignature:(NSString *)signature + header:(NSString *)header + claims:(NSString *)claims +{ + NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:signature]]; + NSString *signedString = [NSString stringWithFormat:@"%@.%@", header, claims]; + NSData *signedData = [signedString dataUsingEncoding:NSASCIIStringEncoding]; + SecKeyRef publicKey = [self getPublicKey]; + + if (publicKey && signatureData && signedData) { + OSStatus status = -1; + + size_t signatureBytesSize = SecKeyGetBlockSize(publicKey); + const void *signatureBytes = signatureData.bytes; + + size_t digestSize = CC_SHA256_DIGEST_LENGTH; + uint8_t digestBytes[digestSize]; + CC_SHA256(signedData.bytes, (CC_LONG)signedData.length, digestBytes); + + status = SecKeyRawVerify( + publicKey, + kSecPaddingPKCS1SHA256, + digestBytes, + digestSize, + signatureBytes, + signatureBytesSize + ); + return status == errSecSuccess; + } + return NO; +} + +- (NSString *)getCertificate +{ + // TODO(T79340096): replace with certificate retrieved from crypto keychain service + return _cert; +} + +- (SecKeyRef)getPublicKey +{ + SecKeyRef publicKey = nil; + NSData *certData = [FBSDKBase64 decodeAsData:[self getCertificate]]; + SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certData); + + if (cert) { + SecPolicyRef policy = SecPolicyCreateBasicX509(); + OSStatus status = -1; + SecTrustRef trust; + + status = SecTrustCreateWithCertificates(cert, policy, &trust); + + if (status == errSecSuccess && trust) { + publicKey = SecTrustCopyPublicKey(trust); + } + + CFRelease(policy); + CFRelease(cert); + } + + return publicKey; +} + ++ (NSString *)base64FromBase64Url:(NSString *)base64Url +{ + NSString *base64 = [base64Url stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; + base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; + + return base64; +} + +#pragma mark - Test methods + +#if DEBUG + ++ (instancetype)emptyInstance +{ + return [super new]; +} + +- (void)setCertificate:(NSString *)certificate +{ + _cert = certificate; +} + +- (NSDictionary *)claims +{ + return _claims; +} + +#endif + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h index eef290a08e..becc869dbf 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h @@ -18,6 +18,7 @@ #import +#import "FBSDKAuthenticationToken.h" #import "FBSDKCoreKitImport.h" #import "FBSDKDeviceLoginCodeInfo.h" #import "FBSDKDeviceLoginManager.h" diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m deleted file mode 100644 index eac4bbeadc..0000000000 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKIDToken.m +++ /dev/null @@ -1,85 +0,0 @@ -// 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 "FBSDKIDToken.h" - -#import - -#if SWIFT_PACKAGE -@import FBSDKCoreKit; -#else - #import -#endif - -#ifdef FBSDKCOCOAPODS - #import -#else - #import "FBSDKCoreKit+Internal.h" -#endif - -@implementation FBSDKIDToken - -- (instancetype)initWithTokenString:(NSString *)idTokenString -{ - if (!idTokenString || idTokenString.length == 0) { - return nil; - } - - NSArray *segments = [idTokenString componentsSeparatedByString:@"."]; - if (segments.count != 3) { - return nil; - } - - if (self = [super init]) { - NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; - - // TODO(T78739428): verify signature - - [self setClaimsWithEncodedString:encodedClaims]; - } - - return self; -} - -- (void)setClaimsWithEncodedString:(NSString *)encodedClaims -{ - NSError *error; - NSData *claimsData = [FBSDKBase64 decodeAsData:encodedClaims]; - - if (claimsData) { - NSDictionary *decodedClaims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; - if (!error) { - // TODO(T78739428): verify claims - - _claims = decodedClaims; - } - } -} - -#pragma mark - Test methods - -#if DEBUG - -+ (instancetype)emptyInstance -{ - return [super new]; -} - -#endif - -@end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 18c2471b6e..df1ef4b939 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -28,7 +28,7 @@ #import #endif - #import "FBSDKIDToken.h" + #import "FBSDKAuthenticationToken.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" @@ -126,7 +126,7 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; - FBSDKIDToken *idToken = [[FBSDKIDToken alloc] initWithTokenString:parameters[@"id_token"]]; + FBSDKAuthenticationToken *idToken = [[FBSDKAuthenticationToken alloc] initWithTokenString:parameters[@"id_token"]]; if ([parameters[@"access_token"] length] > 0 || [parameters[@"nonce"] length] > 0 @@ -277,9 +277,9 @@ - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)ha [connection start]; } -- (void)setParametersWithIDToken:(FBSDKIDToken *)idToken +- (void)setParametersWithIDToken:(FBSDKAuthenticationToken *)idToken { - if (!idToken || !idToken.claims) { + if (!idToken) { return; } diff --git a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h new file mode 120000 index 0000000000..a45d0a2fcc --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h @@ -0,0 +1 @@ +../FBSDKAuthenticationToken.h \ No newline at end of file diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m new file mode 100644 index 0000000000..594f49eb95 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m @@ -0,0 +1,145 @@ +// 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 "FBSDKCoreKit+Internal.h" +#import "FBSDKAuthenticationToken.h" + +static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; + +static NSString *const _encodedHeader = @"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; + +static NSString *const _encodedClaims = @"eyJzdWIiOiIxMjM0IiwibmFtZSI6IlRlc3QgVXNlciIsImlzcyI6Imh0dHBzOi8vZmFjZWJvb2suY29tL2RpYWxvZy9vYXV0aCIsImF1ZCI6IjQzMjEiLCJub25jZSI6InNvbWVfbm9uY2UiLCJleHAiOjE1MTYyNTkwMjIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zb21lX3BpY3R1cmUiLCJpYXQiOjE1MTYyMzkwMjJ9"; + +static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; + +@interface FBSDKAuthenticationToken (Testing) + +- (void)setClaimsWithEncodedString:(NSString *)encodedClaims; + ++ (instancetype)emptyInstance; + +- (void)setCertificate:(NSString *)certificate; + ++ (NSString *)base64FromBase64Url:(NSString *)base64Url; + +- (BOOL)verifySignature:(NSString *)signature + header:(NSString *)header + claims:(NSString *)claims; + +- (NSDictionary *)claims; + +@end + +@interface FBSDKAuthenticationTokenTests : XCTestCase + +@end + +@implementation FBSDKAuthenticationTokenTests + +- (void)testDecodeValidClaims +{ + NSDictionary *expectedClaims = @{ + @"sub" : @"1234", + @"name" : @"Test User", + @"iss" : @"https://facebook.com/dialog/oauth", + @"aud" : @"4321", + @"nonce" : @"some_nonce", + @"exp" : @1516259022, + @"email" : @"email@email.com", + @"picture" : @"https://www.facebook.com/some_picture", + @"iat" : @1516239022, + }; + NSData *expectedClaimsData = [FBSDKTypeUtility dataWithJSONObject:expectedClaims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:expectedClaimsData]; + FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; + + [token setClaimsWithEncodedString:encodedClaims]; + XCTAssertEqualObjects(token.claims, expectedClaims); +} + +- (void)testCreateWithInvalidFormatTokenShouldFail +{ + FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token"]; + XCTAssertNil(token); +} + +- (void)testVerifyValidSignatureShouldSucceed +{ + FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; + [token setCertificate:_certificate]; + + XCTAssertTrue( + [token verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims] + ); +} + +- (void)testVerifyInvalidSignatureShouldFail +{ + FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; + [token setCertificate:_certificate]; + + NSString *invalidSignature = @"hH0uCpIx0BhjT_djfI52wPMp0sYuHAHYOes4GVasXykHsZAeuidFYshiCd8O-KpAo5m9jZWbXdaSN0JMbpBIJ9TwSk6e8bhX-N6BRKl3EZRby6SsZtK9J2X6mWomgMCfJZD54McLIdDQaTTtNsV1kgzm8iksywaT3f1GdicqlJPZn3m83xF3toSdfKdPoJJCpM7IidPru7gF8aZchkE1d-dUzZ9mV0CPfsl5lX4M64f470nm6PzyynAvyKwUBKO3v3x08V17NV8OkRAjtGPRhbs_d4B6ifEXS3piWUlxVm6w27nPbdmKeCqjV-WRfIJ6lOvumR2F26I1soEwtEWq9g"; + + XCTAssertFalse( + [token verifySignature:invalidSignature + header:_encodedHeader + claims:_encodedClaims] + ); +} + +- (void)testVerifySignatureWithInvalidCertificateShouldFail +{ + FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; + [token setCertificate:@"invalid_certification"]; + + XCTAssertFalse( + [token verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims] + ); +} + +- (void)testBase64FromBase64Url +{ + NSString *expectedString = @"testBase64FromBase64Url"; + NSData *data = [expectedString dataUsingEncoding:NSUTF8StringEncoding]; + NSString *base64UrlEncoded = [self base64URLEncodeData:data]; + NSString *base64Encoded = [FBSDKAuthenticationToken base64FromBase64Url:base64UrlEncoded]; + XCTAssertEqualObjects([FBSDKBase64 decodeAsString:base64Encoded], expectedString); + + // test nil + XCTAssertNil([FBSDKAuthenticationToken base64FromBase64Url:nil]); + + // test empty string + XCTAssertEqualObjects([FBSDKAuthenticationToken base64FromBase64Url:@""], @""); +} + +- (NSString *)base64URLEncodeData:(NSData *)data +{ + NSString *base64 = [FBSDKBase64 encodeData:data]; + NSString *base64URL = [base64 stringByReplacingOccurrencesOfString:@"+" withString:@"-"]; + base64URL = [base64URL stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; + return [base64URL stringByReplacingOccurrencesOfString:@"=" withString:@""]; +} + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m deleted file mode 100644 index 6bd8ec35d4..0000000000 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKIDTokenTests.m +++ /dev/null @@ -1,66 +0,0 @@ -// 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 "FBSDKCoreKit+Internal.h" -#import "FBSDKIDToken.h" - -@interface FBSDKIDToken (Testing) - -- (void)setClaimsWithEncodedString:(NSString *)encodedClaims; - -+ (instancetype)emptyInstance; - -@end - -@interface FBSDKIDTokenTests : XCTestCase - -@end - -@implementation FBSDKIDTokenTests - -- (void)testDecodeValidClaims -{ - NSDictionary *expectedClaims = @{ - @"sub" : @"1234", - @"name" : @"Test User", - @"iss" : @"https://facebook.com/dialog/oauth", - @"aud" : @"4321", - @"nonce" : @"some_nonce", - @"exp" : @1516259022, - @"email" : @"email@email.com", - @"picture" : @"https://www.facebook.com/some_picture", - @"iat" : @1516239022, - }; - NSData *expectedClaimsData = [FBSDKTypeUtility dataWithJSONObject:expectedClaims options:0 error:nil]; - NSString *encodedClaims = [FBSDKBase64 encodeData:expectedClaimsData]; - FBSDKIDToken *idToken = [FBSDKIDToken emptyInstance]; - - [idToken setClaimsWithEncodedString:encodedClaims]; - XCTAssertEqualObjects(idToken.claims, expectedClaims); -} - -- (void)testCreateWithInvalidFormatTokenShouldFail -{ - FBSDKIDToken *idToken = [[FBSDKIDToken alloc] initWithTokenString:@"invalid_id_token"]; - XCTAssertNil(idToken); -} - -@end From 711222f90c7f98475c05825d840b771dd4d35a9e Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 13:27:02 -0800 Subject: [PATCH 137/227] ID Token claims verification Summary: According to the openid connect spec (https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation), the client must validate the ID token in the manner specified in the spec. This diff add the needed verification for ID Token claims. Reviewed By: ppansy Differential Revision: D24842791 fbshipit-source-id: 7d7830726a2e4ebc2e6f442163c8a1be92d76371 --- .../FBSDKLoginKit/FBSDKAuthenticationToken.h | 10 +- .../FBSDKLoginKit/FBSDKAuthenticationToken.m | 29 +++- .../FBSDKLoginKit/FBSDKLoginManager.m | 10 +- .../Internal/FBSDKLoginCompletion.h | 3 +- .../Internal/FBSDKLoginCompletion.m | 12 +- .../FBSDKAuthenticationTokenTests.m | 158 +++++++++++++++--- 6 files changed, 186 insertions(+), 36 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h index 9f167516ff..aed59a550c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN /** - Represent an ID Token used for OpenID connect (OIDC) protocal + Represent an AuthenticationToken used for a login attempt */ NS_SWIFT_NAME(AuthenticationToken) @interface FBSDKAuthenticationToken : NSObject @@ -55,11 +55,13 @@ NS_SWIFT_NAME(AuthenticationToken) @property (nonatomic, readonly) FBSDKBetaLoginExperience betaLoginExperience; /** - Initializes a new instance if the ID token is valid. Otherwise returns nil. - An ID Token is verified based of the OpenID connect standard. + Initializes a new instance if the token represented by the token string is valid. Otherwise returns nil. + An `AuthenticationToken` is verified based of the OpenID Connect Protocol. @param tokenString the raw ID token string + @param nonce the nonce string used to associate a client session with the token */ -- (instancetype)initWithTokenString:(NSString *)tokenString; +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce; @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m index 10529d4526..a28070b12e 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m @@ -38,6 +38,8 @@ static FBSDKAuthenticationToken *g_currentAuthenticationToken; +static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins + @implementation FBSDKAuthenticationToken { NSString *_cert; @@ -46,8 +48,9 @@ @implementation FBSDKAuthenticationToken } - (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce { - if (!tokenString || tokenString.length == 0) { + if (!tokenString || tokenString.length == 0 || !nonce || nonce.length == 0) { return nil; } @@ -67,7 +70,7 @@ - (instancetype)initWithTokenString:(NSString *)tokenString return nil; } - [self setClaimsWithEncodedString:encodedClaims]; + _claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; } return self; @@ -85,19 +88,31 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token } } -- (void)setClaimsWithEncodedString:(NSString *)encodedClaims ++ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce { NSError *error; NSData *claimsData = [FBSDKBase64 decodeAsData:encodedClaims]; if (claimsData) { - NSDictionary *decodedClaims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; + NSDictionary *claims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; if (!error) { - // TODO(T78739428): verify claims - - _claims = decodedClaims; + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + + // verify claims + BOOL isFacebook = [claims[@"iss"] isKindOfClass:[NSString class]] && [[[NSURL URLWithString:claims[@"iss"]] host] isEqualToString:@"facebook.com"]; + BOOL audMatched = [claims[@"aud"] isKindOfClass:[NSString class]] && [claims[@"aud"] isEqualToString:[FBSDKSettings appID]]; + BOOL isExpired = [claims[@"exp"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"exp"] longValue] <= currentTime; + BOOL issuedRecently = [claims[@"iat"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"iat"] longValue] >= currentTime - MaxTimeSinceTokenIssued; + BOOL nonceMatched = [claims[@"nonce"] isKindOfClass:[NSString class]] && [claims[@"nonce"] isEqualToString:nonce]; + BOOL userIDValid = [claims[@"sub"] isKindOfClass:[NSString class]] && [claims[@"sub"] length] > 0; + + if (isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid) { + return claims; + } } } + + return nil; } - (BOOL)verifySignature:(NSString *)signature diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 47caea6614..7b3fa33e3f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -46,6 +46,7 @@ static int const FBClientStateChallengeLength = 20; static NSString *const FBSDKExpectedChallengeKey = @"expected_login_challenge"; +static NSString *const FBSDKOIDCExpectedNonceKey = @"expected_login_nonce"; static NSString *const FBSDKOauthPath = @"/dialog/oauth"; static NSString *const SFVCCanceledLogin = @"com.apple.SafariServices.Authentication"; static NSString *const ASCanceledLogin = @"com.apple.AuthenticationServices.WebAuthenticationSession"; @@ -323,6 +324,11 @@ - (NSString *)loadExpectedChallenge return [_keychainStore stringForKey:FBSDKExpectedChallengeKey]; } +- (NSString *)loadExpectedNonce +{ + return [_keychainStore stringForKey:FBSDKOIDCExpectedNonceKey]; +} + - (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration { [FBSDKInternalUtility validateURLSchemes]; @@ -556,7 +562,9 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl if (isFacebookURL) { NSDictionary *urlParameters = [FBSDKLoginUtility queryParamsFromLoginURL:url]; - id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:urlParameters appID:[FBSDKSettings appID]]; + id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:urlParameters + appID:[FBSDKSettings appID] + nonce:[self loadExpectedNonce]]; if (_logger == nil) { _logger = [FBSDKLoginManagerLogger loggerFromParameters:urlParameters]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h index 0efe5136c2..17dbe8008c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h @@ -89,7 +89,8 @@ NS_SWIFT_NAME(LoginURLCompleter) - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; -- (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID; +- (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID nonce:(NSString *)nonce NS_DESIGNATED_INITIALIZER; @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index df1ef4b939..4364fe8176 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -121,12 +121,20 @@ @implementation FBSDKLoginURLCompleter BOOL _performExplicitFallback; } -- (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID +- (instancetype)initWithURLParameters:(NSDictionary *)parameters + appID:(NSString *)appID +{ + return [self initWithURLParameters:parameters appID:appID nonce:nil]; +} + +- (instancetype)initWithURLParameters:(NSDictionary *)parameters + appID:(NSString *)appID + nonce:(NSString *)nonce { if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; - FBSDKAuthenticationToken *idToken = [[FBSDKAuthenticationToken alloc] initWithTokenString:parameters[@"id_token"]]; + FBSDKAuthenticationToken *idToken = [[FBSDKAuthenticationToken alloc] initWithTokenString:parameters[@"id_token"] nonce:nonce]; if ([parameters[@"access_token"] length] > 0 || [parameters[@"nonce"] length] > 0 diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m index 594f49eb95..2ca35956a1 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m @@ -19,8 +19,10 @@ #import #import -#import "FBSDKCoreKit+Internal.h" +#import + #import "FBSDKAuthenticationToken.h" +#import "FBSDKCoreKit+Internal.h" static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; @@ -30,9 +32,15 @@ static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; +static NSString *const _mockAppID = @"4321"; + +static NSString *const _mockNonce = @"some_nonce"; + +static NSString *const _facebookURL = @"https://facebook.com/dialog/oauth"; + @interface FBSDKAuthenticationToken (Testing) -- (void)setClaimsWithEncodedString:(NSString *)encodedClaims; ++ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; + (instancetype)emptyInstance; @@ -53,31 +61,102 @@ @interface FBSDKAuthenticationTokenTests : XCTestCase @end @implementation FBSDKAuthenticationTokenTests +{ + NSDictionary *_claims; +} -- (void)testDecodeValidClaims +- (void)setUp { - NSDictionary *expectedClaims = @{ + [super setUp]; + [FBSDKSettings setAppID:_mockAppID]; + + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + _claims = @{ + @"iss" : _facebookURL, + @"aud" : _mockAppID, + @"nonce" : _mockNonce, + @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later + @"iat" : @(currentTime - 60), // 1 min ago @"sub" : @"1234", @"name" : @"Test User", - @"iss" : @"https://facebook.com/dialog/oauth", - @"aud" : @"4321", - @"nonce" : @"some_nonce", - @"exp" : @1516259022, @"email" : @"email@email.com", @"picture" : @"https://www.facebook.com/some_picture", - @"iat" : @1516239022, }; - NSData *expectedClaimsData = [FBSDKTypeUtility dataWithJSONObject:expectedClaims options:0 error:nil]; - NSString *encodedClaims = [self base64URLEncodeData:expectedClaimsData]; - FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; +} + +- (void)testDecodeValidClaimsShouldSucceed +{ + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - [token setClaimsWithEncodedString:encodedClaims]; - XCTAssertEqualObjects(token.claims, expectedClaims); + NSDictionary *claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; + XCTAssertEqualObjects(claims, _claims); +} + +- (void)testDecodeInvalidFormatClaimsShouldFail +{ + NSData *claimsData = [@"invalid_claims" dataUsingEncoding:NSUTF8StringEncoding]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + XCTAssertNil([FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); +} + +- (void)testDecodeInvalidClaimsShouldFail +{ + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + + // non facebook issuer + [self assertDecodeClaimsFailWithInvalidEntry:@"iss" + value:@"https://notfacebook.com"]; + + // incorrect audience + [self assertDecodeClaimsFailWithInvalidEntry:@"aud" + value:@"wrong_app_id"]; + + // expired + [self assertDecodeClaimsFailWithInvalidEntry:@"exp" + value:@(currentTime - 60 * 60)]; + + // issued too long ago + [self assertDecodeClaimsFailWithInvalidEntry:@"iat" + value:@(currentTime - 60 * 60)]; + + // incorrect nonce + [self assertDecodeClaimsFailWithInvalidEntry:@"nonce" + value:@"incorrect_nonce"]; + + // invalid user ID + [self assertDecodeClaimsFailWithInvalidEntry:@"sub" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"sub" + value:@1234]; + [self assertDecodeClaimsFailWithInvalidEntry:@"sub" + value:@""]; +} + +- (void)testDecodeEmptyClaims +{ + NSDictionary *claims = @{}; + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:claims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + XCTAssertNil([FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); +} + +- (void)testDecodeRandomClaims +{ + for (int i = 0; i < 100; i++) { + NSDictionary *randomizedClaims = [self randomizeDictionary:_claims]; + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:randomizedClaims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; + } } - (void)testCreateWithInvalidFormatTokenShouldFail { - FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token"]; + FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token" nonce:@"123456789"]; XCTAssertNil(token); } @@ -88,8 +167,8 @@ - (void)testVerifyValidSignatureShouldSucceed XCTAssertTrue( [token verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] + header:_encodedHeader + claims:_encodedClaims] ); } @@ -102,8 +181,8 @@ - (void)testVerifyInvalidSignatureShouldFail XCTAssertFalse( [token verifySignature:invalidSignature - header:_encodedHeader - claims:_encodedClaims] + header:_encodedHeader + claims:_encodedClaims] ); } @@ -114,8 +193,8 @@ - (void)testVerifySignatureWithInvalidCertificateShouldFail XCTAssertFalse( [token verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] + header:_encodedHeader + claims:_encodedClaims] ); } @@ -142,4 +221,41 @@ - (NSString *)base64URLEncodeData:(NSData *)data return [base64URL stringByReplacingOccurrencesOfString:@"=" withString:@""]; } +- (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value +{ + NSMutableDictionary *invalidClaims = [_claims mutableCopy]; + if (value) { + [FBSDKTypeUtility dictionary:invalidClaims setObject:value forKey:key]; + } else { + [invalidClaims removeObjectForKey:key]; + } + + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:invalidClaims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + XCTAssertNil([FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); +} + +- (NSDictionary *)randomizeDictionary:(NSDictionary *)dictionary +{ + NSArray *values = @[@YES, @NO, @1, @0, @-1, @INT32_MAX, @LONG_MAX, @MAXFLOAT, @"1", @"a", @"[ { \"something\": nonexistent } ]"]; + NSMutableDictionary *randomized = [dictionary mutableCopy]; + for (NSString *key in dictionary) { + int randOption = arc4random() % 3; + switch (randOption) { + case 0: + [randomized removeObjectForKey:key]; + break; + case 1: + [FBSDKTypeUtility dictionary:randomized setObject:[FBSDKTypeUtility array:values objectAtIndex:arc4random() % values.count] forKey:key]; + break; + case 2: + default: + break; + } + } + + return randomized; +} + @end From 583cb7bcf40fbb4745e1a2bb69be2e208794613c Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 13:27:02 -0800 Subject: [PATCH 138/227] ID Token header decode & verification Summary: For openid connect logins, the server should return login response as "id_token" in the format `HEADER.PAYLOAD.SIGNATURE`. The client must validate the ID token in the manner specified in the spec (https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation). This diff decode and verify the ID Token header from the login response. Reviewed By: ppansy Differential Revision: D24871749 fbshipit-source-id: 15c8e06a868e3226d02e94aac67891b85f516e4b --- .../FBSDKLoginKit/FBSDKAuthenticationToken.m | 21 ++++++++ .../FBSDKAuthenticationTokenTests.m | 54 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m index a28070b12e..010c8f2fe9 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m @@ -44,6 +44,7 @@ @implementation FBSDKAuthenticationToken { NSString *_cert; NSDictionary *_claims; + NSDictionary *_header; NSString *_signature; } @@ -71,6 +72,11 @@ - (instancetype)initWithTokenString:(NSString *)tokenString } _claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; + _header = [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; + + if (!_claims || !_header) { + return nil; + } } return self; @@ -115,6 +121,21 @@ + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims non return nil; } ++ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader +{ + NSError *error; + NSData *headerData = [FBSDKBase64 decodeAsData:encodedHeader]; + + if (headerData) { + NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; + if (!error && [header[@"alg"] isKindOfClass:[NSString class]] && [header[@"alg"] isEqualToString:@"RS256"]) { + return header; + } + } + + return nil; +} + - (BOOL)verifySignature:(NSString *)signature header:(NSString *)header claims:(NSString *)claims diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m index 2ca35956a1..60555dd299 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m @@ -41,6 +41,7 @@ @interface FBSDKAuthenticationToken (Testing) + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; ++ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; + (instancetype)emptyInstance; @@ -63,6 +64,7 @@ @interface FBSDKAuthenticationTokenTests : XCTestCase @implementation FBSDKAuthenticationTokenTests { NSDictionary *_claims; + NSDictionary *_header; } - (void)setUp @@ -82,6 +84,11 @@ - (void)setUp @"email" : @"email@email.com", @"picture" : @"https://www.facebook.com/some_picture", }; + + _header = @{ + @"alg" : @"RS256", + @"typ" : @"JWT" + }; } - (void)testDecodeValidClaimsShouldSucceed @@ -160,6 +167,53 @@ - (void)testCreateWithInvalidFormatTokenShouldFail XCTAssertNil(token); } +- (void)testDecodeValidHeaderShouldSucceed +{ + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + NSDictionary *header = [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; + XCTAssertEqualObjects(header, _header); +} + +- (void)testDecodeInvalidFormatHeaderShouldFail +{ + NSData *headerData = [@"invalid_header" dataUsingEncoding:NSUTF8StringEncoding]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + XCTAssertNil([FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]); +} + +- (void)testDecodeInvalidHeaderShouldFail +{ + NSMutableDictionary *invalidHeader = [_header mutableCopy]; + [FBSDKTypeUtility dictionary:invalidHeader setObject:@"wrong algorithm" forKey:@"alg"]; + NSData *invalidHeaderData = [FBSDKTypeUtility dataWithJSONObject:invalidHeader options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:invalidHeaderData]; + + XCTAssertNil([FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]); +} + +- (void)testDecodeEmptyHeader +{ + NSDictionary *header = @{}; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:header options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + XCTAssertNil([FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]); +} + +- (void)testDecodeRandomHeader +{ + for (int i = 0; i < 100; i++) { + NSDictionary *randomizedHeader = [self randomizeDictionary:_header]; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:randomizedHeader options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; + } +} + - (void)testVerifyValidSignatureShouldSucceed { FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; From b1096ff3f04032ed64c7ed5a38cb9efe4f04a327 Mon Sep 17 00:00:00 2001 From: Julie Yuan Date: Tue, 1 Dec 2020 15:21:31 -0800 Subject: [PATCH 139/227] Expose sessionCompletionHandler via internal method Summary: Add an additional method to the internal-only class `FBSDKBridgeAPI` which exposes the saved `_authenticationSessionCompletionHandler` for usage in E2E testing. Reviewed By: joesus Differential Revision: D24488140 fbshipit-source-id: 82f0091dd1fa143655b09303914bbe84b3feab16 --- .../FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h | 4 ++++ .../FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h index 20c274dcef..9159c5376a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.h @@ -39,6 +39,8 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^FBSDKBridgeAPIResponseBlock)(FBSDKBridgeAPIResponse *response) NS_SWIFT_NAME(BridgeAPIResponseBlock); +typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); + @interface FBSDKBridgeAPI : NSObject - (void)openBridgeAPIRequest:(NSObject *)request @@ -55,6 +57,8 @@ NS_SWIFT_NAME(BridgeAPIResponseBlock); sender:(nullable id)sender handler:(FBSDKSuccessBlock)handler; +- (FBSDKAuthenticationCompletionHandler)sessionCompletionHandler; + @property (class, nonatomic, readonly, strong) FBSDKBridgeAPI *sharedInstance NS_SWIFT_NAME(shared); @property (nonatomic, readonly, getter=isActive) BOOL active; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m index bc8aac0754..ee1e6c5eec 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPI.m @@ -40,8 +40,6 @@ typedef NS_ENUM(NSUInteger, FBSDKAuthenticationSession) { FBSDKAuthenticationSessionCanceledBySystem, }; -typedef void (^FBSDKAuthenticationCompletionHandler)(NSURL *_Nullable callbackURL, NSError *_Nullable error); - @protocol FBSDKAuthenticationSession - (instancetype)initWithURL:(NSURL *)URL callbackURLScheme:(nullable NSString *)callbackURLScheme completionHandler:(FBSDKAuthenticationCompletionHandler)completionHandler; @@ -453,6 +451,11 @@ - (void)setSessionCompletionHandlerFromHandler:(FBSDKSuccessBlock)handler }; } +- (FBSDKAuthenticationCompletionHandler)sessionCompletionHandler +{ + return _authenticationSessionCompletionHandler; +} + #pragma mark -- SFSafariViewControllerDelegate // This means the user tapped "Done" which we should treat as a cancellation. From 4346f6132595b279a949b49eea3461f29c38e16e Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 16:18:45 -0800 Subject: [PATCH 140/227] Fixing static cocoapods for login kit changes Summary: Need to import CoreKit explicitly for the Swift extensions on LoginKit defined types. Reviewed By: ppansy Differential Revision: D25253837 fbshipit-source-id: 909363ca3a92d867b6e40c56139c769a6687cb98 --- FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift index e9ca6c5703..d8601684b1 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift @@ -16,9 +16,8 @@ // 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 Foundation +import FBSDKCoreKit -@available(tvOS, unavailable) public extension LoginConfiguration { /** From 63d2e8f78d3c80cda220ff77cfa3070ba7bb2831 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 16:18:45 -0800 Subject: [PATCH 141/227] Constructs AuthenticationToken from ID token response Summary: This diff uses information from the parsed / decoded ID Token from the login response to create an authentication token that can be used by developers to verify an authentication attempt on their own servers. Reviewed By: ppansy Differential Revision: D24901061 fbshipit-source-id: c08d515ab116cca1093d94a2c80d063e1ad57eef --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 2 + .../FBSDKLoginKit/FBSDKAuthenticationToken.m | 14 +++ .../FBSDKLoginKit/FBSDKLoginConstants.h | 5 ++ .../FBSDKAuthenticationToken+Internal.h | 31 +++++++ .../Internal/FBSDKLoginCompletion.m | 19 ++-- .../FBSDKLoginKit/Internal/FBSDKLoginError.m | 2 + .../FBSDKLoginManagerTests.m | 90 +++++++++++++++++++ 7 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKAuthenticationToken+Internal.h diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 9d98dfa794..687163eb3f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -414,6 +414,7 @@ F4AA32812574448C005EDF04 /* LoginConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginConfiguration.swift; sourceTree = ""; }; F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKNonceUtility.h; sourceTree = ""; }; F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKNonceUtility.m; sourceTree = ""; }; + F4EC48252576C04000D2F47B /* FBSDKAuthenticationToken+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKAuthenticationToken+Internal.h"; sourceTree = ""; }; F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitImport.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -570,6 +571,7 @@ 9D03E8271A72DCA700207493 /* Internal */ = { isa = PBXGroup; children = ( + F4EC48252576C04000D2F47B /* FBSDKAuthenticationToken+Internal.h */, C6CE2BC124EB732C00CF2EB6 /* FBSDKReferralManager+Internal.h */, 0B9DBEFD207C04FF00662776 /* FBSDKDeviceLoginCodeInfo+Internal.h */, 0B9DBEF7207C04FF00662776 /* FBSDKDeviceLoginManagerResult+Internal.h */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m index 010c8f2fe9..8fd8c49d7d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m @@ -140,6 +140,13 @@ - (BOOL)verifySignature:(NSString *)signature header:(NSString *)header claims:(NSString *)claims { +#if DEBUG + // skip signature checking for tests + if (_skipSignatureVerification) { + return YES; + } +#endif + NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:signature]]; NSString *signedString = [NSString stringWithFormat:@"%@.%@", header, claims]; NSData *signedData = [signedString dataUsingEncoding:NSASCIIStringEncoding]; @@ -210,6 +217,13 @@ + (NSString *)base64FromBase64Url:(NSString *)base64Url #if DEBUG +static BOOL _skipSignatureVerification; + ++ (void)setSkipSignatureVerification:(BOOL)value +{ + _skipSignatureVerification = value; +} + + (instancetype)emptyInstance { return [super new]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h index 471bfdcab3..6796cbba3f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h @@ -100,6 +100,11 @@ typedef NS_ERROR_ENUM(FBSDKLoginErrorDomain, FBSDKLoginError) The login response was missing a valid challenge string. */ FBSDKLoginErrorBadChallengeString, + + /** + The ID token returned in login response was invalid + */ + FBSDKLoginErrorInvalidIDToken, } NS_SWIFT_NAME(LoginError); /** diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKAuthenticationToken+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKAuthenticationToken+Internal.h new file mode 100644 index 0000000000..4f0b078d08 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKAuthenticationToken+Internal.h @@ -0,0 +1,31 @@ +// 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 "FBSDKAuthenticationToken.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKAuthenticationToken (Internal) + +- (NSDictionary *)claims; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 4364fe8176..c0d711b7fd 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -29,6 +29,7 @@ #endif #import "FBSDKAuthenticationToken.h" + #import "FBSDKAuthenticationToken+Internal.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" @@ -134,15 +135,15 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; - FBSDKAuthenticationToken *idToken = [[FBSDKAuthenticationToken alloc] initWithTokenString:parameters[@"id_token"] nonce:nonce]; + FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:parameters[@"id_token"] nonce:nonce]; if ([parameters[@"access_token"] length] > 0 || [parameters[@"nonce"] length] > 0 - || idToken) { + || token) { [self setParametersWithDictionary:parameters appID:appID]; - if (idToken) { - [self setParametersWithIDToken:idToken]; + if (token) { + FBSDKProfile.currentProfile = [FBSDKLoginURLCompleter createProfileWithToken:token]; } } else { [self setErrorWithDictionary:parameters]; @@ -285,13 +286,15 @@ - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)ha [connection start]; } -- (void)setParametersWithIDToken:(FBSDKAuthenticationToken *)idToken +/// Returns a `FBSDKProfile` from an `AuthenticationToken` if it can extract the minimum necessary information ++ (FBSDKProfile *)createProfileWithToken:(FBSDKAuthenticationToken *)token { - if (!idToken) { - return; + if (!token || !token.claims) { + return nil; } - // TODO(T78739549): populate parameters with data from claims + // TODO: populate profile from claims + return [FBSDKProfile currentProfile]; } @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m index 21588573f8..1e48c07b07 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m @@ -164,6 +164,8 @@ + (NSError *)fbErrorFromReturnURLParameters:(NSDictionary *)parameters error = [NSError errorWithDomain:FBSDKErrorDomain code:FBSDKErrorGraphRequestGraphAPI userInfo:userInfo]; + } else if (parameters[@"id_token"]) { + error = [FBSDKError errorWithCode:FBSDKLoginErrorInvalidIDToken message:@"Invalid ID token from login response."]; } return error; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 9ee29ac52c..ae2dec4e6e 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -22,6 +22,7 @@ #import +#import "FBSDKAuthenticationToken.h" #import "FBSDKLoginManager.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLoginResult.h" @@ -31,10 +32,20 @@ static NSString *const kFakeChallenge = @"a =bcdef"; +static NSString *const kFakeNonce = @"fedcb =a"; + @interface FBSDKLoginManager (Testing) - (NSDictionary *)logInParametersFromURL:(NSURL *)url; +- (NSString *)loadExpectedNonce; + +@end + +@interface FBSDKAuthenticationToken (Testing) + ++ (void)setSkipSignatureVerification:(BOOL)value; + @end @interface FBSDKLoginManagerTests : XCTestCase @@ -83,6 +94,17 @@ - (FBSDKLoginManager *)loginManagerExpectingChallenge return (FBSDKLoginManager *)partialMock; } +- (FBSDKLoginManager *)loginManagerExpectingChallengeAndNonce +{ + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + id partialMock = [OCMockObject partialMockForObject:loginManager]; + + OCMStub([partialMock loadExpectedChallenge]).andReturn(kFakeChallenge); + OCMStub([partialMock loadExpectedNonce]).andReturn(kFakeNonce); + + return (FBSDKLoginManager *)partialMock; +} + // verify basic case of first login and getting granted and declined permissions (is not classified as cancelled) - (void)testOpenURLAuth { @@ -272,6 +294,74 @@ - (void)testOpenURLWithNoChallengeAndError }]; } +- (void)testOpenURLAuthWithIDToken +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + [FBSDKAccessToken setCurrentAccessToken:nil]; + FBSDKLoginManager *target = [self loginManagerExpectingChallengeAndNonce]; + [FBSDKAuthenticationToken setSkipSignatureVerification:YES]; + + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + NSDictionary *expectedClaims = @{ + @"iss" : @"https://facebook.com/dialog/oauth", + @"aud" : kFakeAppID, + @"nonce" : kFakeNonce, + @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later + @"iat" : @(currentTime - 60), // 1 min ago + @"sub" : @"1234", + @"name" : @"Test User", + @"picture" : @"https://www.facebook.com/some_picture", + }; + NSData *expectedClaimsData = [FBSDKTypeUtility dataWithJSONObject:expectedClaims options:0 error:nil]; + NSString *encodedClaims = [FBSDKBase64 encodeData:expectedClaimsData]; + NSDictionary *expectedHeader = @{ + @"alg" : @"RS256", + @"typ" : @"JWT" + }; + NSData *expectedHeaderData = [FBSDKTypeUtility dataWithJSONObject:expectedHeader options:0 error:nil]; + NSString *encodedHeader = [FBSDKBase64 encodeData:expectedHeaderData]; + + NSString *fragment = [NSString stringWithFormat:@"id_token=%@.%@.%@", encodedHeader, encodedClaims, @"signature"]; + NSURL *url = [self authorizeURLWithFragment:fragment challenge:kFakeChallenge]; + + __block FBSDKProfile *tokenAfterAuth; + [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + // TODO: Verify that the expected profile is set. + // XCTAssertFalse(result.isCancelled); + tokenAfterAuth = [FBSDKProfile currentProfile]; + // XCTAssertEqualObjects(tokenAfterAuth, result.token); + [expectation fulfill]; + }]; + + XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) { + XCTAssertNil(error); + }]; + + [FBSDKAuthenticationToken setSkipSignatureVerification:NO]; +} + +- (void)testOpenURLAuthWithInvalidIDToken +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + [FBSDKAccessToken setCurrentAccessToken:nil]; + FBSDKLoginManager *target = [self loginManagerExpectingChallengeAndNonce]; + NSURL *url = [self authorizeURLWithFragment:@"id_token=invalid_token" challenge:kFakeChallenge]; + + [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTAssertNotNil(error); + XCTAssertNil([FBSDKAccessToken currentAccessToken]); + [expectation fulfill]; + }]; + + XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + + [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) { + XCTAssertNil(error); + }]; +} + - (void)testLoginManagerRetainsItselfForLoginMethod { // Mock some methods to force an error callback. From 6a6542bfcdd887ed68f5ed719d31df8862d62a29 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 1 Dec 2020 16:18:45 -0800 Subject: [PATCH 142/227] Add optional email and image field to FBSDKProfile Summary: When using OIDC login, the returned JWT ID token could contain user claims concluding userID, name, profile picture and email. We need to find a way to save those data so that they are accessible to developers. A good candidate is `FBSDKProfile`, which represents a global "currentProfile" instance and already have fields for userID and name. This diff add optional email and profile image fields for storing the corresponding claims. A note on profile image: `FBSDKProfile` has method `imageURLForPictureMode`, which returns an graph URL for retrieving the user's profile image. Making a request to the url will return a data blob containing the actual image link, with some additional informations like image size. The image field from this diff will just be the actual image link. Reviewed By: ppansy Differential Revision: D24937459 fbshipit-source-id: a1205a812286ed8481296d8e6a5b78f9259bd6ea --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h | 35 ++++++- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 49 ++++++++- .../FBSDKCoreKitTests/FBSDKProfileTests.m | 99 ++++++++++++++----- .../Internal/Helpers/SampleUserProfile.swift | 4 +- 4 files changed, 155 insertions(+), 32 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h index 372b0f9ea8..7076323f5d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h @@ -109,7 +109,30 @@ NS_SWIFT_NAME(Profile) lastName:(nullable NSString *)lastName name:(nullable NSString *)name linkURL:(nullable NSURL *)linkURL - refreshDate:(nullable NSDate *)refreshDate NS_DESIGNATED_INITIALIZER; + refreshDate:(nullable NSDate *)refreshDate; + +/** + initializes a new instance. + @param userID the user ID + @param firstName the user's first name + @param middleName the user's middle name + @param lastName the user's last name + @param name the user's complete name + @param linkURL the link for this profile + @param refreshDate the optional date this profile was fetched. Defaults to [NSDate date]. + @param imageURL an optional URL to use for fetching a user's profile image + @param email the user's email + */ +- (instancetype)initWithUserID:(NSString *)userID + firstName:(nullable NSString *)firstName + middleName:(nullable NSString *)middleName + lastName:(nullable NSString *)lastName + name:(nullable NSString *)name + linkURL:(nullable NSURL *)linkURL + refreshDate:(nullable NSDate *)refreshDate + imageURL:(nullable NSURL *)imageURL + email:(nullable NSString *)email +NS_DESIGNATED_INITIALIZER; /** The current profile instance and posts the appropriate notification @@ -156,6 +179,16 @@ NS_SWIFT_NAME(current); The last time the profile data was fetched. */ @property (nonatomic, readonly) NSDate *refreshDate; +/** + A URL to use for fetching a user's profile image. + */ +@property (nonatomic, readonly, nullable) NSURL *imageURL; +/** + The user's email. + + IMPORTANT: This field will only be populated if your user has granted your application the 'email' permission. + */ +@property (nonatomic, copy, readonly, nullable) NSString *email; /** Indicates if `currentProfile` will automatically observe `FBSDKAccessTokenDidChangeNotification` notifications diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index c2919b6a49..838bf9401d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -44,6 +44,8 @@ #define FBSDKPROFILE_NAME_KEY @"name" #define FBSDKPROFILE_LINKURL_KEY @"linkURL" #define FBSDKPROFILE_REFRESHDATE_KEY @"refreshDate" + #define FBSDKPROFILE_IMAGEURL_KEY @"imageURL" + #define FBSDKPROFILE_EMAIL_KEY @"email" // Once a day #define FBSDKPROFILE_STALE_IN_SECONDS (60 * 60 * 24) @@ -57,6 +59,27 @@ - (instancetype)initWithUserID:(NSString *)userID name:(NSString *)name linkURL:(NSURL *)linkURL refreshDate:(NSDate *)refreshDate +{ + return [self initWithUserID:userID + firstName:firstName + middleName:middleName + lastName:lastName + name:name + linkURL:linkURL + refreshDate:refreshDate + imageURL:nil + email:nil]; +} + +- (instancetype)initWithUserID:(NSString *)userID + firstName:(NSString *)firstName + middleName:(NSString *)middleName + lastName:(NSString *)lastName + name:(NSString *)name + linkURL:(NSURL *)linkURL + refreshDate:(NSDate *)refreshDate + imageURL:(NSURL *)imageURL + email:(NSString *)email { if ((self = [super init])) { _userID = [userID copy]; @@ -66,6 +89,8 @@ - (instancetype)initWithUserID:(NSString *)userID _name = [name copy]; _linkURL = [linkURL copy]; _refreshDate = [refreshDate copy] ?: [NSDate date]; + _imageURL = [imageURL copy]; + _email = [email copy]; } return self; } @@ -131,7 +156,9 @@ - (NSUInteger)hash self.lastName.hash, self.name.hash, self.linkURL.hash, - self.refreshDate.hash + self.refreshDate.hash, + self.imageURL.hash, + self.email.hash, }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } @@ -155,7 +182,9 @@ - (BOOL)isEqualToProfile:(FBSDKProfile *)profile && [_lastName isEqualToString:profile.lastName] && [_name isEqualToString:profile.name] && [_linkURL isEqual:profile.linkURL] - && [_refreshDate isEqualToDate:profile.refreshDate]); + && [_refreshDate isEqualToDate:profile.refreshDate]) + && [_imageURL isEqual:profile.imageURL] + && [_email isEqualToString:profile.email]; } #pragma mark NSCoding @@ -174,13 +203,17 @@ - (instancetype)initWithCoder:(NSCoder *)decoder NSString *name = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_NAME_KEY]; NSURL *linkURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDKPROFILE_LINKURL_KEY]; NSDate *refreshDate = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDKPROFILE_REFRESHDATE_KEY]; + NSURL *imageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDKPROFILE_IMAGEURL_KEY]; + NSString *email = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_EMAIL_KEY]; return [self initWithUserID:userID firstName:firstName middleName:middleName lastName:lastName name:name linkURL:linkURL - refreshDate:refreshDate]; + refreshDate:refreshDate + imageURL:imageURL + email:email]; } - (void)encodeWithCoder:(NSCoder *)encoder @@ -192,6 +225,8 @@ - (void)encodeWithCoder:(NSCoder *)encoder [encoder encodeObject:self.name forKey:FBSDKPROFILE_NAME_KEY]; [encoder encodeObject:self.linkURL forKey:FBSDKPROFILE_LINKURL_KEY]; [encoder encodeObject:self.refreshDate forKey:FBSDKPROFILE_REFRESHDATE_KEY]; + [encoder encodeObject:self.imageURL forKey:FBSDKPROFILE_IMAGEURL_KEY]; + [encoder encodeObject:self.email forKey:FBSDKPROFILE_EMAIL_KEY]; } @end @@ -273,6 +308,10 @@ + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(FBSDKProfileB graphPath = [graphPath stringByAppendingString:@",link"]; } + if ([token.permissions containsObject:@"email"]) { + graphPath = [graphPath stringByAppendingString:@",email"]; + } + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; @@ -299,7 +338,9 @@ + (void)loadProfileWithToken:(FBSDKAccessToken *)token lastName:result[@"last_name"] name:result[@"name"] linkURL:linkUrl - refreshDate:[NSDate date]]; + refreshDate:[NSDate date] + imageURL:nil + email:result[@"email"]]; *profileRef = [profile copy]; }; [[self class] loadProfileWithToken:token completion:completion graphRequest:request parseBlock:parseBlock]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m index 8c3b5b5aec..eaaf1dd671 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKProfileTests.m @@ -362,14 +362,50 @@ - (void)testGraphPathForProfileLoadWithoutLinkPermission XCTAssertTrue(graphRequestMethodInvoked); } +- (void)testGraphPathForProfileLoadWithEmailPermission +{ + id profileMock = OCMClassMock([FBSDKProfile class]); + FBSDKAccessToken *token = [SampleAccessToken validTokenWithPermissions:@[@"email"]]; + NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,email"; + __block BOOL graphRequestMethodInvoked = false; + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY graphRequest:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { + __unsafe_unretained FBSDKGraphRequest *request; + [invocation getArgument:&request atIndex:4]; + graphRequestMethodInvoked = true; + XCTAssertEqualObjects(request.graphPath, graphPath); + }); + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY]).andForwardToRealObject(); + [FBSDKProfile loadProfileWithToken:token completion:nil]; + XCTAssertTrue(graphRequestMethodInvoked); +} + +- (void)testGraphPathForProfileLoadWithoutEmailPermission +{ + id profileMock = OCMClassMock([FBSDKProfile class]); + NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name"; + __block BOOL graphRequestMethodInvoked = false; + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY graphRequest:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) { + __unsafe_unretained FBSDKGraphRequest *request; + [invocation getArgument:&request atIndex:4]; + graphRequestMethodInvoked = true; + XCTAssertEqualObjects(request.graphPath, graphPath); + }); + OCMStub([profileMock loadProfileWithToken:OCMOCK_ANY completion:OCMOCK_ANY]).andForwardToRealObject(); + [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil]; + XCTAssertTrue(graphRequestMethodInvoked); +} + - (void)testLoadingProfile { - id result = @{ @"id" : SampleUserProfile.valid.userID, - @"first_name" : SampleUserProfile.valid.firstName, - @"middle_name" : SampleUserProfile.valid.middleName, - @"last_name" : SampleUserProfile.valid.lastName, - @"name" : SampleUserProfile.valid.name, - @"link" : SampleUserProfile.valid.linkURL}; + id result = @{ + @"id" : SampleUserProfile.valid.userID, + @"first_name" : SampleUserProfile.valid.firstName, + @"middle_name" : SampleUserProfile.valid.middleName, + @"last_name" : SampleUserProfile.valid.lastName, + @"name" : SampleUserProfile.valid.name, + @"link" : SampleUserProfile.valid.linkURL, + @"email" : SampleUserProfile.valid.email + }; [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { @@ -379,17 +415,21 @@ - (void)testLoadingProfile XCTAssertEqualObjects(profile.name, SampleUserProfile.valid.name); XCTAssertEqualObjects(profile.userID, SampleUserProfile.valid.userID); XCTAssertEqualObjects(profile.linkURL, SampleUserProfile.valid.linkURL); + XCTAssertEqualObjects(profile.email, SampleUserProfile.valid.email); } graphRequest:self.graphRequestMock]; } - (void)testLoadingProfileWithInvalidLink { - id result = @{ @"id" : SampleUserProfile.valid.userID, - @"first_name" : SampleUserProfile.valid.firstName, - @"middle_name" : SampleUserProfile.valid.middleName, - @"last_name" : SampleUserProfile.valid.lastName, - @"name" : SampleUserProfile.valid.name, - @"link" : @" "}; + id result = @{ + @"id" : SampleUserProfile.valid.userID, + @"first_name" : SampleUserProfile.valid.firstName, + @"middle_name" : SampleUserProfile.valid.middleName, + @"last_name" : SampleUserProfile.valid.lastName, + @"name" : SampleUserProfile.valid.name, + @"link" : @" ", + @"email" : SampleUserProfile.valid.email + }; [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { @@ -399,11 +439,13 @@ - (void)testLoadingProfileWithInvalidLink - (void)testProfileNilWithNilAccessToken { - id result = @{ @"id" : SampleUserProfile.valid.userID, - @"first_name" : SampleUserProfile.valid.firstName, - @"middle_name" : SampleUserProfile.valid.middleName, - @"last_name" : SampleUserProfile.valid.lastName, - @"name" : SampleUserProfile.valid.name}; + id result = @{ + @"id" : SampleUserProfile.valid.userID, + @"first_name" : SampleUserProfile.valid.firstName, + @"middle_name" : SampleUserProfile.valid.middleName, + @"last_name" : SampleUserProfile.valid.lastName, + @"name" : SampleUserProfile.valid.name + }; [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:nil completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { @@ -414,11 +456,13 @@ - (void)testProfileNilWithNilAccessToken - (void)testProfileNotRefreshedIfNotStale { [FBSDKProfile setCurrentProfile:SampleUserProfile.valid]; - id result = @{ @"id" : SampleUserProfile.valid.userID, - @"first_name" : @"firstname", - @"middle_name" : @"middlename", - @"last_name" : @"lastname", - @"name" : @"name"}; + id result = @{ + @"id" : SampleUserProfile.valid.userID, + @"first_name" : @"firstname", + @"middle_name" : @"middlename", + @"last_name" : @"lastname", + @"name" : @"name" + }; [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:nil completion:^(FBSDKProfile *_Nullable profile, NSError *_Nullable error) { @@ -428,6 +472,7 @@ - (void)testProfileNotRefreshedIfNotStale XCTAssertEqualObjects(profile.name, SampleUserProfile.valid.name); XCTAssertEqualObjects(profile.userID, SampleUserProfile.valid.userID); XCTAssertEqualObjects(profile.linkURL, SampleUserProfile.valid.linkURL); + XCTAssertEqualObjects(profile.email, SampleUserProfile.valid.email); } graphRequest:self.graphRequestMock]; } @@ -471,10 +516,12 @@ - (void)testProfileParseBlockReturnsNilIfResultIsEmpty - (void)testProfileParseBlockReturnsNilIfResultHasNoId { - id result = @{ @"first_name" : @"firstname", - @"middle_name" : @"middlename", - @"last_name" : @"lastname", - @"name" : @"name"}; + id result = @{ + @"first_name" : @"firstname", + @"middle_name" : @"middlename", + @"last_name" : @"lastname", + @"name" : @"name" + }; [self stubGraphRequestWithResult:result error:nil connection:nil]; [FBSDKProfile loadProfileWithToken:SampleAccessToken.validToken completion:nil graphRequest:self.graphRequestMock]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift index 122b7b23d0..de0faddf14 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleUserProfile.swift @@ -27,7 +27,9 @@ import FBSDKCoreKit lastName: "Smith", name: "John Smith", linkURL: URL(string: "http://www.example.com"), - refreshDate: .distantFuture + refreshDate: .distantFuture, + imageURL: URL(string: "http://www.example.com/image.jpg"), + email: "example@example.com" ) } } From 2d478aa1d7885525164048e2711e6cf05eac6ae3 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005325678 Date: Wed, 2 Dec 2020 04:11:47 -0800 Subject: [PATCH 143/227] Daily `arc lint --take UNCRUSTIFY` Reviewed By: zertosh Differential Revision: D25267212 fbshipit-source-id: a50caec4df720cc25a779d02167100a5675da12a --- .../FBSDKLoginKit/FBSDKLoginConfiguration.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m index 9a94019703..52d6cfe57a 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m @@ -20,15 +20,15 @@ #if !TARGET_OS_TV -#import "FBSDKLoginConfiguration.h" + #import "FBSDKLoginConfiguration.h" -#import "FBSDKNonceUtility.h" + #import "FBSDKNonceUtility.h" -#ifdef FBSDKCOCOAPODS - #import -#else - #import "FBSDKCoreKit+Internal.h" -#endif + #ifdef FBSDKCOCOAPODS + #import + #else + #import "FBSDKCoreKit+Internal.h" + #endif @implementation FBSDKLoginConfiguration From 2ca1f29cadbce94c0fbb12d707a81b7e05e4df21 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 2 Dec 2020 15:01:30 -0800 Subject: [PATCH 144/227] Persisting AuthenticationToken Summary: * Moves AuthenticationToken to CoreKit. * Adds AuthenticationToken.currentAuthenticationToken * Fetches cached token on app launch * Nils out token on logout * Construct token upon successful login Reviewed By: joesus Differential Revision: D25257031 fbshipit-source-id: 02f2f2eb4489ab083fa9a44d5412ba4f59dffaac --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 94 ++++++++++------ FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m | 2 +- .../FBSDKCoreKit/FBSDKApplicationDelegate.m | 8 +- .../FBSDKCoreKit}/FBSDKAuthenticationToken.h | 9 +- .../FBSDKCoreKit}/FBSDKAuthenticationToken.m | 95 +++++++++++++--- FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 2 + FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m | 10 +- .../FBSDKAuthenticationToken+Internal.h | 0 .../Internal/FBSDKCoreKit+Internal.h | 8 +- .../Internal/FBSDKSettings+Internal.h | 6 +- ...DKAccessTokenCache.h => FBSDKTokenCache.h} | 6 +- ...DKAccessTokenCache.m => FBSDKTokenCache.m} | 87 ++++++++++++--- ...cessTokenCaching.h => FBSDKTokenCaching.h} | 8 +- .../include/FBSDKAuthenticationToken.h | 1 + .../FBSDKApplicationDelegateTests.m | 31 +++++- .../FBSDKAuthenticationTokenTests.m | 104 ++++++++++++++---- .../FBSDKCoreKitTests-Bridging-Header.h | 8 ++ .../Internal/Helpers/FBSDKTestCase.h | 12 +- .../Internal/Helpers/FBSDKTestCase.m | 18 ++- .../Internal/Helpers/FakeTokenCache.swift | 33 ++++++ ....swift => SampleAuthenticationToken.swift} | 18 +-- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 22 ---- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h | 3 +- .../FBSDKLoginKit/FBSDKLoginManager.m | 1 + .../Internal/FBSDKLoginCompletion.m | 9 +- .../FBSDKLoginManagerTests.m | 26 ++++- 26 files changed, 459 insertions(+), 162 deletions(-) rename {FBSDKLoginKit/FBSDKLoginKit => FBSDKCoreKit/FBSDKCoreKit}/FBSDKAuthenticationToken.h (89%) rename {FBSDKLoginKit/FBSDKLoginKit => FBSDKCoreKit/FBSDKCoreKit}/FBSDKAuthenticationToken.m (69%) rename {FBSDKLoginKit/FBSDKLoginKit => FBSDKCoreKit/FBSDKCoreKit}/Internal/FBSDKAuthenticationToken+Internal.h (100%) rename FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/{FBSDKAccessTokenCache.h => FBSDKTokenCache.h} (90%) rename FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/{FBSDKAccessTokenCache.m => FBSDKTokenCache.m} (54%) rename FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/{FBSDKAccessTokenCaching.h => FBSDKTokenCaching.h} (87%) create mode 120000 FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAuthenticationToken.h rename {FBSDKLoginKit/FBSDKLoginKitTests => FBSDKCoreKit/FBSDKCoreKitTests}/FBSDKAuthenticationTokenTests.m (79%) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeTokenCache.swift rename FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/{FakeAccessTokenCache.swift => SampleAuthenticationToken.swift} (80%) diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index a09ce3857b..abe34ab6c6 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -201,7 +201,7 @@ 814AC7E31D1B528900D61E6C /* FBSDKAppEventsDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */; }; 814AC7E41D1B528900D61E6C /* FBSDKAppEventsUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0BC15A1A8D427800BE8BA4 /* FBSDKAppEventsUtility.m */; }; 814AC7E51D1B528900D61E6C /* FBSDKServerConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 89830F2A1A7805D100226ABB /* FBSDKServerConfigurationManager.m */; }; - 814AC7E61D1B528900D61E6C /* FBSDKAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKAccessTokenCache.m */; }; + 814AC7E61D1B528900D61E6C /* FBSDKTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKTokenCache.m */; }; 814AC7E71D1B528900D61E6C /* FBSDKUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 89C8B1981A8D7A15009B07F5 /* FBSDKUtility.m */; }; 814AC7E81D1B528900D61E6C /* FBSDKBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B101A7021F8009137EF /* FBSDKBase64.m */; }; 814AC7E91D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DF18BB81A9F1A05000F6748 /* _FBSDKTemporaryErrorRecoveryAttempter.m */; }; @@ -258,7 +258,7 @@ 814AC8251D1B528900D61E6C /* FBSDKCoreKit+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 890414731A647D2E00617215 /* FBSDKCoreKit+Internal.h */; }; 814AC8261D1B528900D61E6C /* FBSDKCoreKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D26974C1A5DF40700143BFC /* FBSDKCoreKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 814AC8271D1B528900D61E6C /* FBSDKDeviceButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9E16AA1CB46C7D00C8B68F /* FBSDKDeviceButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 814AC8291D1B528900D61E6C /* FBSDKAccessTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKAccessTokenCache.h */; }; + 814AC8291D1B528900D61E6C /* FBSDKTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKTokenCache.h */; }; 814AC82A1D1B528900D61E6C /* FBSDKAppEventsState.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0BC1641A8E892C00BE8BA4 /* FBSDKAppEventsState.h */; }; 814AC82B1D1B528900D61E6C /* FBSDKAppEvents+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0BC1531A8D23DB00BE8BA4 /* FBSDKAppEvents+Internal.h */; }; 814AC82C1D1B528900D61E6C /* FBSDKTestUsersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D7E7E5F1ADF038800F53E38 /* FBSDKTestUsersManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -299,7 +299,7 @@ 81B71D031D19C87400933E93 /* FBSDKServerConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 89830F2A1A7805D100226ABB /* FBSDKServerConfigurationManager.m */; }; 81B71D041D19C87400933E93 /* FBSDKGraphRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DC658941A6EE5C500B85AAF /* FBSDKGraphRequest.m */; }; 81B71D051D19C87400933E93 /* FBSDKContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D195CC71B9FE2E000BD6BEC /* FBSDKContainerViewController.m */; }; - 81B71D061D19C87400933E93 /* FBSDKAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKAccessTokenCache.m */; }; + 81B71D061D19C87400933E93 /* FBSDKTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKTokenCache.m */; }; 81B71D071D19C87400933E93 /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 894C0B081A702194009137EF /* FBSDKCrypto.m */; }; 81B71D081D19C87400933E93 /* FBSDKAppEventsState.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0BC1651A8E892C00BE8BA4 /* FBSDKAppEventsState.m */; }; 81B71D091D19C87400933E93 /* FBSDKCloseIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D652831A855A6000BB651C /* FBSDKCloseIcon.m */; }; @@ -356,7 +356,7 @@ 81B71D461D19C87400933E93 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9894BFFA1B73D8B300FBA6DB /* SafariServices.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 81B71D481D19C87400933E93 /* FBSDKAppLinkUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E30916C1AA907BD004E91D5 /* FBSDKAppLinkUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81B71D491D19C87400933E93 /* FBSDKAppLinkResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E5557361A8D833100344F86 /* FBSDKAppLinkResolver.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 81B71D4A1D19C87400933E93 /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; + 81B71D4A1D19C87400933E93 /* FBSDKTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKTokenCaching.h */; }; 81B71D4B1D19C87400933E93 /* FBSDKBridgeAPIResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0ADD1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h */; }; 81B71D4C1D19C87400933E93 /* FBSDKCoreKit+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 890414731A647D2E00617215 /* FBSDKCoreKit+Internal.h */; }; 81B71D4D1D19C87400933E93 /* FBSDKMeasurementEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EB63D9E1A9BE730003A7AED /* FBSDKMeasurementEventListener.h */; }; @@ -429,7 +429,7 @@ 81B71D9A1D19C87400933E93 /* FBSDKKeychainStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83C1A69941A000A936D /* FBSDKKeychainStore.h */; }; 81B71D9B1D19C87400933E93 /* FBSDKTestUsersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D7E7E5F1ADF038800F53E38 /* FBSDKTestUsersManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81B71D9C1D19C87400933E93 /* FBSDKAppEventsDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */; }; - 81B71D9D1D19C87400933E93 /* FBSDKAccessTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKAccessTokenCache.h */; }; + 81B71D9D1D19C87400933E93 /* FBSDKTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKTokenCache.h */; }; 81B71DCE1D19C8BF00933E93 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893F449F1A64450C001DB0B6 /* UIKit.framework */; }; 81B71DD21D19C8CF00933E93 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893F44A11A644512001DB0B6 /* CoreGraphics.framework */; }; 81C969321C114723002FC037 /* FBSDKDynamicFrameworkLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 81C969301C114723002FC037 /* FBSDKDynamicFrameworkLoader.h */; }; @@ -537,11 +537,11 @@ 9D28F19A1DB14DBB0057D709 /* FBSDKImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28F1921DB14DBB0057D709 /* FBSDKImageDownloader.m */; }; 9D30290A1A65C4420086B9ED /* FBSDKAccessToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D3029081A65C4420086B9ED /* FBSDKAccessToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D30290B1A65C4420086B9ED /* FBSDKAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D3029091A65C4420086B9ED /* FBSDKAccessToken.m */; }; - 9D32A8401A69941A000A936D /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; + 9D32A8401A69941A000A936D /* FBSDKTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKTokenCaching.h */; }; 9D32A8411A69941A000A936D /* FBSDKKeychainStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83C1A69941A000A936D /* FBSDKKeychainStore.h */; }; 9D32A8421A69941A000A936D /* FBSDKKeychainStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A83D1A69941A000A936D /* FBSDKKeychainStore.m */; }; - 9D32A8451A699459000A936D /* FBSDKAccessTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKAccessTokenCache.h */; }; - 9D32A8461A699459000A936D /* FBSDKAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKAccessTokenCache.m */; }; + 9D32A8451A699459000A936D /* FBSDKTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKTokenCache.h */; }; + 9D32A8461A699459000A936D /* FBSDKTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKTokenCache.m */; }; 9D34A11F1A5F038300C37317 /* FBSDKApplicationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D34A11D1A5F038300C37317 /* FBSDKApplicationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D34A1201A5F038300C37317 /* FBSDKApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D34A11E1A5F038300C37317 /* FBSDKApplicationDelegate.m */; }; 9D3AF4501A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D3AF44E1A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h */; }; @@ -570,8 +570,8 @@ 9D6DEEB01BC2379C001A94ED /* FBSDKTimeSpentData.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0BC14D1A8D236200BE8BA4 /* FBSDKTimeSpentData.m */; }; 9D6DEEB11BC23834001A94ED /* FBSDKAppEventsState.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0BC1651A8E892C00BE8BA4 /* FBSDKAppEventsState.m */; }; 9D6DEEB21BC23838001A94ED /* FBSDKAppEventsState.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0BC1641A8E892C00BE8BA4 /* FBSDKAppEventsState.h */; }; - 9D6DEEB31BC23850001A94ED /* FBSDKAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKAccessTokenCache.m */; }; - 9D6DEEB41BC23855001A94ED /* FBSDKAccessTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKAccessTokenCache.h */; }; + 9D6DEEB31BC23850001A94ED /* FBSDKTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D32A8441A699459000A936D /* FBSDKTokenCache.m */; }; + 9D6DEEB41BC23855001A94ED /* FBSDKTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A8431A699459000A936D /* FBSDKTokenCache.h */; }; 9D6DEEB51BC23862001A94ED /* FBSDKAppEventsStateManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0BC15E1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.m */; }; 9D6DEEB61BC2386C001A94ED /* FBSDKAppEventsStateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0BC15D1A8D428700BE8BA4 /* FBSDKAppEventsStateManager.h */; }; 9D6DEEB71BC23890001A94ED /* FBSDKErrorRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D3AF4881A9EFA0300EEF724 /* FBSDKErrorRecoveryAttempter.m */; }; @@ -852,8 +852,8 @@ F44B056F256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F44B056E256491590059A3A6 /* FBSDKBridgeAPI+SessionCompletionHandlerTests.m */; }; F462DBF023B94C0F00FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; F462DBF123B94C1000FFCECA /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 894C0B071A702194009137EF /* FBSDKCrypto.h */; }; - F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; - F462DBFE23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */; }; + F462DBFD23B9569000FFCECA /* FBSDKTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKTokenCaching.h */; }; + F462DBFE23B9569000FFCECA /* FBSDKTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D32A83B1A69941A000A936D /* FBSDKTokenCaching.h */; }; F462DBFF23B9575000FFCECA /* FBSDKServerConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8917C4AB1B7A46C800B0B96B /* FBSDKServerConfiguration+Internal.h */; }; F462DC0023B9575100FFCECA /* FBSDKServerConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8917C4AB1B7A46C800B0B96B /* FBSDKServerConfiguration+Internal.h */; }; F462DC0123B9578E00FFCECA /* FBSDKGraphRequestConnection+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D69FC421AA66BBC0068EC76 /* FBSDKGraphRequestConnection+Internal.h */; }; @@ -920,10 +920,18 @@ F4713D7D2375DA8200748692 /* FBSDKSuggestedEventsIndexer.m in Sources */ = {isa = PBXBuildFile; fileRef = BF247C812374E1B200A522C0 /* FBSDKSuggestedEventsIndexer.m */; }; F47E560D24E1EA8D001497C9 /* FakeBundle.m in Sources */ = {isa = PBXBuildFile; fileRef = F47E55FB24E1EA8D001497C9 /* FakeBundle.m */; }; F48A6AED24170D29002C6CA1 /* TestMonitorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */; }; + F48AD2E52576FE050052C056 /* FBSDKAuthenticationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = F48AD2E32576FE050052C056 /* FBSDKAuthenticationToken.m */; }; + F48AD2E62576FE050052C056 /* FBSDKAuthenticationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = F48AD2E32576FE050052C056 /* FBSDKAuthenticationToken.m */; }; + F48AD2E92576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = F48AD2E42576FE050052C056 /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F48AD2EA2576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = F48AD2E42576FE050052C056 /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F48AD2EB2576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = F48AD2E42576FE050052C056 /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F48AD2EC2576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = F48AD2E42576FE050052C056 /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F48AD3252576FEB20052C056 /* FBSDKAuthenticationTokenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F48AD3242576FEB20052C056 /* FBSDKAuthenticationTokenTests.m */; }; + F48AD348257700B80052C056 /* SampleAuthenticationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F48AD347257700B80052C056 /* SampleAuthenticationToken.swift */; }; F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */; }; F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; - F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */; }; + F496E5FE24E5D0D5006231A2 /* FakeTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeTokenCache.swift */; }; F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.swift */; }; F496E61224E6049A006231A2 /* AppDelegateObserverFake.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */; }; F4A52AED242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4A52AEC242A7D12005F65CE /* FBSDKPerformanceMonitorEntryTests.m */; }; @@ -1424,11 +1432,11 @@ 9D28F1921DB14DBB0057D709 /* FBSDKImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKImageDownloader.m; sourceTree = ""; }; 9D3029081A65C4420086B9ED /* FBSDKAccessToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessToken.h; sourceTree = ""; }; 9D3029091A65C4420086B9ED /* FBSDKAccessToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessToken.m; sourceTree = ""; }; - 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessTokenCaching.h; sourceTree = ""; }; + 9D32A83B1A69941A000A936D /* FBSDKTokenCaching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKTokenCaching.h; sourceTree = ""; }; 9D32A83C1A69941A000A936D /* FBSDKKeychainStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKKeychainStore.h; sourceTree = ""; }; 9D32A83D1A69941A000A936D /* FBSDKKeychainStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKKeychainStore.m; sourceTree = ""; }; - 9D32A8431A699459000A936D /* FBSDKAccessTokenCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAccessTokenCache.h; sourceTree = ""; }; - 9D32A8441A699459000A936D /* FBSDKAccessTokenCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAccessTokenCache.m; sourceTree = ""; }; + 9D32A8431A699459000A936D /* FBSDKTokenCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKTokenCache.h; sourceTree = ""; }; + 9D32A8441A699459000A936D /* FBSDKTokenCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTokenCache.m; sourceTree = ""; }; 9D34A11D1A5F038300C37317 /* FBSDKApplicationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKApplicationDelegate.h; sourceTree = ""; }; 9D34A11E1A5F038300C37317 /* FBSDKApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKApplicationDelegate.m; sourceTree = ""; }; 9D3AF44E1A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKErrorConfiguration.h; sourceTree = ""; }; @@ -1586,11 +1594,16 @@ F487DBD9231EC293008416A9 /* AccessToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessToken.swift; sourceTree = ""; }; F48A6AEB24170D29002C6CA1 /* TestMonitorEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestMonitorEntry.h; sourceTree = ""; }; F48A6AEC24170D29002C6CA1 /* TestMonitorEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestMonitorEntry.m; sourceTree = ""; }; + F48AD2E32576FE050052C056 /* FBSDKAuthenticationToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationToken.m; sourceTree = ""; }; + F48AD2E42576FE050052C056 /* FBSDKAuthenticationToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationToken.h; sourceTree = ""; }; + F48AD3242576FEB20052C056 /* FBSDKAuthenticationTokenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenTests.m; sourceTree = ""; }; + F48AD347257700B80052C056 /* SampleAuthenticationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAuthenticationToken.swift; sourceTree = ""; }; + F48AD3702577066A0052C056 /* FBSDKAuthenticationToken+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKAuthenticationToken+Internal.h"; sourceTree = ""; }; F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDefaultsSpy.h; sourceTree = ""; }; F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainStoreSpy.swift; sourceTree = ""; }; F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; - F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeAccessTokenCache.swift; sourceTree = ""; }; + F496E5FD24E5D0D5006231A2 /* FakeTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeTokenCache.swift; sourceTree = ""; }; F496E60E24E5D195006231A2 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegateObserverFake.swift; sourceTree = ""; }; F4A11B4824E36E5200D4C010 /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKTypeUtility.h; sourceTree = ""; }; @@ -1982,6 +1995,7 @@ isa = PBXGroup; children = ( B3C20ACC250B100F00DEC008 /* FBSDKAccessToken+Internal.h */, + F48AD3702577066A0052C056 /* FBSDKAuthenticationToken+Internal.h */, 5DB7ADCA22EA59E60012E8CB /* Instrument */, 894C0B0E1A7021F8009137EF /* Base64 */, 894C0AE11A6F1D27009137EF /* BridgeAPI */, @@ -2302,6 +2316,8 @@ C5188F1C223857D700F4D8BC /* AppLink */, 9D3029081A65C4420086B9ED /* FBSDKAccessToken.h */, 9D3029091A65C4420086B9ED /* FBSDKAccessToken.m */, + F48AD2E42576FE050052C056 /* FBSDKAuthenticationToken.h */, + F48AD2E32576FE050052C056 /* FBSDKAuthenticationToken.m */, 9D34A11D1A5F038300C37317 /* FBSDKApplicationDelegate.h */, 9D34A11E1A5F038300C37317 /* FBSDKApplicationDelegate.m */, 891687EC1AB38C7C00F55364 /* FBSDKButton.h */, @@ -2348,6 +2364,7 @@ 9D2697561A5DF40700143BFC /* FBSDKCoreKitTests */ = { isa = PBXGroup; children = ( + F48AD3242576FEB20052C056 /* FBSDKAuthenticationTokenTests.m */, F4A826B624EC6FAC00EB2CD4 /* FBSDKProfileTests.m */, F413883D24C76F3B001BC075 /* FBSDKSafeCastTests.m */, 7E253D841A8EB78300CCCFE7 /* FBSDKCoreKitTestUtility.h */, @@ -2377,9 +2394,9 @@ 9D32A8381A69941A000A936D /* TokenCaching */ = { isa = PBXGroup; children = ( - 9D32A8431A699459000A936D /* FBSDKAccessTokenCache.h */, - 9D32A8441A699459000A936D /* FBSDKAccessTokenCache.m */, - 9D32A83B1A69941A000A936D /* FBSDKAccessTokenCaching.h */, + 9D32A8431A699459000A936D /* FBSDKTokenCache.h */, + 9D32A8441A699459000A936D /* FBSDKTokenCache.m */, + 9D32A83B1A69941A000A936D /* FBSDKTokenCaching.h */, 9D32A83C1A69941A000A936D /* FBSDKKeychainStore.h */, 9D32A83D1A69941A000A936D /* FBSDKKeychainStore.m */, 9DE1F3CB1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.h */, @@ -2701,8 +2718,9 @@ F40B24C124732DD90059351C /* Fuzzer.swift */, F4DE31F424DB695100297C18 /* FBSDKTestCase.h */, F4DE31F524DB695100297C18 /* FBSDKTestCase.m */, - F496E5FD24E5D0D5006231A2 /* FakeAccessTokenCache.swift */, + F496E5FD24E5D0D5006231A2 /* FakeTokenCache.swift */, F496E60E24E5D195006231A2 /* SampleAccessToken.swift */, + F48AD347257700B80052C056 /* SampleAuthenticationToken.swift */, F496E61124E6049A006231A2 /* AppDelegateObserverFake.swift */, F4E50153243648A100C99262 /* FBSDKServerConfigurationFixtures.m */, F4ED90DA24EDDC610048D283 /* NotificationCenterSpy.swift */, @@ -2834,9 +2852,10 @@ 814AC8271D1B528900D61E6C /* FBSDKDeviceButton.h in Headers */, C5EAFAB725528EAF00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, F42004922416C30300AD7006 /* FBSDKMonitor.h in Headers */, - 814AC8291D1B528900D61E6C /* FBSDKAccessTokenCache.h in Headers */, + 814AC8291D1B528900D61E6C /* FBSDKTokenCache.h in Headers */, 814AC82A1D1B528900D61E6C /* FBSDKAppEventsState.h in Headers */, 814AC82B1D1B528900D61E6C /* FBSDKAppEvents+Internal.h in Headers */, + F48AD2EC2576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */, 52D4F0D51D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */, 814AC82C1D1B528900D61E6C /* FBSDKTestUsersManager.h in Headers */, 814AC82D1D1B528900D61E6C /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, @@ -2879,7 +2898,7 @@ 814AC84B1D1B528900D61E6C /* FBSDKDeviceButton+Internal.h in Headers */, 814AC84C1D1B528900D61E6C /* FBSDKGraphRequest+Internal.h in Headers */, 814AC84D1D1B528900D61E6C /* FBSDKApplicationDelegate+Internal.h in Headers */, - F462DBFD23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */, + F462DBFD23B9569000FFCECA /* FBSDKTokenCaching.h in Headers */, F4210E31241B00790061F56D /* FBSDKMethodUsageMonitor.h in Headers */, 5D4360DE23219F7900254DF7 /* FBSDKCrashObserver.h in Headers */, 814AC84E1D1B528900D61E6C /* FBSDKServerConfigurationManager.h in Headers */, @@ -2905,7 +2924,7 @@ 81B71D481D19C87400933E93 /* FBSDKAppLinkUtility.h in Headers */, 81B71D491D19C87400933E93 /* FBSDKAppLinkResolver.h in Headers */, 52963AA6215993C100C7B252 /* FBSDKAppLink_Internal.h in Headers */, - 81B71D4A1D19C87400933E93 /* FBSDKAccessTokenCaching.h in Headers */, + 81B71D4A1D19C87400933E93 /* FBSDKTokenCaching.h in Headers */, 52963A81215992F400C7B252 /* FBSDKAppLinkNavigation.h in Headers */, 5D81B412238739B100B02B2E /* FBSDKIntegrityManager.h in Headers */, 81B71D4B1D19C87400933E93 /* FBSDKBridgeAPIResponse.h in Headers */, @@ -3022,6 +3041,7 @@ 81B71D941D19C87400933E93 /* FBSDKAppEvents.h in Headers */, C5188DFA222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */, 81B71D951D19C87400933E93 /* FBSDKGraphRequest.h in Headers */, + F48AD2EA2576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */, 81B71D961D19C87400933E93 /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */, F4A52B0F242AA532005F65CE /* FBSDKPerformanceMonitor.h in Headers */, 81B71D971D19C87400933E93 /* FBSDKURLOpening.h in Headers */, @@ -3036,7 +3056,7 @@ 81B71D9B1D19C87400933E93 /* FBSDKTestUsersManager.h in Headers */, C5C7B74B22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */, 81B71D9C1D19C87400933E93 /* FBSDKAppEventsDeviceInfo.h in Headers */, - 81B71D9D1D19C87400933E93 /* FBSDKAccessTokenCache.h in Headers */, + 81B71D9D1D19C87400933E93 /* FBSDKTokenCache.h in Headers */, F9FD9A6321659F120068DEAF /* FBSDKGateKeeperManager.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3048,7 +3068,7 @@ F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, 7E30917B1AA92A95004E91D5 /* FBSDKAppLinkUtility.h in Headers */, 7E5557381A8D833100344F86 /* FBSDKAppLinkResolver.h in Headers */, - 9D32A8401A69941A000A936D /* FBSDKAccessTokenCaching.h in Headers */, + 9D32A8401A69941A000A936D /* FBSDKTokenCaching.h in Headers */, F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, 894C0ADF1A6F1D1B009137EF /* FBSDKBridgeAPIResponse.h in Headers */, 890414741A647D8800617215 /* FBSDKCoreKit+Internal.h in Headers */, @@ -3153,6 +3173,7 @@ 52963A8C215992F400C7B252 /* FBSDKAppLink.h in Headers */, 891687FE1AB38D2300F55364 /* FBSDKButton+Subclass.h in Headers */, 9D30290A1A65C4420086B9ED /* FBSDKAccessToken.h in Headers */, + F48AD2E92576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */, 9D26974D1A5DF40700143BFC /* FBSDKCoreKit.h in Headers */, 9DC658A51A6EE7E200B85AAF /* FBSDKGraphRequestBody.h in Headers */, 896DE2341A9E509300195731 /* FBSDKGraphRequestDataAttachment.h in Headers */, @@ -3182,7 +3203,7 @@ 9D7E7E611ADF038800F53E38 /* FBSDKTestUsersManager.h in Headers */, C5C7B74A22D84F64004A5A0C /* FBSDKFeatureManager.h in Headers */, 5F7063FB1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h in Headers */, - 9D32A8451A699459000A936D /* FBSDKAccessTokenCache.h in Headers */, + 9D32A8451A699459000A936D /* FBSDKTokenCache.h in Headers */, F943112124FB1A54002441F1 /* FBSDKSKAdNetworkEvent.h in Headers */, 52963A80215992F400C7B252 /* FBSDKAppLinkNavigation.h in Headers */, ); @@ -3220,9 +3241,10 @@ F42004912416C30300AD7006 /* FBSDKMonitor.h in Headers */, C5EAFAA925528EAE00458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, 9D9E16AE1CB46C8900C8B68F /* FBSDKDeviceButton.h in Headers */, - 9D6DEEB41BC23855001A94ED /* FBSDKAccessTokenCache.h in Headers */, + 9D6DEEB41BC23855001A94ED /* FBSDKTokenCache.h in Headers */, 9D6DEEB21BC23838001A94ED /* FBSDKAppEventsState.h in Headers */, 9DB0FA8A1BC1CED0005EB8B1 /* FBSDKAppEvents+Internal.h in Headers */, + F48AD2EB2576FE050052C056 /* FBSDKAuthenticationToken.h in Headers */, 52D4F0D41D91A1950030B7FC /* FBSDKDeviceRequestsHelper.h in Headers */, 9D6DEEDB1BC24295001A94ED /* FBSDKTestUsersManager.h in Headers */, 9D6DEED11BC23A93001A94ED /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, @@ -3265,7 +3287,7 @@ 9D9E16B11CB46D3C00C8B68F /* FBSDKDeviceButton+Internal.h in Headers */, 9DB0FA9D1BC22CA2005EB8B1 /* FBSDKGraphRequest+Internal.h in Headers */, 9D65383D1BF44F7D008A08E9 /* FBSDKApplicationDelegate+Internal.h in Headers */, - F462DBFE23B9569000FFCECA /* FBSDKAccessTokenCaching.h in Headers */, + F462DBFE23B9569000FFCECA /* FBSDKTokenCaching.h in Headers */, F4210E30241B00790061F56D /* FBSDKMethodUsageMonitor.h in Headers */, 5D4360DD23219F7900254DF7 /* FBSDKCrashObserver.h in Headers */, 9D6DEECA1BC23A36001A94ED /* FBSDKServerConfigurationManager.h in Headers */, @@ -3808,7 +3830,7 @@ 5D6DF1662398E28000AC2D6C /* FBSDKEventDeactivationManager.m in Sources */, 814AC7E41D1B528900D61E6C /* FBSDKAppEventsUtility.m in Sources */, 814AC7E51D1B528900D61E6C /* FBSDKServerConfigurationManager.m in Sources */, - 814AC7E61D1B528900D61E6C /* FBSDKAccessTokenCache.m in Sources */, + 814AC7E61D1B528900D61E6C /* FBSDKTokenCache.m in Sources */, F468B35524C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E323219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 814AC7E71D1B528900D61E6C /* FBSDKUtility.m in Sources */, @@ -3895,7 +3917,7 @@ 81B71D041D19C87400933E93 /* FBSDKGraphRequest.m in Sources */, F9CBE51424E090590097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, 81B71D051D19C87400933E93 /* FBSDKContainerViewController.m in Sources */, - 81B71D061D19C87400933E93 /* FBSDKAccessTokenCache.m in Sources */, + 81B71D061D19C87400933E93 /* FBSDKTokenCache.m in Sources */, 81B71D071D19C87400933E93 /* FBSDKCrypto.m in Sources */, F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 81B71D081D19C87400933E93 /* FBSDKAppEventsState.m in Sources */, @@ -3990,6 +4012,7 @@ 5D4360E123219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, F468B34324C25AB600979F8D /* FBSDKBasicUtility.m in Sources */, F9FD9A7E21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, + F48AD2E62576FE050052C056 /* FBSDKAuthenticationToken.m in Sources */, 81B71D3D1D19C87400933E93 /* FBSDKAppEvents.m in Sources */, FDAF4A912395D27D00711C4C /* FBSDKModelUtility.m in Sources */, 81B71D3E1D19C87400933E93 /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, @@ -4025,7 +4048,7 @@ F9CBE51224E085CD0097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */, C4FC99DA202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, - 9D32A8461A699459000A936D /* FBSDKAccessTokenCache.m in Sources */, + 9D32A8461A699459000A936D /* FBSDKTokenCache.m in Sources */, F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */, 894C0B0A1A702194009137EF /* FBSDKCrypto.m in Sources */, 9D0BC1671A8E892C00BE8BA4 /* FBSDKAppEventsState.m in Sources */, @@ -4119,6 +4142,7 @@ 5D6DF1632398E28000AC2D6C /* FBSDKEventDeactivationManager.m in Sources */, 9DC6589F1A6EE7D800B85AAF /* FBSDKGraphRequestConnection.m in Sources */, 5D4360E023219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, + F48AD2E52576FE050052C056 /* FBSDKAuthenticationToken.m in Sources */, 9D0BC1581A8D23E200BE8BA4 /* FBSDKAppEvents.m in Sources */, FDAF4A8D2395D21700711C4C /* FBSDKModelUtility.m in Sources */, F9FD9A7D21659F320068DEAF /* FBSDKGateKeeperManager.m in Sources */, @@ -4161,6 +4185,7 @@ F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.swift in Sources */, F93680E3249D490600446E35 /* FBSDKSettingsTests.m in Sources */, E4C2B97A23867327002335A4 /* FBSDKModelRuntimeTests.mm in Sources */, + F48AD348257700B80052C056 /* SampleAuthenticationToken.swift in Sources */, F496E61224E6049A006231A2 /* AppDelegateObserverFake.swift in Sources */, BF5D97C3242EC2D10096D7AA /* FBSDKFeatureExtractorTests.m in Sources */, 5DAB023C23A1BA17005495FB /* FBSDKEventDeactivationTests.swift in Sources */, @@ -4177,6 +4202,7 @@ 894C0B3A1A702EBE009137EF /* FBSDKBridgeAPIProtocolNativeV1Tests.m in Sources */, F4E50156243648A100C99262 /* FBSDKServerConfigurationTests.m in Sources */, F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */, + F48AD3252576FEB20052C056 /* FBSDKAuthenticationTokenTests.m in Sources */, 2A3DA4161CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift in Sources */, F4DE31F624DB695100297C18 /* FBSDKTestCase.m in Sources */, 5D2165F22229C6A3004952D8 /* FBSDKGraphRequestTests.m in Sources */, @@ -4220,7 +4246,7 @@ 5DB612A823593AB600150851 /* FBSDKCrashShieldTests.m in Sources */, F44B04B7256442050059A3A6 /* FBSDKBridgeAPIOpenUrlWithSafariTests.m in Sources */, E493252D23F7C60E0000B63A /* FBSDKModelParserTests.mm in Sources */, - F496E5FE24E5D0D5006231A2 /* FakeAccessTokenCache.swift in Sources */, + F496E5FE24E5D0D5006231A2 /* FakeTokenCache.swift in Sources */, F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.swift in Sources */, 5D68D7D822BAEEF60063A3E2 /* FBSDKTimeSpentDataTests.m in Sources */, 9D3AF4661A9ED47900EEF724 /* FBSDKGraphRequestConnectionTests.m in Sources */, @@ -4248,7 +4274,7 @@ 5D6DF1652398E28000AC2D6C /* FBSDKEventDeactivationManager.m in Sources */, 9DB0FA8D1BC1CEF4005EB8B1 /* FBSDKAppEventsUtility.m in Sources */, 9D6DEEC91BC23A30001A94ED /* FBSDKServerConfigurationManager.m in Sources */, - 9D6DEEB31BC23850001A94ED /* FBSDKAccessTokenCache.m in Sources */, + 9D6DEEB31BC23850001A94ED /* FBSDKTokenCache.m in Sources */, F468B35424C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, 5D4360E223219F8E00254DF7 /* FBSDKCrashObserver.m in Sources */, 9DB0FA971BC22BC0005EB8B1 /* FBSDKUtility.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m index cd18a7c825..ba8d71bdfc 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m @@ -153,7 +153,7 @@ + (void)setCurrentAccessToken:(nullable FBSDKAccessToken *)token [FBSDKInternalUtility deleteFacebookCookies]; } - [FBSDKSettings accessTokenCache].accessToken = token; + [FBSDKSettings tokenCache].accessToken = token; if (shouldDispatchNotif) { [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAccessTokenDidChangeNotification object:[self class] diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m index 7d965830b7..0d1d43b20d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m @@ -247,8 +247,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( } _isAppLaunched = YES; - FBSDKAccessToken *cachedToken = [FBSDKSettings accessTokenCache].accessToken; + + // Retrieve cached tokens + FBSDKAccessToken *cachedToken = FBSDKSettings.tokenCache.accessToken; [FBSDKAccessToken setCurrentAccessToken:cachedToken]; + // fetch app settings [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; @@ -258,6 +261,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( #if !TARGET_OS_TV FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile]; [FBSDKProfile setCurrentProfile:cachedProfile]; + + FBSDKAuthenticationToken *cachedAuthToken = FBSDKSettings.tokenCache.authenticationToken; + [FBSDKAuthenticationToken setCurrentAuthenticationToken:cachedAuthToken]; #endif NSArray> *observers = [_applicationObservers allObjects]; BOOL handled = NO; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h similarity index 89% rename from FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h rename to FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h index aed59a550c..bee2a0154e 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h @@ -18,15 +18,13 @@ #import -#import "FBSDKLoginConfiguration.h" - NS_ASSUME_NONNULL_BEGIN /** Represent an AuthenticationToken used for a login attempt */ NS_SWIFT_NAME(AuthenticationToken) -@interface FBSDKAuthenticationToken : NSObject +@interface FBSDKAuthenticationToken : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; @@ -49,11 +47,6 @@ NS_SWIFT_NAME(AuthenticationToken) */ @property (nonatomic, copy, readonly) NSString *nonce; -/** - The beta login experience preference used for the login attempt that resulted in the creation of the token - */ -@property (nonatomic, readonly) FBSDKBetaLoginExperience betaLoginExperience; - /** Initializes a new instance if the token represented by the token string is valid. Otherwise returns nil. An `AuthenticationToken` is verified based of the OpenID Connect Protocol. diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m similarity index 69% rename from FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m rename to FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index 8fd8c49d7d..c8b6c73230 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -38,6 +38,9 @@ static FBSDKAuthenticationToken *g_currentAuthenticationToken; +NSString *const FBSDKAuthenticationTokenTokenStringCodingKey = @"FBSDKAuthenticationTokenTokenStringCodingKey"; +NSString *const FBSDKAuthenticationTokenNonceCodingKey = @"FBSDKAuthenticationTokenNonceCodingKey"; + static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins @implementation FBSDKAuthenticationToken @@ -55,28 +58,52 @@ - (instancetype)initWithTokenString:(NSString *)tokenString return nil; } + NSString *signature; + NSDictionary *claims; + NSDictionary *header; + NSArray *segments = [tokenString componentsSeparatedByString:@"."]; if (segments.count != 3) { return nil; } - if (self = [super init]) { - NSString *encodedHeader = [FBSDKTypeUtility array:segments objectAtIndex:0]; - NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; - _signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; + NSString *encodedHeader = [FBSDKTypeUtility array:segments objectAtIndex:0]; + NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; + signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; - if (![self verifySignature:_signature - header:encodedHeader - claims:encodedClaims]) { - return nil; - } + if (![self verifySignature:signature + header:encodedHeader + claims:encodedClaims]) { + return nil; + } - _claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; - _header = [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; + claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; + header = [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; - if (!_claims || !_header) { - return nil; - } + if (!claims || !header) { + return nil; + } + + return [self initWithTokenString:tokenString + nonce:nonce + signature:signature + claims:claims + header:header]; +} + +/// Do not call directly. Does not validate any of the data. +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + signature:(NSString *)signature + claims:(NSDictionary *)claims + header:(NSDictionary *)header +{ + if ((self = [super init])) { + _tokenString = tokenString; + _nonce = nonce; + _signature = signature; + _claims = claims; + _header = header; } return self; @@ -91,13 +118,14 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token { if (token != g_currentAuthenticationToken) { g_currentAuthenticationToken = token; + [[self tokenCache] setAuthenticationToken:token]; } } + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce { NSError *error; - NSData *claimsData = [FBSDKBase64 decodeAsData:encodedClaims]; + NSData *claimsData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:encodedClaims]]; if (claimsData) { NSDictionary *claims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; @@ -124,7 +152,7 @@ + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims non + (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader { NSError *error; - NSData *headerData = [FBSDKBase64 decodeAsData:encodedHeader]; + NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:encodedHeader]]; if (headerData) { NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; @@ -213,10 +241,45 @@ + (NSString *)base64FromBase64Url:(NSString *)base64Url return base64; } +#pragma mark Storage + ++ (id)tokenCache +{ + return FBSDKSettings.tokenCache; +} + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + +- (instancetype)initWithCoder:(NSCoder *)decoder +{ + NSString *tokenString = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenTokenStringCodingKey]; + NSString *nonce = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenNonceCodingKey]; + + return [self initWithTokenString:tokenString + nonce:nonce + signature:nil + claims:nil + header:nil]; +} + +- (void)encodeWithCoder:(NSCoder *)encoder +{ + [encoder encodeObject:self.tokenString forKey:FBSDKAuthenticationTokenTokenStringCodingKey]; + [encoder encodeObject:self.nonce forKey:FBSDKAuthenticationTokenNonceCodingKey]; +} + #pragma mark - Test methods #if DEBUG ++ (void)resetCurrentAuthenticationTokenCache +{ + g_currentAuthenticationToken = nil; +} + static BOOL _skipSignatureVerification; + (void)setSkipSignatureVerification:(BOOL)value diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index 1fc9b542d5..d9b4660329 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -29,6 +29,7 @@ #import #import #import + #import #import #import #import @@ -66,6 +67,7 @@ #import "FBSDKAccessToken.h" #import "FBSDKAppEvents.h" #import "FBSDKApplicationDelegate.h" + #import "FBSDKAuthenticationToken.h" #import "FBSDKButton.h" #import "FBSDKConstants.h" #import "FBSDKCopying.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m index 7b26d7d386..2b5fea2697 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m @@ -20,13 +20,13 @@ #import -#import "FBSDKAccessTokenCache.h" #import "FBSDKAccessTokenExpirer.h" #import "FBSDKAppEvents+Internal.h" #import "FBSDKAppEventsConfiguration.h" #import "FBSDKAppEventsConfigurationManager.h" #import "FBSDKCoreKit.h" #import "FBSDKInternalUtility.h" +#import "FBSDKTokenCache.h" #define FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE, ENABLE_CACHE) \ static TYPE *g_ ## PLIST_KEY = nil; \ @@ -63,7 +63,7 @@ + (void)SETTER:(TYPE *)value { \ FBSDKLoggingBehavior FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info"; FBSDKLoggingBehavior FBSDKLoggingBehaviorNetworkRequests = @"network_requests"; -static NSObject *g_tokenCache; +static NSObject *g_tokenCache; static NSMutableSet *g_loggingBehaviors; static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage"; static NSString *const FBSDKSettingsBitmask = @"com.facebook.sdk:FBSDKSettingsBitmask"; @@ -99,7 +99,7 @@ @implementation FBSDKSettings + (void)initialize { if (self == [FBSDKSettings class]) { - g_tokenCache = [[FBSDKAccessTokenCache alloc] init]; + g_tokenCache = [FBSDKTokenCache new]; g_accessTokenExpirer = [[FBSDKAccessTokenExpirer alloc] init]; [FBSDKSettings _logWarnings]; @@ -329,12 +329,12 @@ + (NSString *)sdkVersion #pragma mark - Internal -+ (NSObject *)accessTokenCache ++ (NSObject *)tokenCache { return g_tokenCache; } -+ (void)setAccessTokenCache:(NSObject *)cache ++ (void)setTokenCache:(NSObject *)cache { if (g_tokenCache != cache) { g_tokenCache = cache; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKAuthenticationToken+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h similarity index 100% rename from FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKAuthenticationToken+Internal.h rename to FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 9c1672cc60..7f2db78cd9 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -62,8 +62,6 @@ #endif #import "FBSDKAccessToken+Internal.h" - #import "FBSDKAccessTokenCache.h" - #import "FBSDKAccessTokenCaching.h" #import "FBSDKAppEvents+Internal.h" #import "FBSDKAppEventsConfiguration.h" #import "FBSDKAppEventsConfigurationManager.h" @@ -104,6 +102,8 @@ #import "FBSDKSettings+Internal.h" #import "FBSDKSwizzler.h" #import "FBSDKTimeSpentData.h" + #import "FBSDKTokenCache.h" + #import "FBSDKTokenCaching.h" #else @@ -171,10 +171,10 @@ #import "ServerConfiguration/FBSDKServerConfiguration+Internal.h" #import "ServerConfiguration/FBSDKServerConfigurationManager.h" #import "ServerConfiguration/FBSDKServerConfigurationManager+Internal.h" - #import "TokenCaching/FBSDKAccessTokenCache.h" - #import "TokenCaching/FBSDKAccessTokenCaching.h" #import "TokenCaching/FBSDKKeychainStore.h" #import "TokenCaching/FBSDKKeychainStoreViaBundleID.h" + #import "TokenCaching/FBSDKTokenCache.h" + #import "TokenCaching/FBSDKTokenCaching.h" #import "UI/FBSDKButton+Subclass.h" #import "UI/FBSDKIcon.h" #import "UI/FBSDKLogo.h" diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h index a018c37683..82aa62e0a8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h @@ -28,13 +28,13 @@ #define DATA_PROCESSING_OPTIONS_COUNTRY @"data_processing_options_country" #define DATA_PROCESSING_OPTIONS_STATE @"data_processing_options_state" -@protocol FBSDKAccessTokenCaching; +@protocol FBSDKTokenCaching; @interface FBSDKSettings (Internal) -+ (nullable NSObject *)accessTokenCache; ++ (nullable NSObject *)tokenCache; -+ (void)setAccessTokenCache:(nullable NSObject *)accessTokenCache; ++ (void)setTokenCache:(nullable NSObject *)tokenCache; + (FBSDKAdvertisingTrackingStatus)getAdvertisingTrackingStatus; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCache.h similarity index 90% rename from FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.h rename to FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCache.h index 2176928b4e..13ff37d373 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCache.h @@ -24,9 +24,9 @@ #import #endif -#import "FBSDKAccessTokenCaching.h" +#import "FBSDKTokenCaching.h" -NS_SWIFT_NAME(AccessTokenCache) -@interface FBSDKAccessTokenCache : NSObject +NS_SWIFT_NAME(TokenCache) +@interface FBSDKTokenCache : NSObject @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCache.m similarity index 54% rename from FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m rename to FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCache.m index 6a52b245f1..f5c2467339 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCache.m @@ -16,7 +16,7 @@ // 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 "FBSDKAccessTokenCache.h" +#import "FBSDKTokenCache.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKInternalUtility.h" @@ -24,10 +24,14 @@ static NSString *const kFBSDKAccessTokenUserDefaultsKey = @"com.facebook.sdk.v4.FBSDKAccessTokenInformationKey"; static NSString *const kFBSDKAccessTokenKeychainKey = @"com.facebook.sdk.v4.FBSDKAccessTokenInformationKeychainKey"; -static NSString *const kFBSDKAccessTokenUUIDKey = @"tokenUUID"; -static NSString *const kFBSDKAccessTokenEncodedKey = @"tokenEncoded"; -@implementation FBSDKAccessTokenCache +static NSString *const kFBSDKAuthenticationTokenUserDefaultsKey = @"com.facebook.sdk.v9.FBSDKAuthenticationTokenInformationKey"; +static NSString *const kFBSDKAuthenticationTokenKeychainKey = @"com.facebook.sdk.v9.FBSDKAuthenticationTokenInformationKeychainKey"; + +static NSString *const kFBSDKTokenUUIDKey = @"tokenUUID"; +static NSString *const kFBSDKTokenEncodedKey = @"tokenEncoded"; + +@implementation FBSDKTokenCache { FBSDKKeychainStore *_keychainStore; } @@ -43,32 +47,33 @@ - (instancetype)init #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" + - (FBSDKAccessToken *)accessToken { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *uuid = [defaults objectForKey:kFBSDKAccessTokenUserDefaultsKey]; NSDictionary *dict = [_keychainStore dictionaryForKey:kFBSDKAccessTokenKeychainKey]; - if ([dict[kFBSDKAccessTokenUUIDKey] isKindOfClass:[NSString class]]) { + if ([dict[kFBSDKTokenUUIDKey] isKindOfClass:[NSString class]]) { // there is a bug while running on simulator that the uuid stored in dict can be NSData, // do a type check to make sure it is NSString - if ([dict[kFBSDKAccessTokenUUIDKey] isEqualToString:uuid]) { - id tokenData = dict[kFBSDKAccessTokenEncodedKey]; + if ([dict[kFBSDKTokenUUIDKey] isEqualToString:uuid]) { + id tokenData = dict[kFBSDKTokenEncodedKey]; if ([tokenData isKindOfClass:[NSData class]]) { return [NSKeyedUnarchiver unarchiveObjectWithData:tokenData]; } } } // if the uuid doesn't match (including if there is no uuid in defaults which means uninstalled case) - // clear the keychain and return nil. - [self clearCache]; + // clear the access token cache and return nil. + [self clearAccessTokenCache]; return nil; } - (void)setAccessToken:(FBSDKAccessToken *)token { if (!token) { - [self clearCache]; + [self clearAccessTokenCache]; return; } NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; @@ -76,12 +81,11 @@ - (void)setAccessToken:(FBSDKAccessToken *)token if (!uuid) { uuid = [NSUUID UUID].UUIDString; [defaults setObject:uuid forKey:kFBSDKAccessTokenUserDefaultsKey]; - [defaults synchronize]; } NSData *tokenData = [NSKeyedArchiver archivedDataWithRootObject:token]; NSDictionary *dict = @{ - kFBSDKAccessTokenUUIDKey : uuid, - kFBSDKAccessTokenEncodedKey : tokenData + kFBSDKTokenUUIDKey : uuid, + kFBSDKTokenEncodedKey : tokenData }; [_keychainStore setDictionary:dict @@ -89,9 +93,64 @@ - (void)setAccessToken:(FBSDKAccessToken *)token accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; } +- (FBSDKAuthenticationToken *)authenticationToken +{ + NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; + NSString *uuid = [defaults objectForKey:kFBSDKAuthenticationTokenUserDefaultsKey]; + + NSDictionary *dict = [_keychainStore dictionaryForKey:kFBSDKAuthenticationTokenKeychainKey]; + if ([dict[kFBSDKTokenUUIDKey] isKindOfClass:[NSString class]]) { + // there is a bug while running on simulator that the uuid stored in dict can be NSData, + // do a type check to make sure it is NSString + if ([dict[kFBSDKTokenUUIDKey] isEqualToString:uuid]) { + id tokenData = dict[kFBSDKTokenEncodedKey]; + if ([tokenData isKindOfClass:[NSData class]]) { + return [NSKeyedUnarchiver unarchiveObjectWithData:tokenData]; + } + } + } + // if the uuid doesn't match (including if there is no uuid in defaults which means uninstalled case) + // clear the authentication token cache and return nil. + [self clearAuthenticationTokenCache]; + return nil; +} + +- (void)setAuthenticationToken:(FBSDKAuthenticationToken *)token +{ + if (!token) { + [self clearAuthenticationTokenCache]; + return; + } + NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; + NSString *uuid = [defaults objectForKey:kFBSDKAuthenticationTokenUserDefaultsKey]; + if (!uuid) { + uuid = NSUUID.UUID.UUIDString; + [defaults setObject:uuid forKey:kFBSDKAuthenticationTokenUserDefaultsKey]; + } + NSData *tokenData = [NSKeyedArchiver archivedDataWithRootObject:token]; + NSDictionary *dict = @{ + kFBSDKTokenUUIDKey : uuid, + kFBSDKTokenEncodedKey : tokenData + }; + + [_keychainStore setDictionary:dict + forKey:kFBSDKAuthenticationTokenKeychainKey + accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; +} + #pragma clang diagnostic pop -- (void)clearCache +- (void)clearAuthenticationTokenCache +{ + [_keychainStore setDictionary:nil + forKey:kFBSDKAuthenticationTokenKeychainKey + accessibility:NULL]; + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults removeObjectForKey:kFBSDKAuthenticationTokenUserDefaultsKey]; + [defaults synchronize]; +} + +- (void)clearAccessTokenCache { [_keychainStore setDictionary:nil forKey:kFBSDKAccessTokenKeychainKey diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCaching.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCaching.h similarity index 87% rename from FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCaching.h rename to FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCaching.h index e5595db760..f877469d6f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCaching.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKTokenCaching.h @@ -19,12 +19,12 @@ #import @class FBSDKAccessToken; +@class FBSDKAuthenticationToken; -NS_SWIFT_NAME(AccessTokenCaching) -@protocol FBSDKAccessTokenCaching +NS_SWIFT_NAME(TokenCaching) +@protocol FBSDKTokenCaching @property (nonatomic, copy) FBSDKAccessToken *accessToken; - -- (void)clearCache; +@property (nonatomic, copy) FBSDKAuthenticationToken *authenticationToken; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAuthenticationToken.h b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAuthenticationToken.h new file mode 120000 index 0000000000..a45d0a2fcc --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/include/FBSDKAuthenticationToken.h @@ -0,0 +1 @@ +../FBSDKAuthenticationToken.h \ No newline at end of file diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index 52c42d2640..0e03fb40a1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -178,8 +178,9 @@ - (void)testDidFinishLaunchingLaunchedApp - (void)testDidFinishLaunchingSetsCurrentAccessTokenWithCache { FBSDKAccessToken *expected = SampleAccessToken.validToken; - FakeAccessTokenCache *cache = [[FakeAccessTokenCache alloc] initWithToken:expected]; - [self stubAccessTokenCacheWith:cache]; + FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:expected + authenticationToken:nil]; + [self stubTokenCacheWith:cache]; [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; @@ -189,7 +190,7 @@ - (void)testDidFinishLaunchingSetsCurrentAccessTokenWithCache - (void)testDidFinishLaunchingSetsCurrentAccessTokenWithoutCache { - [self stubAccessTokenCacheWith:[[FakeAccessTokenCache alloc] initWithToken:nil]]; + [self stubTokenCacheWith:[[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]]; [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; @@ -197,6 +198,30 @@ - (void)testDidFinishLaunchingSetsCurrentAccessTokenWithoutCache OCMVerify(ClassMethod([self.accessTokenClassMock setCurrentAccessToken:nil])); } +- (void)testDidFinishLaunchingSetsCurrentAuthenticationTokenWithCache +{ + FBSDKAuthenticationToken *expected = SampleAuthenticationToken.validToken; + FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil + authenticationToken:expected]; + [self stubTokenCacheWith:cache]; + + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + // Should set the current authentication token to the cached access token when it exists + OCMVerify(ClassMethod([self.authenticationTokenClassMock setCurrentAuthenticationToken:expected])); +} + +- (void)testDidFinishLaunchingSetsCurrentAuthenticationTokenWithoutCache +{ + FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]; + [self stubTokenCacheWith:cache]; + + [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; + + // Should set the current authentication token to nil access token when there isn't a cached token + OCMVerify(ClassMethod([self.authenticationTokenClassMock setCurrentAuthenticationToken:nil])); +} + - (void)testDidFinishLaunchingLoadsServerConfiguration { [_delegate application:UIApplication.sharedApplication didFinishLaunchingWithOptions:nil]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m similarity index 79% rename from FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m rename to FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m index 60555dd299..6d51869baf 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m @@ -21,8 +21,10 @@ #import -#import "FBSDKAuthenticationToken.h" #import "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" +#import "FBSDKTestCoder.h" static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; @@ -57,12 +59,13 @@ - (NSDictionary *)claims; @end -@interface FBSDKAuthenticationTokenTests : XCTestCase +@interface FBSDKAuthenticationTokenTests : FBSDKTestCase @end @implementation FBSDKAuthenticationTokenTests { + FBSDKAuthenticationToken *_token; NSDictionary *_claims; NSDictionary *_header; } @@ -70,7 +73,8 @@ @implementation FBSDKAuthenticationTokenTests - (void)setUp { [super setUp]; - [FBSDKSettings setAppID:_mockAppID]; + + [self stubAppID:_mockAppID]; long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; _claims = @{ @@ -91,6 +95,66 @@ - (void)setUp }; } +- (void)testRetrievingCurrentToken +{ + FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" signature:@"" claims:@{} header:@{}]; + id partialTokenMock = OCMPartialMock(_token); + OCMStub([partialTokenMock tokenCache]).andReturn(cache); + + FBSDKAuthenticationToken.currentAuthenticationToken = _token; + XCTAssertEqualObjects( + cache.authenticationToken, + _token, + "Setting the global authentication token should invoke the cache" + ); + + [partialTokenMock stopMocking]; + partialTokenMock = nil; +} + +- (void)testEncoding +{ + NSString *expectedTokenString = @"expectedTokenString"; + NSString *expectedNonce = @"expectedNonce"; + + FBSDKTestCoder *coder = [FBSDKTestCoder new]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:expectedTokenString + nonce:expectedNonce + signature:@"" + claims:@{} + header:@{}]; + [_token encodeWithCoder:coder]; + + XCTAssertEqualObjects( + coder.encodedObject[@"FBSDKAuthenticationTokenTokenStringCodingKey"], + expectedTokenString, + @"Should encode the expected token string" + ); + XCTAssertEqualObjects( + coder.encodedObject[@"FBSDKAuthenticationTokenNonceCodingKey"], + expectedNonce, + @"Should encode the expected nonce string" + ); +} + +- (void)testDecodingEntryWithMethodName +{ + FBSDKTestCoder *coder = [FBSDKTestCoder new]; + _token = [[FBSDKAuthenticationToken alloc] initWithCoder:coder]; + + XCTAssertEqualObjects( + coder.decodedObject[@"FBSDKAuthenticationTokenTokenStringCodingKey"], + [NSString class], + @"Initializing from a decoder should attempt to decode a String for the token string key" + ); + XCTAssertEqualObjects( + coder.decodedObject[@"FBSDKAuthenticationTokenNonceCodingKey"], + [NSString class], + @"Initializing from a decoder should attempt to decode a String for the nonce key" + ); +} + - (void)testDecodeValidClaimsShouldSucceed { NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; @@ -163,8 +227,8 @@ - (void)testDecodeRandomClaims - (void)testCreateWithInvalidFormatTokenShouldFail { - FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token" nonce:@"123456789"]; - XCTAssertNil(token); + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token" nonce:@"123456789"]; + XCTAssertNil(_token); } - (void)testDecodeValidHeaderShouldSucceed @@ -216,39 +280,39 @@ - (void)testDecodeRandomHeader - (void)testVerifyValidSignatureShouldSucceed { - FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; - [token setCertificate:_certificate]; + _token = [FBSDKAuthenticationToken emptyInstance]; + [_token setCertificate:_certificate]; XCTAssertTrue( - [token verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] + [_token verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims] ); } - (void)testVerifyInvalidSignatureShouldFail { - FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; - [token setCertificate:_certificate]; + _token = [FBSDKAuthenticationToken emptyInstance]; + [_token setCertificate:_certificate]; NSString *invalidSignature = @"hH0uCpIx0BhjT_djfI52wPMp0sYuHAHYOes4GVasXykHsZAeuidFYshiCd8O-KpAo5m9jZWbXdaSN0JMbpBIJ9TwSk6e8bhX-N6BRKl3EZRby6SsZtK9J2X6mWomgMCfJZD54McLIdDQaTTtNsV1kgzm8iksywaT3f1GdicqlJPZn3m83xF3toSdfKdPoJJCpM7IidPru7gF8aZchkE1d-dUzZ9mV0CPfsl5lX4M64f470nm6PzyynAvyKwUBKO3v3x08V17NV8OkRAjtGPRhbs_d4B6ifEXS3piWUlxVm6w27nPbdmKeCqjV-WRfIJ6lOvumR2F26I1soEwtEWq9g"; XCTAssertFalse( - [token verifySignature:invalidSignature - header:_encodedHeader - claims:_encodedClaims] + [_token verifySignature:invalidSignature + header:_encodedHeader + claims:_encodedClaims] ); } - (void)testVerifySignatureWithInvalidCertificateShouldFail { - FBSDKAuthenticationToken *token = [FBSDKAuthenticationToken emptyInstance]; - [token setCertificate:@"invalid_certification"]; + _token = [FBSDKAuthenticationToken emptyInstance]; + [_token setCertificate:@"invalid_certification"]; XCTAssertFalse( - [token verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] + [_token verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims] ); } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index ce0801b902..9c7400ce56 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -43,3 +43,11 @@ secondaryColor:(UIColor *)secondaryColor scale:(CGFloat)scale; @end + +@interface FBSDKAuthenticationToken (Testing) +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + signature:(NSString *)signature + claims:(NSDictionary *)claims + header:(NSDictionary *)header; +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 2862e21d94..5634ea8327 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -29,7 +29,7 @@ #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" -@class FakeAccessTokenCache; +@class FakeTokenCache; NS_ASSUME_NONNULL_BEGIN @@ -56,6 +56,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing an `FBSDKAccessToken` class mock between tests @property (nullable, assign) id accessTokenClassMock; +/// Used for sharing an `FBSDKAuthenticationToken` class mock between tests +@property (nullable, assign) id authenticationTokenClassMock; + /// Used for sharing a common app identifier between tests. This is not a valid FB App ID @property (nullable, assign) NSString *appID; @@ -194,8 +197,8 @@ Also, to get a better understanding of mocking, please read the documentation at /// Prevents logging on changes to Settings properties - (void)stubLoggingIfUserSettingsChanged; -/// Stubs `FBSDKSettings.accessTokenCache` -- (void)stubAccessTokenCacheWith:(FakeAccessTokenCache *)cache; +/// Stubs `FBSDKSettings.tokenCache` +- (void)stubTokenCacheWith:(FakeTokenCache *)cache; /// Stubs `FBSDKProfile.fetchCachedProfile` - (void)stubCachedProfileWith:(FBSDKProfile *__nullable)profile; @@ -221,6 +224,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKAccessToken.currentAccessToken` with the provided token - (void)stubCurrentAccessTokenWith:(nullable FBSDKAccessToken *)token; +/// Stubs `FBSDKAuthenticationToken.currentAuthenticationToken` with the provided token +- (void)stubCurrentAuthenticationTokenWith:(nullable FBSDKAuthenticationToken *)token; + /// Stubs `FBSDKSettings.clientToken` with the provided token string - (void)stubClientTokenWith:(nullable NSString *)token; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 4d9d83609d..faf8ebb855 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -91,6 +91,7 @@ - (void)setUp [self setUpFeatureManagerMock]; [self setUpNSUserDefaultsMock]; [self setUpAccessTokenMock]; + [self setUpAuthenticationTokenClassMock]; [self setUpProfileMock]; [self setUpSKAdNetworkMock]; [self setUpNSNotificationCenterMock]; @@ -151,6 +152,9 @@ - (void)tearDown [_accessTokenClassMock stopMocking]; _accessTokenClassMock = nil; + [_authenticationTokenClassMock stopMocking]; + _authenticationTokenClassMock = nil; + [_profileClassMock stopMocking]; _profileClassMock = nil; @@ -269,6 +273,11 @@ - (void)setUpAccessTokenMock self.accessTokenClassMock = OCMStrictClassMock(FBSDKAccessToken.class); } +- (void)setUpAuthenticationTokenClassMock +{ + self.authenticationTokenClassMock = OCMStrictClassMock(FBSDKAuthenticationToken.class); +} + - (void)setUpProfileMock { self.profileClassMock = OCMStrictClassMock(FBSDKProfile.class); @@ -432,9 +441,9 @@ - (void)stubLoggingIfUserSettingsChanged OCMStub(ClassMethod([_settingsClassMock _logIfSDKSettingsChanged])); } -- (void)stubAccessTokenCacheWith:(FakeAccessTokenCache *)cache +- (void)stubTokenCacheWith:(FakeTokenCache *)cache { - OCMStub(ClassMethod([_settingsClassMock accessTokenCache])).andReturn(cache); + OCMStub(ClassMethod([_settingsClassMock tokenCache])).andReturn(cache); } - (void)stubIsAutoInitEnabled:(BOOL)isEnabled @@ -487,6 +496,11 @@ - (void)stubCurrentAccessTokenWith:(FBSDKAccessToken *)token OCMStub(ClassMethod([_accessTokenClassMock currentAccessToken])).andReturn(token); } +- (void)stubCurrentAuthenticationTokenWith:(FBSDKAuthenticationToken *)token +{ + OCMStub(ClassMethod([_authenticationTokenClassMock currentAuthenticationToken])).andReturn(token); +} + - (void)stubGraphAPIVersionWith:(NSString *)version { OCMStub(ClassMethod([_settingsClassMock graphAPIVersion])).andReturn(version); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeTokenCache.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeTokenCache.swift new file mode 100644 index 0000000000..9171ffcdd4 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeTokenCache.swift @@ -0,0 +1,33 @@ +// 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 FBSDKCoreKit + +@objcMembers +public class FakeTokenCache: NSObject, TokenCaching { + public var accessToken: AccessToken? + public var authenticationToken: AuthenticationToken? + + public init( + accessToken: AccessToken?, + authenticationToken: AuthenticationToken? + ) { + self.accessToken = accessToken + self.authenticationToken = authenticationToken + } +} diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift similarity index 80% rename from FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.swift rename to FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift index f168912843..49b354412d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeAccessTokenCache.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift @@ -16,17 +16,17 @@ // 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 FBSDKCoreKit - @objcMembers -public class FakeAccessTokenCache: NSObject, AccessTokenCaching { - public var accessToken: AccessToken? +public class SampleAuthenticationToken: NSObject { - public init(token: AccessToken?) { - accessToken = token + public static var validToken: AuthenticationToken { + return AuthenticationToken( + tokenString: "fakeTokenString", + nonce: "fakeNonce", + signature: "fakeSignature", + claims: [:], + header: [:] + ) } - public func clearCache() { - // noop for now - } } diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 687163eb3f..591818b872 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -135,11 +135,6 @@ C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; - C66FC2A72553748C00A7909C /* FBSDKAuthenticationTokenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC29D2553748C00A7909C /* FBSDKAuthenticationTokenTests.m */; }; - C66FC2FE255376D200A7909C /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C66FC2FF255376D200A7909C /* FBSDKAuthenticationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */; }; - C66FC338255377BF00A7909C /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; - C66FC340255377F400A7909C /* FBSDKAuthenticationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -173,8 +168,6 @@ F4EC46052575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */; }; F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */; }; - F4EC48462576C64600D2F47B /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F4EC48572576C64700D2F47B /* FBSDKAuthenticationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4EC48662576C6B200D2F47B /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4EC486E2576C6B300D2F47B /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4ECC67923EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */ = {isa = PBXBuildFile; fileRef = F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -391,9 +384,6 @@ 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; - C66FC29D2553748C00A7909C /* FBSDKAuthenticationTokenTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenTests.m; sourceTree = ""; }; - C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationToken.h; sourceTree = ""; }; - C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationToken.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -414,7 +404,6 @@ F4AA32812574448C005EDF04 /* LoginConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginConfiguration.swift; sourceTree = ""; }; F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKNonceUtility.h; sourceTree = ""; }; F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKNonceUtility.m; sourceTree = ""; }; - F4EC48252576C04000D2F47B /* FBSDKAuthenticationToken+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKAuthenticationToken+Internal.h"; sourceTree = ""; }; F4ECC66F23EE2094005DBF05 /* FBSDKCoreKitImport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKCoreKitImport.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -571,7 +560,6 @@ 9D03E8271A72DCA700207493 /* Internal */ = { isa = PBXGroup; children = ( - F4EC48252576C04000D2F47B /* FBSDKAuthenticationToken+Internal.h */, C6CE2BC124EB732C00CF2EB6 /* FBSDKReferralManager+Internal.h */, 0B9DBEFD207C04FF00662776 /* FBSDKDeviceLoginCodeInfo+Internal.h */, 0B9DBEF7207C04FF00662776 /* FBSDKDeviceLoginManagerResult+Internal.h */, @@ -626,8 +614,6 @@ 9D9DB8DB1A114E500086167B /* FBSDKLoginKit */ = { isa = PBXGroup; children = ( - C66FC2FC255376D100A7909C /* FBSDKAuthenticationToken.h */, - C66FC2FD255376D100A7909C /* FBSDKAuthenticationToken.m */, C681486124F866EA004EED1A /* FBSDKReferralCode.h */, C681486B24F866EA004EED1A /* FBSDKReferralCode.m */, C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */, @@ -674,7 +660,6 @@ 9D9DB8E81A114E500086167B /* FBSDKLoginKitTests */ = { isa = PBXGroup; children = ( - C66FC29D2553748C00A7909C /* FBSDKAuthenticationTokenTests.m */, C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */, 6B6276321A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.h */, 6B6276331A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m */, @@ -716,7 +701,6 @@ 0B9DBF7B207C201F00662776 /* FBSDKLoginConstants.h in Headers */, 0B9DBF38207C061D00662776 /* FBSDKDeviceLoginCodeInfo.h in Headers */, 0B9DBF3A207C061D00662776 /* FBSDKDeviceLoginManager.h in Headers */, - F4EC48462576C64600D2F47B /* FBSDKAuthenticationToken.h in Headers */, 0B9DBF3B207C061D00662776 /* FBSDKDeviceLoginManagerResult.h in Headers */, F4ECC67B23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, F4EC48662576C6B200D2F47B /* FBSDKLoginConfiguration.h in Headers */, @@ -735,7 +719,6 @@ 0B9DBF78207C200500662776 /* FBSDKLoginConstants.h in Headers */, 0B9DBF48207C07C600662776 /* FBSDKDeviceLoginCodeInfo.h in Headers */, 0B9DBF4A207C07C600662776 /* FBSDKDeviceLoginManager.h in Headers */, - F4EC48572576C64700D2F47B /* FBSDKAuthenticationToken.h in Headers */, 0B9DBF4B207C07C600662776 /* FBSDKDeviceLoginManagerResult.h in Headers */, F4ECC67C23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, F4EC486E2576C6B300D2F47B /* FBSDKLoginConfiguration.h in Headers */, @@ -756,7 +739,6 @@ 0B9DBF0F207C051800662776 /* FBSDKDeviceLoginManager.h in Headers */, 818EB4321D1A283100252851 /* _FBSDKLoginRecoveryAttempter.h in Headers */, C6CE2BC324EB73B500CF2EB6 /* FBSDKReferralManager.h in Headers */, - C66FC338255377BF00A7909C /* FBSDKAuthenticationToken.h in Headers */, C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */, 818EB4331D1A283100252851 /* FBSDKCoreKit+Internal.h in Headers */, 818EB4341D1A283100252851 /* FBSDKLoginConstants.h in Headers */, @@ -789,7 +771,6 @@ C6CE2BBF24EB72F200CF2EB6 /* FBSDKReferralManager.h in Headers */, 9DBC4C3C1A782E2000816FE8 /* FBSDKCoreKit+Internal.h in Headers */, 9D03E8341A72DF5800207493 /* FBSDKLoginConstants.h in Headers */, - C66FC2FE255376D200A7909C /* FBSDKAuthenticationToken.h in Headers */, 9D9DB8DF1A114E500086167B /* FBSDKLoginKit.h in Headers */, F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */, 9D03E8251A72D89100207493 /* FBSDKLoginManagerLoginResult.h in Headers */, @@ -1151,7 +1132,6 @@ F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C625B49C24F97DF0003DCE23 /* FBSDKReferralManagerLogger.m in Sources */, F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */, - C66FC340255377F400A7909C /* FBSDKAuthenticationToken.m in Sources */, 818EB42A1D1A283100252851 /* FBSDKLoginManagerLoginResult.m in Sources */, C681486F24F86806004EED1A /* FBSDKReferralCode.m in Sources */, 818EB42B1D1A283100252851 /* FBSDKLoginTooltipView.m in Sources */, @@ -1182,7 +1162,6 @@ F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */, F46FA65A245347580060C902 /* FBLoginButton.swift in Sources */, - C66FC2FF255376D200A7909C /* FBSDKAuthenticationToken.m in Sources */, 9D03E8261A72D89100207493 /* FBSDKLoginManagerLoginResult.m in Sources */, C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */, 9DBA6A2A1A80252F00B4DE6A /* FBSDKLoginTooltipView.m in Sources */, @@ -1206,7 +1185,6 @@ F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */, 9D641F841A7B69160048F563 /* FBSDKLoginManagerTests.m in Sources */, F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, - C66FC2A72553748C00A7909C /* FBSDKAuthenticationTokenTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h index becc869dbf..f27581ebba 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h @@ -18,16 +18,15 @@ #import -#import "FBSDKAuthenticationToken.h" #import "FBSDKCoreKitImport.h" #import "FBSDKDeviceLoginCodeInfo.h" #import "FBSDKDeviceLoginManager.h" #import "FBSDKDeviceLoginManagerResult.h" +#import "FBSDKLoginConfiguration.h" #import "FBSDKLoginConstants.h" #if !TARGET_OS_TV #import "FBSDKLoginButton.h" - #import "FBSDKLoginConfiguration.h" #import "FBSDKLoginManager.h" #import "FBSDKLoginManagerLoginResult.h" #import "FBSDKLoginTooltipView.h" diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 7b3fa33e3f..7e5cf45eaf 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -117,6 +117,7 @@ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FB - (void)logOut { [FBSDKAccessToken setCurrentAccessToken:nil]; + [FBSDKAuthenticationToken setCurrentAuthenticationToken:nil]; [FBSDKProfile setCurrentProfile:nil]; } diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index c0d711b7fd..d1f98c56d3 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -28,13 +28,17 @@ #import #endif - #import "FBSDKAuthenticationToken.h" - #import "FBSDKAuthenticationToken+Internal.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginUtility.h" +@interface FBSDKAuthenticationToken (ClaimsProviding) + +- (NSDictionary *)claims; + +@end + static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *parameters, void (^completionBlock)(void)) { __block NSUInteger pendingCount = 1; @@ -144,6 +148,7 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters if (token) { FBSDKProfile.currentProfile = [FBSDKLoginURLCompleter createProfileWithToken:token]; + [FBSDKAuthenticationToken setCurrentAuthenticationToken:token]; } } else { [self setErrorWithDictionary:parameters]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index ae2dec4e6e..2510fc3c94 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -22,7 +22,6 @@ #import -#import "FBSDKAuthenticationToken.h" #import "FBSDKLoginManager.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLoginResult.h" @@ -321,15 +320,16 @@ - (void)testOpenURLAuthWithIDToken NSData *expectedHeaderData = [FBSDKTypeUtility dataWithJSONObject:expectedHeader options:0 error:nil]; NSString *encodedHeader = [FBSDKBase64 encodeData:expectedHeaderData]; - NSString *fragment = [NSString stringWithFormat:@"id_token=%@.%@.%@", encodedHeader, encodedClaims, @"signature"]; - NSURL *url = [self authorizeURLWithFragment:fragment challenge:kFakeChallenge]; + NSString *tokenString = [NSString stringWithFormat:@"%@.%@.%@", encodedHeader, encodedClaims, @"signature"]; + NSURL *url = [self authorizeURLWithFragment:[NSString stringWithFormat:@"id_token=%@", tokenString] challenge:kFakeChallenge]; - __block FBSDKProfile *tokenAfterAuth; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { // TODO: Verify that the expected profile is set. // XCTAssertFalse(result.isCancelled); - tokenAfterAuth = [FBSDKProfile currentProfile]; - // XCTAssertEqualObjects(tokenAfterAuth, result.token); + FBSDKAuthenticationToken *authToken = FBSDKAuthenticationToken.currentAuthenticationToken; + XCTAssertNotNil(authToken); + XCTAssertEqualObjects(authToken.tokenString, tokenString); + XCTAssertEqualObjects(authToken.nonce, kFakeNonce); [expectation fulfill]; }]; @@ -492,4 +492,18 @@ - (void)testLogInWithURLFailWithNoLoginData }]; } +- (void)testLogout +{ + id accessTokenClassMock = OCMClassMock(FBSDKAccessToken.class); + id authenticationTokenClassMock = OCMClassMock(FBSDKAuthenticationToken.class); + id profileClassMock = OCMClassMock(FBSDKProfile.class); + + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + [loginManager logOut]; + + OCMVerify(ClassMethod([accessTokenClassMock setCurrentAccessToken:nil])); + OCMVerify(ClassMethod([authenticationTokenClassMock setCurrentAuthenticationToken:nil])); + OCMVerify(ClassMethod([profileClassMock setCurrentProfile:nil])); +} + @end From 4054b833b80ffcf6f3eea8ed282bed970bac44b5 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 2 Dec 2020 15:01:30 -0800 Subject: [PATCH 145/227] update login request to support OIDC & configurable login Summary: Update login request to support OIDC and the new configurable login API. Reviewed By: joesus Differential Revision: D25237613 fbshipit-source-id: aede56de91b75d5e716b2fbabad518b535208469 --- .../FBSDKLoginKit/FBSDKLoginManager.m | 36 +++++++++--- .../Internal/FBSDKLoginManager+Internal.h | 3 +- .../FBSDKLoginManagerTests.m | 58 ++++++++++++++++--- 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 7e5cf45eaf..b8498752fd 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -46,7 +46,7 @@ static int const FBClientStateChallengeLength = 20; static NSString *const FBSDKExpectedChallengeKey = @"expected_login_challenge"; -static NSString *const FBSDKOIDCExpectedNonceKey = @"expected_login_nonce"; +static NSString *const FBSDKExpectedNonceKey = @"expected_login_nonce"; static NSString *const FBSDKOauthPath = @"/dialog/oauth"; static NSString *const SFVCCanceledLogin = @"com.apple.SafariServices.Authentication"; static NSString *const ASCanceledLogin = @"com.apple.AuthenticationServices.WebAuthenticationSession"; @@ -61,6 +61,7 @@ @implementation FBSDKLoginManager FBSDKLoginManagerLogger *_logger; FBSDKLoginManagerState _state; FBSDKKeychainStore *_keychainStore; + FBSDKLoginConfiguration *_configuration; BOOL _usedSFAuthSession; } @@ -91,6 +92,8 @@ - (void)logInFromViewController:(UIViewController *)viewController return; } self.fromViewController = viewController; + _configuration = configuration; + [self logInWithPermissions:configuration.requestedPermissions handler:completion]; } @@ -327,16 +330,16 @@ - (NSString *)loadExpectedChallenge - (NSString *)loadExpectedNonce { - return [_keychainStore stringForKey:FBSDKOIDCExpectedNonceKey]; + return [_keychainStore stringForKey:FBSDKExpectedNonceKey]; } -- (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration +- (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)configuration + serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration { [FBSDKInternalUtility validateURLSchemes]; NSMutableDictionary *loginParams = [NSMutableDictionary dictionary]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings appID] forKey:@"client_id"]; - [FBSDKTypeUtility dictionary:loginParams setObject:@"token_or_nonce,signed_request,graph_domain" forKey:@"response_type"]; [FBSDKTypeUtility dictionary:loginParams setObject:@"fbconnect://success" forKey:@"redirect_uri"]; [FBSDKTypeUtility dictionary:loginParams setObject:@"touch" forKey:@"display"]; [FBSDKTypeUtility dictionary:loginParams setObject:@"ios" forKey:@"sdk"]; @@ -348,17 +351,28 @@ - (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConf long long cbtInMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); [FBSDKTypeUtility dictionary:loginParams setObject:@(cbtInMilliseconds) forKey:@"cbt"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0 forKey:@"ies"]; - [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings appURLSchemeSuffix] forKey:@"local_client_id"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKLoginUtility stringForAudience:self.defaultAudience] forKey:@"default_audience"]; + + NSSet *permissions = [configuration.requestedPermissions setByAddingObject:@"openid"]; [FBSDKTypeUtility dictionary:loginParams setObject:[permissions.allObjects componentsJoinedByString:@","] forKey:@"scope"]; NSString *expectedChallenge = [FBSDKLoginManager stringForChallenge]; NSDictionary *state = @{@"challenge" : [FBSDKUtility URLEncode:expectedChallenge]}; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKBasicUtility JSONStringForObject:state error:NULL invalidObjectHandler:nil] forKey:@"state"]; - [self storeExpectedChallenge:expectedChallenge]; + NSString *responseType; + if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { + responseType = @"id_token"; + } else { + responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; + } + [FBSDKTypeUtility dictionary:loginParams setObject:responseType forKey:@"response_type"]; + + [FBSDKTypeUtility dictionary:loginParams setObject:configuration.nonce forKey:@"nonce"]; + [self storeExpectedNonce:configuration.nonce keychainStore:_keychainStore]; + return loginParams; } @@ -419,6 +433,7 @@ - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler _handler = [handler copy]; // Don't need to pass permissions for data reauthorization. _requestedPermissions = [NSSet set]; + _configuration = [FBSDKLoginConfiguration init]; self.authType = FBSDKLoginAuthTypeReauthorize; [_logger startSessionForLoginManager:self]; [self logIn]; @@ -427,7 +442,7 @@ - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler - (void)logIn { FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; - NSDictionary *loginParams = [self logInParametersWithPermissions:_requestedPermissions serverConfiguration:serverConfiguration]; + NSDictionary *loginParams = [self logInParametersWithConfiguration:_configuration serverConfiguration:serverConfiguration]; self->_usedSFAuthSession = NO; void (^completion)(BOOL, NSError *) = ^void (BOOL didPerformLogIn, NSError *error) { @@ -457,6 +472,13 @@ - (void)storeExpectedChallenge:(NSString *)challengeExpected accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; } +- (void)storeExpectedNonce:(NSString *)nonceExpected keychainStore:(FBSDKKeychainStore *)keychainStore +{ + [keychainStore setString:nonceExpected + forKey:FBSDKExpectedNonceKey + accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; +} + + (NSString *)stringForChallenge { NSString *challenge = [FBSDKCrypto randomString:FBClientStateChallengeLength]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h index d24c9b03e6..96a8b2911a 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h @@ -69,7 +69,8 @@ typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { - (void)logIn; // made available for testing only -- (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration; +- (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)configuration + serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration; // made available for testing only - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 2510fc3c94..a7feebbea6 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -39,6 +39,8 @@ - (NSDictionary *)logInParametersFromURL:(NSURL *)url; - (NSString *)loadExpectedNonce; +- (void)storeExpectedNonce:(NSString *)nonceExpected keychainStore:(FBSDKKeychainStore *)keychainStore; + @end @interface FBSDKAuthenticationToken (Testing) @@ -60,6 +62,7 @@ - (void)setUp { _mockNSBundle = [FBSDKLoginUtilityTests mainBundleMock]; [FBSDKSettings setAppID:kFakeAppID]; + [FBSDKAuthenticationToken setCurrentAuthenticationToken:nil]; } - (NSURL *)authorizeURLWithParameters:(NSString *)parameters joinedBy:(NSString *)joinChar @@ -296,7 +299,6 @@ - (void)testOpenURLWithNoChallengeAndError - (void)testOpenURLAuthWithIDToken { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; - [FBSDKAccessToken setCurrentAccessToken:nil]; FBSDKLoginManager *target = [self loginManagerExpectingChallengeAndNonce]; [FBSDKAuthenticationToken setSkipSignatureVerification:YES]; @@ -327,9 +329,9 @@ - (void)testOpenURLAuthWithIDToken // TODO: Verify that the expected profile is set. // XCTAssertFalse(result.isCancelled); FBSDKAuthenticationToken *authToken = FBSDKAuthenticationToken.currentAuthenticationToken; - XCTAssertNotNil(authToken); - XCTAssertEqualObjects(authToken.tokenString, tokenString); - XCTAssertEqualObjects(authToken.nonce, kFakeNonce); + XCTAssertNotNil(authToken, @"An Authentication token should be created after successful login"); + XCTAssertEqualObjects(authToken.tokenString, tokenString, @"A raw authentication token string should be stored"); + XCTAssertEqualObjects(authToken.nonce, kFakeNonce, @"The nonce claims in the authentication token should be stored"); [expectation fulfill]; }]; @@ -415,19 +417,21 @@ - (void)testCallingLoginWhileAnotherLoginHasNotFinishedNoOps XCTAssertEqual(loginCount, 1); } -- (void)testLoginParams +- (void)testBetaLoginExperienceEnabledLoginParams { id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { // Nothing }] validateURLSchemes]; - FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; - NSDictionary *params = [loginManager logInParametersWithPermissions:[NSSet setWithArray:@[@"public_profile", @"email"]] serverConfiguration:nil]; + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"] betaLoginExperience:FBSDKBetaLoginExperienceEnabled]; + + NSDictionary *params = [loginManager logInParametersWithConfiguration:config serverConfiguration:nil]; long long cbt = [params[@"cbt"] longLongValue]; long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); - XCTAssertEqualObjects(params[@"response_type"], @"token_or_nonce,signed_request,graph_domain"); + XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); XCTAssertEqualObjects(params[@"display"], @"touch"); XCTAssertEqualObjects(params[@"sdk"], @"ios"); @@ -435,6 +439,34 @@ - (void)testLoginParams XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); XCTAssertEqualObjects(params[@"fbapp_pres"], @0); XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + XCTAssertNotNil(params[@"nonce"]); +} + +- (void)testBetaLoginExperienceRestrictedLoginParams +{ + id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; + [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { + // Nothing + }] validateURLSchemes]; + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"] betaLoginExperience:FBSDKBetaLoginExperienceRestricted nonce:@"some_nonce"]; + + NSDictionary *params = [loginManager logInParametersWithConfiguration:config serverConfiguration:nil]; + long long cbt = [params[@"cbt"] longLongValue]; + long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); + XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); + XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); + XCTAssertEqualObjects(params[@"response_type"], @"id_token"); + XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); + XCTAssertEqualObjects(params[@"display"], @"touch"); + XCTAssertEqualObjects(params[@"sdk"], @"ios"); + XCTAssertEqualObjects(params[@"return_scopes"], @"true"); + XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); + XCTAssertEqualObjects(params[@"fbapp_pres"], @0); + XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); } - (void)testlogInParametersFromURL @@ -506,4 +538,14 @@ - (void)testLogout OCMVerify(ClassMethod([profileClassMock setCurrentProfile:nil])); } +- (void)testStoreExpectedNonce +{ + FBSDKKeychainStore *keychainStore = [[FBSDKKeychainStore alloc] initWithService:self.name accessGroup:nil]; + FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; + + [loginManager storeExpectedNonce:@"some_nonce" keychainStore:keychainStore]; + + XCTAssertEqualObjects([keychainStore stringForKey:@"expected_login_nonce"], @"some_nonce"); +} + @end From e92ce6df2f28895b6ea53b2876dc88ace2b8079d Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 2 Dec 2020 15:01:30 -0800 Subject: [PATCH 146/227] Fix Login button for configurable login Summary: Update login button to make sure configurable login works end to end: 1) Remove call to classic login 2) provide default nonce when a nonce is not supplied for login button Reviewed By: joesus Differential Revision: D25255239 fbshipit-source-id: 21450d8d9b774d75fdab484688f25112b96ae93b --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index e02d436b54..3cb522a4ab 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -289,16 +289,18 @@ - (void)_buttonPressed:(id)sender } }; - FBSDKLoginConfiguration *loginConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions - betaLoginExperience:self.betaLoginExperience - nonce:self.nonce]; + FBSDKLoginConfiguration *loginConfig; + if (self.nonce) { + loginConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions + betaLoginExperience:self.betaLoginExperience + nonce:self.nonce]; + } else { + loginConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions + betaLoginExperience:self.betaLoginExperience]; + } [_loginManager logInFromViewController:[FBSDKInternalUtility viewControllerForView:self] configuration:loginConfig completion:handler]; - - [_loginManager logInWithPermissions:self.permissions - fromViewController:[FBSDKInternalUtility viewControllerForView:self] - handler:handler]; } } From 7186a37c15b1a3cb97e69a8d8cd67093c26083e4 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 2 Dec 2020 15:01:30 -0800 Subject: [PATCH 147/227] Construct profile from ID token Summary: When using OIDC login, the returned JWT ID token could contain user claims concluding userID, name, profile picture and email. We need to find a way to save those data so that they are accessible to developers. The last diff added email and image field to `FBSDKProfile`, this diff add changes to construct a `FBSDKProfile` instance when an ID token is successfully parsed. After this change, basic user data should be accessible by calling `[FBSDKProfile currentProfile]` Reviewed By: joesus Differential Revision: D24939251 fbshipit-source-id: 005e764a431280d791fc85c34f6604bcba148561 --- .../FBSDKLoginKit/FBSDKLoginButton.h | 2 +- .../FBSDKLoginKit/FBSDKLoginButton.m | 2 +- .../Internal/FBSDKLoginCompletion.m | 20 +++++++++++++++++-- .../FBSDKLoginManagerTests.m | 10 ++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h index 6846fa6f8c..db0fb16331 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h @@ -58,7 +58,7 @@ typedef NS_ENUM(NSUInteger, FBSDKLoginButtonTooltipBehavior) /** A button that initiates a log in or log out flow upon tapping. - `FBSDKLoginButton` works with `[FBSDKAccessToken currentAccessToken]` to + `FBSDKLoginButton` works with `FBSDKProfile.currentProfile` to determine what to display, and automatically starts authentication when tapped (i.e., you do not need to manually subscribe action targets). diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index 3cb522a4ab..2085f36c04 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -216,7 +216,7 @@ - (void)_accessTokenDidChangeNotification:(NSNotification *)notification - (void)_buttonPressed:(id)sender { [self logTapEventWithEventName:FBSDKAppEventNameFBSDKLoginButtonDidTap parameters:self.analyticsParameters]; - if (FBSDKAccessToken.isCurrentAccessTokenActive) { + if (FBSDKAccessToken.isCurrentAccessTokenActive || FBSDKProfile.currentProfile) { NSString *title = nil; if (_userName) { diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index d1f98c56d3..3c2aabbcf2 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -298,8 +298,24 @@ + (FBSDKProfile *)createProfileWithToken:(FBSDKAuthenticationToken *)token return nil; } - // TODO: populate profile from claims - return [FBSDKProfile currentProfile]; + NSDictionary *claims = token.claims; + if (![claims[@"sub"] isKindOfClass:NSString.class]) { + return nil; + } + + NSString *name = [claims[@"name"] isKindOfClass:NSString.class] ? claims[@"name"] : nil; + NSString *email = [claims[@"email"] isKindOfClass:NSString.class] ? claims[@"email"] : nil; + NSURL *imageURL = [claims[@"picture"] isKindOfClass:NSString.class] ? [NSURL URLWithString:claims[@"picture"]] : nil; + + return [[FBSDKProfile alloc]initWithUserID:claims[@"sub"] + firstName:nil + middleName:nil + lastName:nil + name:name + linkURL:nil + refreshDate:nil + imageURL:imageURL + email:email]; } @end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index a7feebbea6..5ff923ea80 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -60,9 +60,11 @@ @implementation FBSDKLoginManagerTests - (void)setUp { + [super setUp]; _mockNSBundle = [FBSDKLoginUtilityTests mainBundleMock]; [FBSDKSettings setAppID:kFakeAppID]; [FBSDKAuthenticationToken setCurrentAuthenticationToken:nil]; + [FBSDKProfile setCurrentProfile:nil]; } - (NSURL *)authorizeURLWithParameters:(NSString *)parameters joinedBy:(NSString *)joinChar @@ -328,10 +330,18 @@ - (void)testOpenURLAuthWithIDToken [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { // TODO: Verify that the expected profile is set. // XCTAssertFalse(result.isCancelled); + FBSDKAuthenticationToken *authToken = FBSDKAuthenticationToken.currentAuthenticationToken; XCTAssertNotNil(authToken, @"An Authentication token should be created after successful login"); XCTAssertEqualObjects(authToken.tokenString, tokenString, @"A raw authentication token string should be stored"); XCTAssertEqualObjects(authToken.nonce, kFakeNonce, @"The nonce claims in the authentication token should be stored"); + + FBSDKProfile *profile = [FBSDKProfile currentProfile]; + XCTAssertNotNil(profile, @"user profile should be updated"); + XCTAssertEqualObjects(profile.name, expectedClaims[@"name"], @"failed to parse user name"); + XCTAssertEqualObjects(profile.userID, expectedClaims[@"sub"], @"failed to parse userID"); + XCTAssertEqualObjects(profile.imageURL.absoluteString, expectedClaims[@"picture"], @"failed to parse user profile picture"); + [expectation fulfill]; }]; From 4db65dab59a0ee0e315d2da329ec56295bcf6c3d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 3 Dec 2020 09:47:39 -0800 Subject: [PATCH 148/227] Tweak Swift Interface Summary: The Swift typeahead should only show the method that works well with Swift. Previously the signature: `logIn(from:configuration:completion:)` was available for Swift but referred to the ObjC method which has a `(response, error)` completion type. This is not Swifty. We also provided them with the signature: `logIn(viewController:configuration:completion:)` which we want them to use because it has a `(result)` completion type which is very Swifty. This removes the first signature from typeahead and prevents it from being called without explicit `__`. This is a better experience. Reviewed By: ppansy Differential Revision: D25284727 fbshipit-source-id: 1524f5f14d8d6ec42839c00e933ee9f72fc527d9 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h | 4 ++-- .../FBSDKLoginKit/Swift/LoginConfiguration.swift | 3 ++- FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift | 10 +++++----- .../FBSDKLoginKitTests/LoginConfigurationTests.swift | 11 ++++++----- FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift | 1 - 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index 45b052791d..e1bbb3d183 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -55,7 +55,7 @@ NS_SWIFT_NAME(logIn(permissions:from:handler:)); - (void)logInFromViewController:(nullable UIViewController *)viewController configuration:(FBSDKLoginConfiguration *)configuration completion:(LoginManagerLoginResultBlock)completion -NS_SWIFT_NAME(logIn(from:configuration:completion:)); +NS_REFINED_FOR_SWIFT; @end @@ -174,7 +174,7 @@ NS_SWIFT_NAME(logIn(permissions:from:handler:)); - (void)logInFromViewController:(nullable UIViewController *)viewController configuration:(FBSDKLoginConfiguration *)configuration completion:(FBSDKLoginManagerLoginResultBlock)completion -NS_SWIFT_NAME(logIn(from:configuration:completion:)); +NS_REFINED_FOR_SWIFT; /** Logs the user in with the given deep link url. Will only log user in if the given url contains valid login data. diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift index d8601684b1..e7e0c52b6c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift @@ -27,7 +27,8 @@ public extension LoginConfiguration { The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. Defaults to an empty `Permission` array. - parameter beta: Determines whether the login attempt should use the beta experience. Defaults to `.enabled` - - parameter nonce: An optional nonce to use for the login attempt. A valid nonce must be an alphanumeric string without whitespace. + - parameter nonce: An optional nonce to use for the login attempt. + A valid nonce must be an alphanumeric string without whitespace. Creation of the configuration will fail if the nonce is invalid. Defaults to a `UUID` string. */ convenience init?( diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift index 5671af88df..d4fbe18804 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift @@ -125,11 +125,11 @@ public extension LoginManager { configuration: LoginConfiguration, completion: @escaping LoginResultBlock ) { - let _completion = { (result: LoginManagerLoginResult?, error: Error?) in + let legacyCompletion = { (result: LoginManagerLoginResult?, error: Error?) in let result = LoginResult(result: result, error: error) completion(result) } - self.logIn(from: viewController, configuration: configuration, completion: _completion) + self.__logIn(from: viewController, configuration: configuration, completion: legacyCompletion) } /** @@ -145,7 +145,7 @@ public extension LoginManager { You can only perform one login call at a time. Calling a login method before the completion handler is called on a previous login will result in an error. - + - parameter configuration the login configuration to use. - parameter completion: Optional callback. */ @@ -153,11 +153,11 @@ public extension LoginManager { configuration: LoginConfiguration, completion: @escaping LoginResultBlock ) { - let _completion = { (result: LoginManagerLoginResult?, error: Error?) in + let legacyCompletion = { (result: LoginManagerLoginResult?, error: Error?) in let result = LoginResult(result: result, error: error) completion(result) } - self.logIn(from: nil, configuration: configuration, completion: _completion) + self.__logIn(from: nil, configuration: configuration, completion: legacyCompletion) } private func sdkCompletion(_ completion: LoginResultBlock?) -> LoginManagerLoginResultBlock? { diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift index c94c158a57..ea970c0dfc 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift @@ -33,7 +33,7 @@ class LoginConfigurationTests: XCTestCase { XCTAssertEqual( config.betaLoginExperience, .enabled, - "Beta login experience should default to enabled when unspecified" + "Beta login experience should default to enabled when unspecified" ) XCTAssertNotNil( config.nonce, @@ -59,10 +59,11 @@ class LoginConfigurationTests: XCTestCase { } func testCreatingWithBetaLoginExperience() { - [ + let preferences = [ BetaLoginExperience.enabled, .restricted - ].forEach { preference in + ] + preferences.forEach { preference in let config = LoginConfiguration(betaLoginExperience: preference) XCTAssertEqual( config?.betaLoginExperience, @@ -93,7 +94,7 @@ class LoginConfigurationTests: XCTestCase { ) XCTAssertNil( configuration, - "Should not create a configuration with permissions that are disallowed based on the beta login experience preference" + "Should not create a configuration with permissions that are disallowed based on the beta login experience preference" // swiftlint:disable:this line_length ) configuration = LoginConfiguration( @@ -102,7 +103,7 @@ class LoginConfigurationTests: XCTestCase { ) XCTAssertNotNil( configuration, - "Should create a configuration with permissions that are allowed based on the beta login experience preference" + "Should create a configuration with permissions that are allowed based on the beta login experience preference" // swiftlint:disable:this line_length ) } } diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift index 7fc8b44535..39fa27897e 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift +++ b/FBSDKLoginKit/FBSDKLoginKitTests/NonceTests.swift @@ -45,5 +45,4 @@ class NonceTests: XCTestCase { } } - } From 14c098c8dd3503a37d7fdcdb0445c49499f5eec2 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 3 Dec 2020 15:40:14 -0800 Subject: [PATCH 149/227] Updating Readme for data disclosure discoverability Summary: $title Reviewed By: Mxiim Differential Revision: D25274858 fbshipit-source-id: fc3b58825979e920ebcc8af53e0ed6bb5842eddf --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 519dd94513..8e6c5f12ed 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,7 @@ Please take a moment and [subscribe to releases](https://docs.github.com/en/ente **Note for Swift Package Manager Users:** If you explicitly **DO NOT** want to include Swift, import `FBSDKCoreKit` `FBSDKLoginKit` and `FBSDKShareKit` - -For projects that include Swift, use `FacebookCore`, `FacebookLogin`, and `FacebookShare` +
For projects that include Swift, use `FacebookCore`, `FacebookLogin`, and `FacebookShare` ### CocoaPods @@ -41,6 +40,16 @@ For projects that include Swift, use `FacebookCore`, `FacebookLogin`, and `Faceb 3. Check-out the tutorials available online at: 4. Start coding! Visit for tutorials and reference documentation. +## iOS 14 CHANGES + +### Data Disclosure + +Due to the release of iOS 14, tracking events that your app collects and sends to Facebook may require you to disclosed these data types in the App Store Connect questionnaire. It is your responsibility to ensure this is reflected in your application’s privacy policy. Visit our blogpost for information on affected Facebook SDKs, APIs, and products and the Apple App Store Privacy Details article to learn more about the data types you will need to disclose. + +link to FB blogpost https://developers.facebook.com/blog/post/2020/10/22/preparing-for-apple-app-store-data-disclosure-requirements/ + +apple store details https://developer.apple.com/app-store/app-privacy-details/ + ## FEATURES - Login - From ad23c6857e2bfbe2731972bddd5babf38619da0d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 4 Dec 2020 14:16:38 -0800 Subject: [PATCH 150/227] Fix first party app login Summary: Fixing app login. Reviewed By: ppansy Differential Revision: D25343842 fbshipit-source-id: 1f7b7e0c6ebdba26992d08085032e89fcefd03e2 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 8 ++++++-- .../FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 12 +++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index b8498752fd..ec82d7eb4c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -354,7 +354,9 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings appURLSchemeSuffix] forKey:@"local_client_id"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKLoginUtility stringForAudience:self.defaultAudience] forKey:@"default_audience"]; - NSSet *permissions = [configuration.requestedPermissions setByAddingObject:@"openid"]; + // TODO: Re-implement when server issue resolved - T80884847 + // [configuration.requestedPermissions setByAddingObject:@"openid"]; + NSSet *permissions = configuration.requestedPermissions; [FBSDKTypeUtility dictionary:loginParams setObject:[permissions.allObjects componentsJoinedByString:@","] forKey:@"scope"]; NSString *expectedChallenge = [FBSDKLoginManager stringForChallenge]; @@ -366,7 +368,9 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { responseType = @"id_token"; } else { - responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; + // TODO: Re-implement when server issue resolved - T80884847 + // responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; + responseType = @"token_or_nonce,signed_request,graph_domain"; } [FBSDKTypeUtility dictionary:loginParams setObject:responseType forKey:@"response_type"]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 5ff923ea80..a241eff1a6 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -441,7 +441,9 @@ - (void)testBetaLoginExperienceEnabledLoginParams long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); - XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); + // TODO: Re-implement when server issue resolved - T80884847 + // XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); + XCTAssertEqualObjects(params[@"response_type"], @"token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); XCTAssertEqualObjects(params[@"display"], @"touch"); XCTAssertEqualObjects(params[@"sdk"], @"ios"); @@ -449,7 +451,9 @@ - (void)testBetaLoginExperienceEnabledLoginParams XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); XCTAssertEqualObjects(params[@"fbapp_pres"], @0); XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); - XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + // TODO: Re-implement when server issue resolved - T80884847 + // XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); XCTAssertNotNil(params[@"nonce"]); } @@ -475,7 +479,9 @@ - (void)testBetaLoginExperienceRestrictedLoginParams XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); XCTAssertEqualObjects(params[@"fbapp_pres"], @0); XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); - XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + // TODO: Re-implement when server issue resolved - T80884847 +// XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); } From 5ce58cc13820d39e2bb3b467d989982dd5156966 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 4 Dec 2020 16:28:38 -0800 Subject: [PATCH 151/227] Clean up FBSDKLoginManagerTests Summary: Some cleanups to FBSDKLoginManagerTests, including: - Extract common assertions into helper functions - Extract common mocks - Add mock tear downs Differential Revision: D25292636 fbshipit-source-id: 40568764c486d2165b1245e9bb6a3e770430540b --- .../FBSDKLoginManagerTests.m | 207 ++++++++---------- 1 file changed, 96 insertions(+), 111 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index a241eff1a6..48462f204b 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -56,6 +56,11 @@ @interface FBSDKLoginManagerTests : XCTestCase @implementation FBSDKLoginManagerTests { id _mockNSBundle; + id _mockInternalUtility; + id _mockLoginManager; + id _mockAccessTokenClass; + id _mockAuthenticationTokenClass; + id _mockProfileClass; } - (void)setUp @@ -65,6 +70,38 @@ - (void)setUp [FBSDKSettings setAppID:kFakeAppID]; [FBSDKAuthenticationToken setCurrentAuthenticationToken:nil]; [FBSDKProfile setCurrentProfile:nil]; + [FBSDKAccessToken setCurrentAccessToken:nil]; + + _mockInternalUtility = OCMClassMock(FBSDKInternalUtility.class); + OCMStub(ClassMethod([_mockInternalUtility validateURLSchemes])); + + _mockLoginManager = OCMPartialMock([FBSDKLoginManager new]); + OCMStub([_mockLoginManager loadExpectedChallenge]).andReturn(kFakeChallenge); + OCMStub([_mockLoginManager loadExpectedNonce]).andReturn(kFakeNonce); + + _mockAccessTokenClass = OCMClassMock(FBSDKAccessToken.class); + _mockAuthenticationTokenClass = OCMClassMock(FBSDKAuthenticationToken.class); + _mockProfileClass = OCMClassMock(FBSDKProfile.class); +} + +- (void)tearDown +{ + [super tearDown]; + + [_mockInternalUtility stopMocking]; + _mockInternalUtility = nil; + + [_mockLoginManager stopMocking]; + _mockLoginManager = nil; + + [_mockAccessTokenClass stopMocking]; + _mockAccessTokenClass = nil; + + [_mockAuthenticationTokenClass stopMocking]; + _mockAuthenticationTokenClass = nil; + + [_mockProfileClass stopMocking]; + _mockProfileClass = nil; } - (NSURL *)authorizeURLWithParameters:(NSString *)parameters joinedBy:(NSString *)joinChar @@ -88,34 +125,12 @@ - (NSURL *)authorizeURLWithFragment:(NSString *)fragment return [self authorizeURLWithFragment:fragment challenge:kFakeChallenge]; } -- (FBSDKLoginManager *)loginManagerExpectingChallenge -{ - FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; - id partialMock = (FBSDKLoginManager *)[OCMockObject partialMockForObject:loginManager]; - - [[[partialMock stub] andReturn:kFakeChallenge] loadExpectedChallenge]; - - return (FBSDKLoginManager *)partialMock; -} - -- (FBSDKLoginManager *)loginManagerExpectingChallengeAndNonce -{ - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; - id partialMock = [OCMockObject partialMockForObject:loginManager]; - - OCMStub([partialMock loadExpectedChallenge]).andReturn(kFakeChallenge); - OCMStub([partialMock loadExpectedNonce]).andReturn(kFakeNonce); - - return (FBSDKLoginManager *)partialMock; -} - // verify basic case of first login and getting granted and declined permissions (is not classified as cancelled) - (void)testOpenURLAuth { XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; - FBSDKLoginManager *target = [self loginManagerExpectingChallenge]; + FBSDKLoginManager *target = _mockLoginManager; [target setRequestedPermissions:[NSSet setWithObjects:@"email", @"user_friends", nil]]; __block FBSDKAccessToken *tokenAfterAuth; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { @@ -147,9 +162,8 @@ - (void)testOpenURLAuth // verify basic case of first login and no declined permissions. - (void)testOpenURLAuthNoDeclines { - [FBSDKAccessToken setCurrentAccessToken:nil]; NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile&denied_scopes=&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; - FBSDKLoginManager *target = [self loginManagerExpectingChallenge]; + FBSDKLoginManager *target = _mockLoginManager; XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); FBSDKAccessToken *actualToken = [FBSDKAccessToken currentAccessToken]; XCTAssertTrue([actualToken.userID isEqualToString:@"123"], @"failed to parse userID"); @@ -162,7 +176,6 @@ - (void)testOpenURLAuthNoDeclines - (void)testOpenURLRecentlyDeclined { XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; // receive url with denied_scopes more than what was requested. NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile&denied_scopes=user_friends,user_likes&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; @@ -174,7 +187,7 @@ - (void)testOpenURLRecentlyDeclined XCTAssertEqualObjects(result.grantedPermissions, [NSSet setWithObject:@"public_profile"]); [expectation fulfill]; }; - FBSDKLoginManager *target = [self loginManagerExpectingChallenge]; + FBSDKLoginManager *target = _mockLoginManager; [target setRequestedPermissions:[NSSet setWithObject:@"user_friends"]]; [target setHandler:handler]; XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); @@ -200,7 +213,7 @@ - (void)testOpenURLReauthSamePermissionsIsNotCancelled [FBSDKAccessToken setCurrentAccessToken:existingToken]; NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile,read_stream&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; // Use OCMock to verify the validateReauthentication: call and verify the result there. - id target = [OCMockObject partialMockForObject:[[FBSDKLoginManager alloc] init]]; + id target = _mockLoginManager; [[[target stub] andDo:^(NSInvocation *invocation) { __unsafe_unretained FBSDKLoginManagerLoginResult *result; [invocation getArgument:&result atIndex:3]; @@ -237,7 +250,7 @@ - (void)testOpenURLReauthNoPermissionsIsNotCancelled [FBSDKAccessToken setCurrentAccessToken:existingToken]; NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile,read_stream&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949"]; // Use OCMock to verify the validateReauthentication: call and verify the result there. - id target = [OCMockObject partialMockForObject:[[FBSDKLoginManager alloc] init]]; + id target = _mockLoginManager; [[[target stub] andDo:^(NSInvocation *invocation) { __unsafe_unretained FBSDKLoginManagerLoginResult *result; [invocation getArgument:&result atIndex:3]; @@ -260,10 +273,9 @@ - (void)testOpenURLReauthNoPermissionsIsNotCancelled - (void)testOpenURLWithBadChallenge { XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; NSURL *url = [self authorizeURLWithFragment:@"granted_scopes=public_profile&denied_scopes=email%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949" challenge:@"someotherchallenge"]; - FBSDKLoginManager *target = [self loginManagerExpectingChallenge]; + FBSDKLoginManager *target = _mockLoginManager; [target setRequestedPermissions:[NSSet setWithObjects:@"email", @"user_friends", nil]]; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { XCTAssertNotNil(error); @@ -281,10 +293,9 @@ - (void)testOpenURLWithBadChallenge - (void)testOpenURLWithNoChallengeAndError { XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; - [FBSDKAccessToken setCurrentAccessToken:nil]; NSURL *url = [self authorizeURLWithParameters:@"error=some_error&error_code=999&error_message=Errorerror_reason=foo#_=_" joinedBy:@"?"]; - FBSDKLoginManager *target = [self loginManagerExpectingChallenge]; + FBSDKLoginManager *target = _mockLoginManager; [target setRequestedPermissions:[NSSet setWithObjects:@"email", @"user_friends", nil]]; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { XCTAssertNotNil(error); @@ -301,7 +312,7 @@ - (void)testOpenURLWithNoChallengeAndError - (void)testOpenURLAuthWithIDToken { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; - FBSDKLoginManager *target = [self loginManagerExpectingChallengeAndNonce]; + FBSDKLoginManager *target = _mockLoginManager; [FBSDKAuthenticationToken setSkipSignatureVerification:YES]; long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; @@ -328,7 +339,6 @@ - (void)testOpenURLAuthWithIDToken NSURL *url = [self authorizeURLWithFragment:[NSString stringWithFormat:@"id_token=%@", tokenString] challenge:kFakeChallenge]; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { - // TODO: Verify that the expected profile is set. // XCTAssertFalse(result.isCancelled); FBSDKAuthenticationToken *authToken = FBSDKAuthenticationToken.currentAuthenticationToken; @@ -357,13 +367,14 @@ - (void)testOpenURLAuthWithIDToken - (void)testOpenURLAuthWithInvalidIDToken { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; - [FBSDKAccessToken setCurrentAccessToken:nil]; - FBSDKLoginManager *target = [self loginManagerExpectingChallengeAndNonce]; + FBSDKLoginManager *target = _mockLoginManager; NSURL *url = [self authorizeURLWithFragment:@"id_token=invalid_token" challenge:kFakeChallenge]; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { XCTAssertNotNil(error); - XCTAssertNil([FBSDKAccessToken currentAccessToken]); + OCMReject([self->_mockAccessTokenClass setCurrentAccessToken:OCMOCK_ANY]); + OCMReject([self->_mockAuthenticationTokenClass setCurrentAuthenticationToken:OCMOCK_ANY]); + OCMReject([self->_mockProfileClass setCurrentProfile:OCMOCK_ANY]); [expectation fulfill]; }]; @@ -377,16 +388,12 @@ - (void)testOpenURLAuthWithInvalidIDToken - (void)testLoginManagerRetainsItselfForLoginMethod { // Mock some methods to force an error callback. - id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { - // Nothing - }] validateURLSchemes]; - [[[FBSDKInternalUtilityMock stub] andReturnValue:@NO] isFacebookAppInstalled]; + [[[_mockInternalUtility stub] andReturnValue:@NO] isFacebookAppInstalled]; NSError *URLError = [[NSError alloc] initWithDomain:FBSDKErrorDomain code:0 userInfo:nil]; - [[FBSDKInternalUtilityMock stub] appURLWithHost:OCMOCK_ANY - path:OCMOCK_ANY - queryParameters:OCMOCK_ANY - error:((NSError __autoreleasing **)[OCMArg setTo:URLError])]; + [[_mockInternalUtility stub] appURLWithHost:OCMOCK_ANY + path:OCMOCK_ANY + queryParameters:OCMOCK_ANY + error:((NSError __autoreleasing **)[OCMArg setTo:URLError])]; XCTestExpectation *expectation = [self expectationWithDescription:@"completed auth"]; FBSDKLoginManager *manager = [FBSDKLoginManager new]; @@ -403,14 +410,10 @@ - (void)testLoginManagerRetainsItselfForLoginMethod - (void)testCallingLoginWhileAnotherLoginHasNotFinishedNoOps { // Mock some methods to force a SafariVC load - id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { - // Nothing - }] validateURLSchemes]; - [[[FBSDKInternalUtilityMock stub] andReturnValue:@NO] isFacebookAppInstalled]; + [[[_mockInternalUtility stub] andReturnValue:@NO] isFacebookAppInstalled]; __block int loginCount = 0; - FBSDKLoginManager *manager = [OCMockObject partialMockForObject:[FBSDKLoginManager new]]; + FBSDKLoginManager *manager = _mockLoginManager; [[[(id)manager stub] andDo:^(NSInvocation *invocation) { loginCount++; }] logIn]; @@ -429,68 +432,42 @@ - (void)testCallingLoginWhileAnotherLoginHasNotFinishedNoOps - (void)testBetaLoginExperienceEnabledLoginParams { - id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { - // Nothing - }] validateURLSchemes]; - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; - FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"] betaLoginExperience:FBSDKBetaLoginExperienceEnabled]; - - NSDictionary *params = [loginManager logInParametersWithConfiguration:config serverConfiguration:nil]; - long long cbt = [params[@"cbt"] longLongValue]; - long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); - XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); - XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); + FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] + initWithPermissions:@[@"public_profile", @"email"] + betaLoginExperience:FBSDKBetaLoginExperienceEnabled]; + + NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:config serverConfiguration:nil]; + [self validateCommonLoginParameters:params]; // TODO: Re-implement when server issue resolved - T80884847 // XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"response_type"], @"token_or_nonce,signed_request,graph_domain"); - XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); - XCTAssertEqualObjects(params[@"display"], @"touch"); - XCTAssertEqualObjects(params[@"sdk"], @"ios"); - XCTAssertEqualObjects(params[@"return_scopes"], @"true"); - XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); - XCTAssertEqualObjects(params[@"fbapp_pres"], @0); - XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); // TODO: Re-implement when server issue resolved - T80884847 - // XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + // XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); XCTAssertNotNil(params[@"nonce"]); } - (void)testBetaLoginExperienceRestrictedLoginParams { - id FBSDKInternalUtilityMock = [OCMockObject niceMockForClass:[FBSDKInternalUtility class]]; - [[[FBSDKInternalUtilityMock stub] andDo:^(NSInvocation *invocation) { - // Nothing - }] validateURLSchemes]; - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; - FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"] betaLoginExperience:FBSDKBetaLoginExperienceRestricted nonce:@"some_nonce"]; - - NSDictionary *params = [loginManager logInParametersWithConfiguration:config serverConfiguration:nil]; - long long cbt = [params[@"cbt"] longLongValue]; - long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); - XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); - XCTAssertEqualObjects(params[@"client_id"], @"7391628439"); + FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] + initWithPermissions:@[@"public_profile", @"email"] + betaLoginExperience:FBSDKBetaLoginExperienceRestricted + nonce:@"some_nonce"]; + + NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:config serverConfiguration:nil]; + [self validateCommonLoginParameters:params]; XCTAssertEqualObjects(params[@"response_type"], @"id_token"); - XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); - XCTAssertEqualObjects(params[@"display"], @"touch"); - XCTAssertEqualObjects(params[@"sdk"], @"ios"); - XCTAssertEqualObjects(params[@"return_scopes"], @"true"); - XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); - XCTAssertEqualObjects(params[@"fbapp_pres"], @0); - XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); // TODO: Re-implement when server issue resolved - T80884847 -// XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); - XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); + // XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); } - (void)testlogInParametersFromURL { NSURL *url = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22fb_login%22%3A%22%7B%5C%22granted_scopes%5C%22%3A%5C%22public_profile%5C%22%2C%5C%22denied_scopes%5C%22%3A%5C%22%5C%22%2C%5C%22signed_request%5C%22%3A%5C%22ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0%5C%22%2C%5C%22nonce%5C%22%3A%5C%22someNonce%5C%22%2C%5C%22data_access_expiration_time%5C%22%3A%5C%221607374566%5C%22%2C%5C%22expires_in%5C%22%3A%5C%225183401%5C%22%7D%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; - NSDictionary *params = [loginManager logInParametersFromURL:url]; + NSDictionary *params = [_mockLoginManager logInParametersFromURL:url]; XCTAssertNotNil(params); XCTAssertEqualObjects(params[@"nonce"], @"someNonce"); @@ -502,7 +479,6 @@ - (void)testLogInWithURLFailWithInvalidLoginData { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; NSURL *urlWithInvalidLoginData = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22fb_login%22%3A%22invalid%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; FBSDKLoginManagerLoginResultBlock handler = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { XCTAssertNil(result); @@ -512,7 +488,7 @@ - (void)testLogInWithURLFailWithInvalidLoginData } }; - [loginManager logInWithURL:urlWithInvalidLoginData handler:handler]; + [_mockLoginManager logInWithURL:urlWithInvalidLoginData handler:handler]; [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { XCTAssertNil(error); @@ -523,7 +499,6 @@ - (void)testLogInWithURLFailWithNoLoginData { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; NSURL *urlWithNoLoginData = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22some_param%22%3A%22some_value%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; FBSDKLoginManagerLoginResultBlock handler = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { XCTAssertNil(result); @@ -533,7 +508,7 @@ - (void)testLogInWithURLFailWithNoLoginData } }; - [loginManager logInWithURL:urlWithNoLoginData handler:handler]; + [_mockLoginManager logInWithURL:urlWithNoLoginData handler:handler]; [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { XCTAssertNil(error); @@ -542,26 +517,36 @@ - (void)testLogInWithURLFailWithNoLoginData - (void)testLogout { - id accessTokenClassMock = OCMClassMock(FBSDKAccessToken.class); - id authenticationTokenClassMock = OCMClassMock(FBSDKAuthenticationToken.class); - id profileClassMock = OCMClassMock(FBSDKProfile.class); - - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; - [loginManager logOut]; + [_mockLoginManager logOut]; - OCMVerify(ClassMethod([accessTokenClassMock setCurrentAccessToken:nil])); - OCMVerify(ClassMethod([authenticationTokenClassMock setCurrentAuthenticationToken:nil])); - OCMVerify(ClassMethod([profileClassMock setCurrentProfile:nil])); + OCMVerify(ClassMethod([_mockAccessTokenClass setCurrentAccessToken:nil])); + OCMVerify(ClassMethod([_mockAuthenticationTokenClass setCurrentAuthenticationToken:nil])); + OCMVerify(ClassMethod([_mockProfileClass setCurrentProfile:nil])); } - (void)testStoreExpectedNonce { FBSDKKeychainStore *keychainStore = [[FBSDKKeychainStore alloc] initWithService:self.name accessGroup:nil]; - FBSDKLoginManager *loginManager = [FBSDKLoginManager new]; - [loginManager storeExpectedNonce:@"some_nonce" keychainStore:keychainStore]; + [_mockLoginManager storeExpectedNonce:@"some_nonce" keychainStore:keychainStore]; XCTAssertEqualObjects([keychainStore stringForKey:@"expected_login_nonce"], @"some_nonce"); } +- (void)validateCommonLoginParameters:(NSDictionary *)params +{ + XCTAssertEqualObjects(params[@"client_id"], kFakeAppID); + XCTAssertEqualObjects(params[@"redirect_uri"], @"fbconnect://success"); + XCTAssertEqualObjects(params[@"display"], @"touch"); + XCTAssertEqualObjects(params[@"sdk"], @"ios"); + XCTAssertEqualObjects(params[@"return_scopes"], @"true"); + XCTAssertEqual(params[@"auth_type"], FBSDKLoginAuthTypeRerequest); + XCTAssertEqualObjects(params[@"fbapp_pres"], @0); + XCTAssertEqualObjects(params[@"ies"], [FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0); + + long long cbt = [params[@"cbt"] longLongValue]; + long long currentMilliseconds = round(1000 * [NSDate date].timeIntervalSince1970); + XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); +} + @end From b25df16aa60cb61ca20bc49f2ed0773d26e87383 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 7 Dec 2020 09:52:04 -0800 Subject: [PATCH 152/227] Fix Login Manager Check for Cancellation Summary: This is for people implementing login with LoginManager directly. An attempt should be inferred to be cancelled if there is no Authentication or AccessToken. Reviewed By: ppansy Differential Revision: D25339923 fbshipit-source-id: 9ebc54fb85ca6ba530ca597dc11a20fb14c5b406 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index ec82d7eb4c..d469422723 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -199,7 +199,7 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe NSError *error = parameters.error; NSString *tokenString = parameters.accessTokenString; - BOOL cancelled = (tokenString == nil); + BOOL cancelled = ((tokenString == nil) && (FBSDKAuthenticationToken.currentAuthenticationToken == nil)); BOOL challengePassed = YES; if (expectChallenge) { From 53182218bbd9d39dea4fc9859f2261bdc0590b07 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 7 Dec 2020 10:09:58 -0800 Subject: [PATCH 153/227] Adding notifications for AuthenticationToken changes Summary: $title Reviewed By: ppansy Differential Revision: D25317137 fbshipit-source-id: 9a02a04591f75ccee3485d379d5aa64f316d19e1 --- .../FBSDKCoreKit/FBSDKAuthenticationToken.h | 42 +++++++ .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 12 ++ .../FBSDKAuthenticationTokenTests.m | 104 +++++++++++++++++- .../Helpers/NotificationCenterSpy.swift | 37 ++++++- 4 files changed, 188 insertions(+), 7 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h index bee2a0154e..3e7d7a01b7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h @@ -20,6 +20,48 @@ NS_ASSUME_NONNULL_BEGIN +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +/** + Notification indicating that the `currentAuthenticationToken` has changed. + + the userInfo dictionary of the notification will contain keys + `FBSDKAuthenticationTokenChangeOldKey` and + `FBSDKAuthenticationTokenChangeNewKey`. + */ +FOUNDATION_EXPORT NSNotificationName const FBSDKAuthenticationTokenDidChangeNotification +NS_SWIFT_NAME(AuthenticationTokenDidChange); + +#else + +/** + Notification indicating that the `currentAuthenticationToken` has changed. + + the userInfo dictionary of the notification will contain keys + `FBSDKAuthenticationTokenChangeOldKey` and + `FBSDKAuthenticationTokenChangeNewKey`. + */ +FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenDidChangeNotification +NS_SWIFT_NAME(AuthenticationTokenDidChange); + +#endif + +/** + A key in the `AuthenticationTokenDidChange` notification's userInfo object for getting the old token. + + If there was no old token, the key will not be present. + */ +FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenChangeOldKey +NS_SWIFT_NAME(AuthenticationTokenChangeOldKey); + +/** + A key in `AuthenticationTokenDidChange` notification's userInfo object for getting the new token. + + If there is no new token, the key will not be present. + */ +FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenChangeNewKey +NS_SWIFT_NAME(AuthenticationTokenChangeNewKey); + /** Represent an AuthenticationToken used for a login attempt */ diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index c8b6c73230..89cb6e6b10 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -41,6 +41,10 @@ NSString *const FBSDKAuthenticationTokenTokenStringCodingKey = @"FBSDKAuthenticationTokenTokenStringCodingKey"; NSString *const FBSDKAuthenticationTokenNonceCodingKey = @"FBSDKAuthenticationTokenNonceCodingKey"; +NSNotificationName const FBSDKAuthenticationTokenDidChangeNotification = @"com.facebook.sdk.FBSDKAuthenticationTokenData.FBSDKAuthenticationTokenDidChangeNotification"; +NSString *const FBSDKAuthenticationTokenChangeNewKey = @"FBSDKAuthenticationTokenChangeNew"; +NSString *const FBSDKAuthenticationTokenChangeOldKey = @"FBSDKAuthenticationTokenChangeOld"; + static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins @implementation FBSDKAuthenticationToken @@ -117,8 +121,16 @@ + (FBSDKAuthenticationToken *)currentAuthenticationToken + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token { if (token != g_currentAuthenticationToken) { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + [FBSDKTypeUtility dictionary:userInfo setObject:token forKey:FBSDKAuthenticationTokenChangeNewKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:g_currentAuthenticationToken forKey:FBSDKAuthenticationTokenChangeOldKey]; + g_currentAuthenticationToken = token; [[self tokenCache] setAuthenticationToken:token]; + + [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAuthenticationTokenDidChangeNotification + object:[self class] + userInfo:userInfo]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m index 6d51869baf..61814ab156 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m @@ -44,7 +44,6 @@ @interface FBSDKAuthenticationToken (Testing) + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; + (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; - + (instancetype)emptyInstance; - (void)setCertificate:(NSString *)certificate; @@ -68,6 +67,7 @@ @implementation FBSDKAuthenticationTokenTests FBSDKAuthenticationToken *_token; NSDictionary *_claims; NSDictionary *_header; + NotificationCenterSpy *_notificationCenterSpy; } - (void)setUp @@ -93,8 +93,21 @@ - (void)setUp @"alg" : @"RS256", @"typ" : @"JWT" }; + + _notificationCenterSpy = [NotificationCenterSpy new]; + [self stubDefaultNotificationCenterWith:_notificationCenterSpy]; +} + +// MARK: - Creation + +- (void)testCreateWithInvalidFormatTokenShouldFail +{ + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token" nonce:@"123456789"]; + XCTAssertNil(_token); } +// MARK: - Persistence + - (void)testRetrievingCurrentToken { FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]; @@ -155,6 +168,8 @@ - (void)testDecodingEntryWithMethodName ); } +// MARK: - Decoding Claims + - (void)testDecodeValidClaimsShouldSucceed { NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; @@ -225,11 +240,7 @@ - (void)testDecodeRandomClaims } } -- (void)testCreateWithInvalidFormatTokenShouldFail -{ - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token" nonce:@"123456789"]; - XCTAssertNil(_token); -} +// MARK: - Decoding Header - (void)testDecodeValidHeaderShouldSucceed { @@ -278,6 +289,8 @@ - (void)testDecodeRandomHeader } } +// MARK: - Verifying Signature + - (void)testVerifyValidSignatureShouldSucceed { _token = [FBSDKAuthenticationToken emptyInstance]; @@ -316,6 +329,85 @@ - (void)testVerifySignatureWithInvalidCertificateShouldFail ); } +// MARK: - Notifications + +- (void)testPostsNotificationOnSettingInitial +{ + _token = [FBSDKAuthenticationToken emptyInstance]; + FBSDKAuthenticationToken.currentAuthenticationToken = _token; + + XCTAssertTrue( + [_notificationCenterSpy.capturedPostNames containsObject:FBSDKAuthenticationTokenDidChangeNotification], + "Should post a notification when the authentication token is initially set" + ); + XCTAssertTrue( + [_notificationCenterSpy.capturedPostObjects containsObject:FBSDKAuthenticationToken.class], + "Notification should contain information about the object that posted it" + ); + XCTAssertTrue( + [_notificationCenterSpy.capturedPostUserInfos containsObject:@{ + FBSDKAuthenticationTokenChangeNewKey : _token + }], + "Notification should contain information about the change that occured" + ); +} + +- (void)testPostsNotificationOnSettingNew +{ + _token = [FBSDKAuthenticationToken emptyInstance]; + FBSDKAuthenticationToken *token2 = [FBSDKAuthenticationToken emptyInstance]; + FBSDKAuthenticationToken.currentAuthenticationToken = _token; + + [_notificationCenterSpy clearTestEvidence]; + FBSDKAuthenticationToken.currentAuthenticationToken = token2; + + NSDictionary *expectedUserInfo = @{ + FBSDKAuthenticationTokenChangeOldKey : _token, + FBSDKAuthenticationTokenChangeNewKey : token2 + }; + + XCTAssertTrue( + [_notificationCenterSpy.capturedPostNames containsObject:FBSDKAuthenticationTokenDidChangeNotification], + "Should post a notification when the authentication token is changed" + ); + XCTAssertTrue( + [_notificationCenterSpy.capturedPostObjects containsObject:FBSDKAuthenticationToken.class], + "Notification should contain information about the object that posted it" + ); + XCTAssertTrue( + [_notificationCenterSpy.capturedPostUserInfos containsObject:expectedUserInfo], + "Notification should contain information about the change that occured" + ); +} + +- (void)testPostsNotificationOnSettingNil +{ + _token = [FBSDKAuthenticationToken emptyInstance]; + FBSDKAuthenticationToken.currentAuthenticationToken = _token; + + [_notificationCenterSpy clearTestEvidence]; + FBSDKAuthenticationToken.currentAuthenticationToken = nil; + + NSDictionary *expectedUserInfo = @{ + FBSDKAuthenticationTokenChangeOldKey : _token + }; + + XCTAssertTrue( + [_notificationCenterSpy.capturedPostNames containsObject:FBSDKAuthenticationTokenDidChangeNotification], + "Should post a notification when the authentication token is removed" + ); + XCTAssertTrue( + [_notificationCenterSpy.capturedPostObjects containsObject:FBSDKAuthenticationToken.class], + "Notification should contain information about the object that posted it" + ); + XCTAssertTrue( + [_notificationCenterSpy.capturedPostUserInfos containsObject:expectedUserInfo], + "Notification should contain information about the change that occured" + ); +} + +// MARK: - Utilities + - (void)testBase64FromBase64Url { NSString *expectedString = @"testBase64FromBase64Url"; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift index d973494e86..3b346fb6fe 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/NotificationCenterSpy.swift @@ -18,8 +18,43 @@ import Foundation +@objcMembers class NotificationCenterSpy: NotificationCenter { - override func addObserver(_ observer: Any, selector: Selector, name: NSNotification.Name?, object: Any?) { + var capturedRemovedObservers = [Any]() + var capturedPostNames = [NSNotification.Name]() + var capturedPostObjects = [Any]() + var capturedPostUserInfos = [[AnyHashable : Any]]() + + // MARK: Posting + + override func post( + name: NSNotification.Name, + object: Any?, + userInfo: [AnyHashable : Any]? = nil + ) { + self.capturedPostNames.append(name) + self.capturedPostObjects.append(object as Any) + self.capturedPostUserInfos.append(userInfo ?? [:]) + } + + // MARK: Observing + override func removeObserver(_ observer: Any) { + capturedRemovedObservers.append(observer) + } + + override func addObserver( + _ observer: Any, + selector: Selector, + name: NSNotification.Name?, + object: Any? + ) { // TODO: capture values } + + func clearTestEvidence() { + capturedRemovedObservers = [] + capturedPostNames = [] + capturedPostObjects = [] + capturedPostUserInfos = [] + } } From e809087f942f3ff7605ffbd4146a2257d6a5fe2e Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 7 Dec 2020 15:00:24 -0800 Subject: [PATCH 154/227] Add Authentication Token factory object Summary: Add a factory builder object for Authentication token to support async verification for the id token string Reviewed By: robtimp Differential Revision: D25325191 fbshipit-source-id: 2c01894d98afb507dede924912f7c48fb7684c51 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 16 + .../FBSDKCoreKit/FBSDKAuthenticationToken.h | 9 - .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 195 +---------- .../FBSDKAuthenticationTokenFactory.h | 53 +++ .../FBSDKAuthenticationTokenFactory.m | 244 +++++++++++++ .../Internal/FBSDKCoreKit+Internal.h | 2 + .../FBSDKAuthenticationTokenTests.m | 298 +--------------- .../FBSDKCoreKitTests-Bridging-Header.h | 4 +- .../FBSDKAuthenticationTokenFactoryTests.m | 321 ++++++++++++++++++ .../Helpers/SampleAuthenticationToken.swift | 4 +- .../FBSDKLoginKit/FBSDKLoginManager.m | 7 +- .../Internal/FBSDKLoginCompletion+Internal.h | 1 + .../Internal/FBSDKLoginCompletion.h | 9 +- .../Internal/FBSDKLoginCompletion.m | 35 +- .../FBSDKLoginKit/Internal/FBSDKLoginError.m | 2 - .../FBSDKLoginManagerTests.m | 6 +- 16 files changed, 683 insertions(+), 523 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index abe34ab6c6..f737ca24cf 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -782,6 +782,11 @@ C5EAFAC725528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; C5EAFAD525528EB200458DF5 /* FBSDKUserDataStore+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */; }; C5F6EC861FA24FAF009EB258 /* FBSDKPaymentObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */; }; + C638153D257EA7CC00B7690F /* FBSDKAuthenticationTokenFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */; }; + C638158A257EA8F000B7690F /* FBSDKAuthenticationTokenFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */; }; + C6381628257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6381619257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m */; }; + C6A308BD257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */; }; + C6A308D8257AD227003C52FD /* FBSDKAuthenticationTokenFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */; }; C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */; }; E4416C0123F61902009CCBFA /* FBSDKModelParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */; }; E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4416C0023F61902009CCBFA /* FBSDKModelParser.mm */; }; @@ -1539,6 +1544,9 @@ C5D25D3521795B790037B13D /* FBSDKCodelessIndexer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKCodelessIndexer.m; sourceTree = ""; }; C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKUserDataStore+Internal.h"; sourceTree = ""; }; C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPaymentObserverTests.m; sourceTree = ""; }; + C6381619257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenFactoryTests.m; sourceTree = ""; }; + C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationTokenFactory.h; sourceTree = ""; }; + C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenFactory.m; sourceTree = ""; }; C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterTests.m; sourceTree = ""; }; E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKModelParser.h; sourceTree = ""; }; E4416C0023F61902009CCBFA /* FBSDKModelParser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FBSDKModelParser.mm; sourceTree = ""; }; @@ -2005,6 +2013,8 @@ 52963A9E215993C100C7B252 /* FBSDKAppLink_Internal.h */, 52963A9B215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h */, 894C0ACD1A6F0D3F009137EF /* FBSDKApplicationDelegate+Internal.h */, + C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */, + C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */, C5188DF8222F388400F4D8BC /* FBSDKApplicationObserving.h */, 89D05AA71AA1134000609300 /* FBSDKAudioResourceLoader.h */, 89D05AA81AA1134000609300 /* FBSDKAudioResourceLoader.m */, @@ -2074,6 +2084,7 @@ 893F44A41A644552001DB0B6 /* Internal */ = { isa = PBXGroup; children = ( + C6381619257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m */, 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */, 9D18A8D91A95403F00A41042 /* AppEvents */, 7E5557391A8D833800344F86 /* AppLinks */, @@ -2921,6 +2932,7 @@ files = ( F916581624F6BB4D00BB759A /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */, F943110424F8D613002441F1 /* FBSDKSKAdNetworkRule.h in Headers */, + C638153D257EA7CC00B7690F /* FBSDKAuthenticationTokenFactory.h in Headers */, 81B71D481D19C87400933E93 /* FBSDKAppLinkUtility.h in Headers */, 81B71D491D19C87400933E93 /* FBSDKAppLinkResolver.h in Headers */, 52963AA6215993C100C7B252 /* FBSDKAppLink_Internal.h in Headers */, @@ -3067,6 +3079,7 @@ files = ( F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, 7E30917B1AA92A95004E91D5 /* FBSDKAppLinkUtility.h in Headers */, + C6A308D8257AD227003C52FD /* FBSDKAuthenticationTokenFactory.h in Headers */, 7E5557381A8D833100344F86 /* FBSDKAppLinkResolver.h in Headers */, 9D32A8401A69941A000A936D /* FBSDKTokenCaching.h in Headers */, F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, @@ -3982,6 +3995,7 @@ 81B71D301D19C87400933E93 /* FBSDKAppLinkResolver.m in Sources */, F420D18F2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 81B71D311D19C87400933E93 /* FBSDKIcon.m in Sources */, + C638158A257EA8F000B7690F /* FBSDKAuthenticationTokenFactory.m in Sources */, F468B2A724C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, E4416C1623F61917009CCBFA /* FBSDKModelParser.mm in Sources */, 5D90CDE02343D4BD00AF326A /* FBSDKCrashShield.m in Sources */, @@ -4112,6 +4126,7 @@ 9DBA6A311A80265A00B4DE6A /* FBSDKColor.m in Sources */, E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */, F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, + C6A308BD257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m in Sources */, 7E5557371A8D833100344F86 /* FBSDKAppLinkResolver.m in Sources */, F468B2A624C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, F468B34A24C25AB600979F8D /* FBSDKURLSession.m in Sources */, @@ -4214,6 +4229,7 @@ 5D497702244A3E6A00BD45C6 /* FBSDKIntegrityTests.m in Sources */, F4210E1E241AFF740061F56D /* FBSDKMethodUsageMonitorTests.m in Sources */, F428430B246B427700CD4393 /* FBSDKServerConfigurationManagerTests.swift in Sources */, + C6381628257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m in Sources */, F9CEF1EB24F769F900EB0C3D /* FBSDKSKAdNetworkReporterTests.m in Sources */, F98D1D73251297A900276B68 /* FBSDKAppEventsConfigurationManagerTests.swift in Sources */, F44B051125645DAC0059A3A6 /* FakeDylibResolver.swift in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h index 3e7d7a01b7..5929fdd218 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h @@ -89,15 +89,6 @@ NS_SWIFT_NAME(AuthenticationToken) */ @property (nonatomic, copy, readonly) NSString *nonce; -/** - Initializes a new instance if the token represented by the token string is valid. Otherwise returns nil. - An `AuthenticationToken` is verified based of the OpenID Connect Protocol. - @param tokenString the raw ID token string - @param nonce the nonce string used to associate a client session with the token -*/ -- (instancetype)initWithTokenString:(NSString *)tokenString - nonce:(NSString *)nonce; - @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index 89cb6e6b10..1a6642f00b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -32,10 +32,6 @@ #import "FBSDKCoreKit+Internal.h" #endif -#import - -#import - static FBSDKAuthenticationToken *g_currentAuthenticationToken; NSString *const FBSDKAuthenticationTokenTokenStringCodingKey = @"FBSDKAuthenticationTokenTokenStringCodingKey"; @@ -45,71 +41,20 @@ NSString *const FBSDKAuthenticationTokenChangeNewKey = @"FBSDKAuthenticationTokenChangeNew"; NSString *const FBSDKAuthenticationTokenChangeOldKey = @"FBSDKAuthenticationTokenChangeOld"; -static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins - @implementation FBSDKAuthenticationToken { - NSString *_cert; NSDictionary *_claims; - NSDictionary *_header; - NSString *_signature; } - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce -{ - if (!tokenString || tokenString.length == 0 || !nonce || nonce.length == 0) { - return nil; - } - - NSString *signature; - NSDictionary *claims; - NSDictionary *header; - - NSArray *segments = [tokenString componentsSeparatedByString:@"."]; - if (segments.count != 3) { - return nil; - } - - NSString *encodedHeader = [FBSDKTypeUtility array:segments objectAtIndex:0]; - NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; - signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; - - if (![self verifySignature:signature - header:encodedHeader - claims:encodedClaims]) { - return nil; - } - - claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; - header = [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; - - if (!claims || !header) { - return nil; - } - - return [self initWithTokenString:tokenString - nonce:nonce - signature:signature - claims:claims - header:header]; -} - -/// Do not call directly. Does not validate any of the data. -- (instancetype)initWithTokenString:(NSString *)tokenString - nonce:(NSString *)nonce - signature:(NSString *)signature claims:(NSDictionary *)claims - header:(NSDictionary *)header { if ((self = [super init])) { _tokenString = tokenString; _nonce = nonce; - _signature = signature; _claims = claims; - _header = header; } - return self; } @@ -134,125 +79,6 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token } } -+ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce -{ - NSError *error; - NSData *claimsData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:encodedClaims]]; - - if (claimsData) { - NSDictionary *claims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; - if (!error) { - long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; - - // verify claims - BOOL isFacebook = [claims[@"iss"] isKindOfClass:[NSString class]] && [[[NSURL URLWithString:claims[@"iss"]] host] isEqualToString:@"facebook.com"]; - BOOL audMatched = [claims[@"aud"] isKindOfClass:[NSString class]] && [claims[@"aud"] isEqualToString:[FBSDKSettings appID]]; - BOOL isExpired = [claims[@"exp"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"exp"] longValue] <= currentTime; - BOOL issuedRecently = [claims[@"iat"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"iat"] longValue] >= currentTime - MaxTimeSinceTokenIssued; - BOOL nonceMatched = [claims[@"nonce"] isKindOfClass:[NSString class]] && [claims[@"nonce"] isEqualToString:nonce]; - BOOL userIDValid = [claims[@"sub"] isKindOfClass:[NSString class]] && [claims[@"sub"] length] > 0; - - if (isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid) { - return claims; - } - } - } - - return nil; -} - -+ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader -{ - NSError *error; - NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:encodedHeader]]; - - if (headerData) { - NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; - if (!error && [header[@"alg"] isKindOfClass:[NSString class]] && [header[@"alg"] isEqualToString:@"RS256"]) { - return header; - } - } - - return nil; -} - -- (BOOL)verifySignature:(NSString *)signature - header:(NSString *)header - claims:(NSString *)claims -{ -#if DEBUG - // skip signature checking for tests - if (_skipSignatureVerification) { - return YES; - } -#endif - - NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationToken base64FromBase64Url:signature]]; - NSString *signedString = [NSString stringWithFormat:@"%@.%@", header, claims]; - NSData *signedData = [signedString dataUsingEncoding:NSASCIIStringEncoding]; - SecKeyRef publicKey = [self getPublicKey]; - - if (publicKey && signatureData && signedData) { - OSStatus status = -1; - - size_t signatureBytesSize = SecKeyGetBlockSize(publicKey); - const void *signatureBytes = signatureData.bytes; - - size_t digestSize = CC_SHA256_DIGEST_LENGTH; - uint8_t digestBytes[digestSize]; - CC_SHA256(signedData.bytes, (CC_LONG)signedData.length, digestBytes); - - status = SecKeyRawVerify( - publicKey, - kSecPaddingPKCS1SHA256, - digestBytes, - digestSize, - signatureBytes, - signatureBytesSize - ); - return status == errSecSuccess; - } - return NO; -} - -- (NSString *)getCertificate -{ - // TODO(T79340096): replace with certificate retrieved from crypto keychain service - return _cert; -} - -- (SecKeyRef)getPublicKey -{ - SecKeyRef publicKey = nil; - NSData *certData = [FBSDKBase64 decodeAsData:[self getCertificate]]; - SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certData); - - if (cert) { - SecPolicyRef policy = SecPolicyCreateBasicX509(); - OSStatus status = -1; - SecTrustRef trust; - - status = SecTrustCreateWithCertificates(cert, policy, &trust); - - if (status == errSecSuccess && trust) { - publicKey = SecTrustCopyPublicKey(trust); - } - - CFRelease(policy); - CFRelease(cert); - } - - return publicKey; -} - -+ (NSString *)base64FromBase64Url:(NSString *)base64Url -{ - NSString *base64 = [base64Url stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; - base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; - - return base64; -} - #pragma mark Storage + (id)tokenCache @@ -272,9 +98,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder return [self initWithTokenString:tokenString nonce:nonce - signature:nil - claims:nil - header:nil]; + claims:nil]; } - (void)encodeWithCoder:(NSCoder *)encoder @@ -292,23 +116,6 @@ + (void)resetCurrentAuthenticationTokenCache g_currentAuthenticationToken = nil; } -static BOOL _skipSignatureVerification; - -+ (void)setSkipSignatureVerification:(BOOL)value -{ - _skipSignatureVerification = value; -} - -+ (instancetype)emptyInstance -{ - return [super new]; -} - -- (void)setCertificate:(NSString *)certificate -{ - _cert = certificate; -} - - (NSDictionary *)claims { return _claims; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h new file mode 100644 index 0000000000..6ba54ce113 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h @@ -0,0 +1,53 @@ +// 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 + +#if SWIFT_PACKAGE + #import "FBSDKAuthenticationToken" +#else + #import +#endif + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^FBSDKAuthenticationTokenBlock)(FBSDKAuthenticationToken *_Nullable token) +NS_SWIFT_NAME(AuthenticationTokenBlock); + +/** + Class responsible for generating an `AuthenticationToken` given a valid token string. + An `AuthenticationToken` is verified based of the OpenID Connect Protocol. + */ +NS_SWIFT_NAME(AuthenticationTokenFactory) +@interface FBSDKAuthenticationTokenFactory : NSObject + + /** + Create an `AuthenticationToken` given a valid token string. + Returns nil to the completion handler if the token string is invalid + An `AuthenticationToken` is verified based of the OpenID Connect Protocol. + @param tokenString the raw ID token string + @param nonce the nonce string used to associate a client session with the token + @param completion the completion handler +*/ +- (void)createTokenFromTokenString:(NSString * _Nonnull)tokenString + nonce:(NSString * _Nonnull)nonce + completion:(FBSDKAuthenticationTokenBlock)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m new file mode 100644 index 0000000000..13715080f9 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -0,0 +1,244 @@ +// 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 "FBSDKAuthenticationTokenFactory.h" + +#if SWIFT_PACKAGE +@import FBSDKCoreKit; +#else + #import +#endif + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +#import + +#import + +static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins + +@interface FBSDKAuthenticationToken (FactoryInitializer) + +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + claims:(NSDictionary *)claims; + +@end + +@implementation FBSDKAuthenticationTokenFactory +{ + NSString *_cert; + NSDictionary *_claims; + NSDictionary *_header; + NSString *_signature; +} + +- (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString + nonce:(NSString *)nonce + completion:(FBSDKAuthenticationTokenBlock)completion +{ + if (!tokenString || tokenString.length == 0 || !nonce || nonce.length == 0) { + completion(nil); + return; + } + + NSString *signature; + NSDictionary *claims; + NSDictionary *header; + + NSArray *segments = [tokenString componentsSeparatedByString:@"."]; + if (segments.count != 3) { + completion(nil); + return; + } + + NSString *encodedHeader = [FBSDKTypeUtility array:segments objectAtIndex:0]; + NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; + signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; + + claims = [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; + header = [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; + + if (!claims || !header) { + completion(nil); + return; + } + + if (![self verifySignature:signature + header:encodedHeader + claims:encodedClaims]) { + completion(nil); + return; + } + + FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc]initWithTokenString:tokenString nonce:nonce claims:claims]; + completion(token); +} + ++ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce +{ + NSError *error; + NSData *claimsData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory base64FromBase64Url:encodedClaims]]; + + if (claimsData) { + NSDictionary *claims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; + if (!error) { + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + + // verify claims + BOOL isFacebook = [claims[@"iss"] isKindOfClass:[NSString class]] && [[[NSURL URLWithString:claims[@"iss"]] host] isEqualToString:@"facebook.com"]; + BOOL audMatched = [claims[@"aud"] isKindOfClass:[NSString class]] && [claims[@"aud"] isEqualToString:[FBSDKSettings appID]]; + BOOL isExpired = [claims[@"exp"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"exp"] longValue] <= currentTime; + BOOL issuedRecently = [claims[@"iat"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"iat"] longValue] >= currentTime - MaxTimeSinceTokenIssued; + BOOL nonceMatched = [claims[@"nonce"] isKindOfClass:[NSString class]] && [claims[@"nonce"] isEqualToString:nonce]; + BOOL userIDValid = [claims[@"sub"] isKindOfClass:[NSString class]] && [claims[@"sub"] length] > 0; + + if (isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid) { + return claims; + } + } + } + + return nil; +} + ++ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader +{ + NSError *error; + NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory base64FromBase64Url:encodedHeader]]; + + if (headerData) { + NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; + if (!error && [header[@"alg"] isKindOfClass:[NSString class]] && [header[@"alg"] isEqualToString:@"RS256"]) { + return header; + } + } + + return nil; +} + +- (BOOL)verifySignature:(NSString *)signature + header:(NSString *)header + claims:(NSString *)claims +{ +#if DEBUG + // skip signature checking for tests + if (_skipSignatureVerification) { + return YES; + } +#endif + + NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory base64FromBase64Url:signature]]; + NSString *signedString = [NSString stringWithFormat:@"%@.%@", header, claims]; + NSData *signedData = [signedString dataUsingEncoding:NSASCIIStringEncoding]; + SecKeyRef publicKey = [self getPublicKey]; + + if (publicKey && signatureData && signedData) { + OSStatus status = -1; + + size_t signatureBytesSize = SecKeyGetBlockSize(publicKey); + const void *signatureBytes = signatureData.bytes; + + size_t digestSize = CC_SHA256_DIGEST_LENGTH; + uint8_t digestBytes[digestSize]; + CC_SHA256(signedData.bytes, (CC_LONG)signedData.length, digestBytes); + + status = SecKeyRawVerify( + publicKey, + kSecPaddingPKCS1SHA256, + digestBytes, + digestSize, + signatureBytes, + signatureBytesSize + ); + return status == errSecSuccess; + } + return NO; +} + +- (NSString *)getCertificate +{ + // TODO(T79340096): replace with certificate retrieved from crypto keychain service + return _cert; +} + +- (SecKeyRef)getPublicKey +{ + SecKeyRef publicKey = nil; + NSData *certData = [FBSDKBase64 decodeAsData:[self getCertificate]]; + SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certData); + + if (cert) { + SecPolicyRef policy = SecPolicyCreateBasicX509(); + OSStatus status = -1; + SecTrustRef trust; + + status = SecTrustCreateWithCertificates(cert, policy, &trust); + + if (status == errSecSuccess && trust) { + publicKey = SecTrustCopyPublicKey(trust); + } + + CFRelease(policy); + CFRelease(cert); + } + + return publicKey; +} + ++ (NSString *)base64FromBase64Url:(NSString *)base64Url +{ + NSString *base64 = [base64Url stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; + base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; + + return base64; +} + +#pragma mark - Test methods + +#if DEBUG + +static BOOL _skipSignatureVerification; + ++ (void)setSkipSignatureVerification:(BOOL)value +{ + _skipSignatureVerification = value; +} + ++ (instancetype)emptyInstance +{ + return [super new]; +} + +- (void)setCertificate:(NSString *)certificate +{ + _cert = certificate; +} + +- (NSDictionary *)claims +{ + return _claims; +} + +#endif + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 7f2db78cd9..1da2e2d46f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -70,6 +70,7 @@ #import "FBSDKAppEventsUtility.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" + #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKBase64.h" #import "FBSDKButton+Subclass.h" #import "FBSDKDeviceRequestsHelper.h" @@ -148,6 +149,7 @@ #import "FBSDKAccessToken+Internal.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" + #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKDeviceRequestsHelper.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKError.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m index 61814ab156..7a63bdbc03 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m @@ -26,35 +26,11 @@ #import "FBSDKTestCase.h" #import "FBSDKTestCoder.h" -static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; - -static NSString *const _encodedHeader = @"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; - -static NSString *const _encodedClaims = @"eyJzdWIiOiIxMjM0IiwibmFtZSI6IlRlc3QgVXNlciIsImlzcyI6Imh0dHBzOi8vZmFjZWJvb2suY29tL2RpYWxvZy9vYXV0aCIsImF1ZCI6IjQzMjEiLCJub25jZSI6InNvbWVfbm9uY2UiLCJleHAiOjE1MTYyNTkwMjIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zb21lX3BpY3R1cmUiLCJpYXQiOjE1MTYyMzkwMjJ9"; - -static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; - -static NSString *const _mockAppID = @"4321"; - -static NSString *const _mockNonce = @"some_nonce"; - -static NSString *const _facebookURL = @"https://facebook.com/dialog/oauth"; - @interface FBSDKAuthenticationToken (Testing) -+ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; -+ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; -+ (instancetype)emptyInstance; - -- (void)setCertificate:(NSString *)certificate; - -+ (NSString *)base64FromBase64Url:(NSString *)base64Url; - -- (BOOL)verifySignature:(NSString *)signature - header:(NSString *)header - claims:(NSString *)claims; - -- (NSDictionary *)claims; +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + claims:(NSDictionary *)claims; @end @@ -65,8 +41,6 @@ @interface FBSDKAuthenticationTokenTests : FBSDKTestCase @implementation FBSDKAuthenticationTokenTests { FBSDKAuthenticationToken *_token; - NSDictionary *_claims; - NSDictionary *_header; NotificationCenterSpy *_notificationCenterSpy; } @@ -74,44 +48,16 @@ - (void)setUp { [super setUp]; - [self stubAppID:_mockAppID]; - - long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; - _claims = @{ - @"iss" : _facebookURL, - @"aud" : _mockAppID, - @"nonce" : _mockNonce, - @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later - @"iat" : @(currentTime - 60), // 1 min ago - @"sub" : @"1234", - @"name" : @"Test User", - @"email" : @"email@email.com", - @"picture" : @"https://www.facebook.com/some_picture", - }; - - _header = @{ - @"alg" : @"RS256", - @"typ" : @"JWT" - }; - _notificationCenterSpy = [NotificationCenterSpy new]; [self stubDefaultNotificationCenterWith:_notificationCenterSpy]; } -// MARK: - Creation - -- (void)testCreateWithInvalidFormatTokenShouldFail -{ - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"invalid_id_token" nonce:@"123456789"]; - XCTAssertNil(_token); -} - // MARK: - Persistence - (void)testRetrievingCurrentToken { FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]; - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" signature:@"" claims:@{} header:@{}]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; id partialTokenMock = OCMPartialMock(_token); OCMStub([partialTokenMock tokenCache]).andReturn(cache); @@ -133,10 +79,7 @@ - (void)testEncoding FBSDKTestCoder *coder = [FBSDKTestCoder new]; _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:expectedTokenString - nonce:expectedNonce - signature:@"" - claims:@{} - header:@{}]; + nonce:expectedNonce claims:@{}]; [_token encodeWithCoder:coder]; XCTAssertEqualObjects( @@ -168,172 +111,11 @@ - (void)testDecodingEntryWithMethodName ); } -// MARK: - Decoding Claims - -- (void)testDecodeValidClaimsShouldSucceed -{ - NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; - NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - - NSDictionary *claims = [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; - XCTAssertEqualObjects(claims, _claims); -} - -- (void)testDecodeInvalidFormatClaimsShouldFail -{ - NSData *claimsData = [@"invalid_claims" dataUsingEncoding:NSUTF8StringEncoding]; - NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - - XCTAssertNil([FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); -} - -- (void)testDecodeInvalidClaimsShouldFail -{ - long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; - - // non facebook issuer - [self assertDecodeClaimsFailWithInvalidEntry:@"iss" - value:@"https://notfacebook.com"]; - - // incorrect audience - [self assertDecodeClaimsFailWithInvalidEntry:@"aud" - value:@"wrong_app_id"]; - - // expired - [self assertDecodeClaimsFailWithInvalidEntry:@"exp" - value:@(currentTime - 60 * 60)]; - - // issued too long ago - [self assertDecodeClaimsFailWithInvalidEntry:@"iat" - value:@(currentTime - 60 * 60)]; - - // incorrect nonce - [self assertDecodeClaimsFailWithInvalidEntry:@"nonce" - value:@"incorrect_nonce"]; - - // invalid user ID - [self assertDecodeClaimsFailWithInvalidEntry:@"sub" - value:nil]; - [self assertDecodeClaimsFailWithInvalidEntry:@"sub" - value:@1234]; - [self assertDecodeClaimsFailWithInvalidEntry:@"sub" - value:@""]; -} - -- (void)testDecodeEmptyClaims -{ - NSDictionary *claims = @{}; - NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:claims options:0 error:nil]; - NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - - XCTAssertNil([FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); -} - -- (void)testDecodeRandomClaims -{ - for (int i = 0; i < 100; i++) { - NSDictionary *randomizedClaims = [self randomizeDictionary:_claims]; - NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:randomizedClaims options:0 error:nil]; - NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - - [FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; - } -} - -// MARK: - Decoding Header - -- (void)testDecodeValidHeaderShouldSucceed -{ - NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; - NSString *encodedHeader = [self base64URLEncodeData:headerData]; - - NSDictionary *header = [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; - XCTAssertEqualObjects(header, _header); -} - -- (void)testDecodeInvalidFormatHeaderShouldFail -{ - NSData *headerData = [@"invalid_header" dataUsingEncoding:NSUTF8StringEncoding]; - NSString *encodedHeader = [self base64URLEncodeData:headerData]; - - XCTAssertNil([FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]); -} - -- (void)testDecodeInvalidHeaderShouldFail -{ - NSMutableDictionary *invalidHeader = [_header mutableCopy]; - [FBSDKTypeUtility dictionary:invalidHeader setObject:@"wrong algorithm" forKey:@"alg"]; - NSData *invalidHeaderData = [FBSDKTypeUtility dataWithJSONObject:invalidHeader options:0 error:nil]; - NSString *encodedHeader = [self base64URLEncodeData:invalidHeaderData]; - - XCTAssertNil([FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]); -} - -- (void)testDecodeEmptyHeader -{ - NSDictionary *header = @{}; - NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:header options:0 error:nil]; - NSString *encodedHeader = [self base64URLEncodeData:headerData]; - - XCTAssertNil([FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]); -} - -- (void)testDecodeRandomHeader -{ - for (int i = 0; i < 100; i++) { - NSDictionary *randomizedHeader = [self randomizeDictionary:_header]; - NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:randomizedHeader options:0 error:nil]; - NSString *encodedHeader = [self base64URLEncodeData:headerData]; - - [FBSDKAuthenticationToken validatedHeaderWithEncodedString:encodedHeader]; - } -} - -// MARK: - Verifying Signature - -- (void)testVerifyValidSignatureShouldSucceed -{ - _token = [FBSDKAuthenticationToken emptyInstance]; - [_token setCertificate:_certificate]; - - XCTAssertTrue( - [_token verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] - ); -} - -- (void)testVerifyInvalidSignatureShouldFail -{ - _token = [FBSDKAuthenticationToken emptyInstance]; - [_token setCertificate:_certificate]; - - NSString *invalidSignature = @"hH0uCpIx0BhjT_djfI52wPMp0sYuHAHYOes4GVasXykHsZAeuidFYshiCd8O-KpAo5m9jZWbXdaSN0JMbpBIJ9TwSk6e8bhX-N6BRKl3EZRby6SsZtK9J2X6mWomgMCfJZD54McLIdDQaTTtNsV1kgzm8iksywaT3f1GdicqlJPZn3m83xF3toSdfKdPoJJCpM7IidPru7gF8aZchkE1d-dUzZ9mV0CPfsl5lX4M64f470nm6PzyynAvyKwUBKO3v3x08V17NV8OkRAjtGPRhbs_d4B6ifEXS3piWUlxVm6w27nPbdmKeCqjV-WRfIJ6lOvumR2F26I1soEwtEWq9g"; - - XCTAssertFalse( - [_token verifySignature:invalidSignature - header:_encodedHeader - claims:_encodedClaims] - ); -} - -- (void)testVerifySignatureWithInvalidCertificateShouldFail -{ - _token = [FBSDKAuthenticationToken emptyInstance]; - [_token setCertificate:@"invalid_certification"]; - - XCTAssertFalse( - [_token verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] - ); -} - // MARK: - Notifications - (void)testPostsNotificationOnSettingInitial { - _token = [FBSDKAuthenticationToken emptyInstance]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]];; FBSDKAuthenticationToken.currentAuthenticationToken = _token; XCTAssertTrue( @@ -354,8 +136,8 @@ - (void)testPostsNotificationOnSettingInitial - (void)testPostsNotificationOnSettingNew { - _token = [FBSDKAuthenticationToken emptyInstance]; - FBSDKAuthenticationToken *token2 = [FBSDKAuthenticationToken emptyInstance]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; + FBSDKAuthenticationToken *token2 = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; FBSDKAuthenticationToken.currentAuthenticationToken = _token; [_notificationCenterSpy clearTestEvidence]; @@ -382,7 +164,7 @@ - (void)testPostsNotificationOnSettingNew - (void)testPostsNotificationOnSettingNil { - _token = [FBSDKAuthenticationToken emptyInstance]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; FBSDKAuthenticationToken.currentAuthenticationToken = _token; [_notificationCenterSpy clearTestEvidence]; @@ -406,66 +188,4 @@ - (void)testPostsNotificationOnSettingNil ); } -// MARK: - Utilities - -- (void)testBase64FromBase64Url -{ - NSString *expectedString = @"testBase64FromBase64Url"; - NSData *data = [expectedString dataUsingEncoding:NSUTF8StringEncoding]; - NSString *base64UrlEncoded = [self base64URLEncodeData:data]; - NSString *base64Encoded = [FBSDKAuthenticationToken base64FromBase64Url:base64UrlEncoded]; - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:base64Encoded], expectedString); - - // test nil - XCTAssertNil([FBSDKAuthenticationToken base64FromBase64Url:nil]); - - // test empty string - XCTAssertEqualObjects([FBSDKAuthenticationToken base64FromBase64Url:@""], @""); -} - -- (NSString *)base64URLEncodeData:(NSData *)data -{ - NSString *base64 = [FBSDKBase64 encodeData:data]; - NSString *base64URL = [base64 stringByReplacingOccurrencesOfString:@"+" withString:@"-"]; - base64URL = [base64URL stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; - return [base64URL stringByReplacingOccurrencesOfString:@"=" withString:@""]; -} - -- (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value -{ - NSMutableDictionary *invalidClaims = [_claims mutableCopy]; - if (value) { - [FBSDKTypeUtility dictionary:invalidClaims setObject:value forKey:key]; - } else { - [invalidClaims removeObjectForKey:key]; - } - - NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:invalidClaims options:0 error:nil]; - NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - - XCTAssertNil([FBSDKAuthenticationToken validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); -} - -- (NSDictionary *)randomizeDictionary:(NSDictionary *)dictionary -{ - NSArray *values = @[@YES, @NO, @1, @0, @-1, @INT32_MAX, @LONG_MAX, @MAXFLOAT, @"1", @"a", @"[ { \"something\": nonexistent } ]"]; - NSMutableDictionary *randomized = [dictionary mutableCopy]; - for (NSString *key in dictionary) { - int randOption = arc4random() % 3; - switch (randOption) { - case 0: - [randomized removeObjectForKey:key]; - break; - case 1: - [FBSDKTypeUtility dictionary:randomized setObject:[FBSDKTypeUtility array:values objectAtIndex:arc4random() % values.count] forKey:key]; - break; - case 2: - default: - break; - } - } - - return randomized; -} - @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 9c7400ce56..5e6672b375 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -47,7 +47,5 @@ @interface FBSDKAuthenticationToken (Testing) - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - signature:(NSString *)signature - claims:(NSDictionary *)claims - header:(NSDictionary *)header; + claims:(NSDictionary *)claims; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m new file mode 100644 index 0000000000..5a71cf0204 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -0,0 +1,321 @@ +// 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 "FBSDKCoreKit+Internal.h" +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" + +static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; + +static NSString *const _encodedHeader = @"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; + +static NSString *const _encodedClaims = @"eyJzdWIiOiIxMjM0IiwibmFtZSI6IlRlc3QgVXNlciIsImlzcyI6Imh0dHBzOi8vZmFjZWJvb2suY29tL2RpYWxvZy9vYXV0aCIsImF1ZCI6IjQzMjEiLCJub25jZSI6InNvbWVfbm9uY2UiLCJleHAiOjE1MTYyNTkwMjIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zb21lX3BpY3R1cmUiLCJpYXQiOjE1MTYyMzkwMjJ9"; + +static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; + +static NSString *const _mockAppID = @"4321"; + +static NSString *const _mockNonce = @"some_nonce"; + +static NSString *const _facebookURL = @"https://facebook.com/dialog/oauth"; + +@interface FBSDKAuthenticationTokenFactory (Testing) + ++ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; ++ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; + +- (void)setCertificate:(NSString *)certificate; + ++ (NSString *)base64FromBase64Url:(NSString *)base64Url; + +- (BOOL)verifySignature:(NSString *)signature + header:(NSString *)header + claims:(NSString *)claims; + +- (NSDictionary *)claims; + +@end + +@interface FBSDKAuthenticationTokenFactoryTests : FBSDKTestCase + +@end + +@implementation FBSDKAuthenticationTokenFactoryTests +{ + NSDictionary *_claims; + NSDictionary *_header; +} + +- (void)setUp +{ + [super setUp]; + + [self stubAppID:_mockAppID]; + + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + _claims = @{ + @"iss" : _facebookURL, + @"aud" : _mockAppID, + @"nonce" : _mockNonce, + @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later + @"iat" : @(currentTime - 60), // 1 min ago + @"sub" : @"1234", + @"name" : @"Test User", + @"email" : @"email@email.com", + @"picture" : @"https://www.facebook.com/some_picture", + }; + + _header = @{ + @"alg" : @"RS256", + @"typ" : @"JWT" + }; +} + +// MARK: - Creation + +- (void)testCreateWithInvalidFormatTokenShouldFail +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + FBSDKAuthenticationTokenBlock completion = ^(FBSDKAuthenticationToken *token) { + XCTAssertNil(token); + [expectation fulfill]; + }; + + [[FBSDKAuthenticationTokenFactory new] createTokenFromTokenString:@"invalid_token" nonce:@"123456789" completion:completion]; + + [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { + XCTAssertNil(error); + }]; +} + +// MARK: - Decoding Claims + +- (void)testDecodeValidClaimsShouldSucceed +{ + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + NSDictionary *claims = [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; + XCTAssertEqualObjects(claims, _claims); +} + +- (void)testDecodeInvalidFormatClaimsShouldFail +{ + NSData *claimsData = [@"invalid_claims" dataUsingEncoding:NSUTF8StringEncoding]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + XCTAssertNil([FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); +} + +- (void)testDecodeInvalidClaimsShouldFail +{ + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + + // non facebook issuer + [self assertDecodeClaimsFailWithInvalidEntry:@"iss" + value:@"https://notfacebook.com"]; + + // incorrect audience + [self assertDecodeClaimsFailWithInvalidEntry:@"aud" + value:@"wrong_app_id"]; + + // expired + [self assertDecodeClaimsFailWithInvalidEntry:@"exp" + value:@(currentTime - 60 * 60)]; + + // issued too long ago + [self assertDecodeClaimsFailWithInvalidEntry:@"iat" + value:@(currentTime - 60 * 60)]; + + // incorrect nonce + [self assertDecodeClaimsFailWithInvalidEntry:@"nonce" + value:@"incorrect_nonce"]; + + // invalid user ID + [self assertDecodeClaimsFailWithInvalidEntry:@"sub" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"sub" + value:@1234]; + [self assertDecodeClaimsFailWithInvalidEntry:@"sub" + value:@""]; +} + +- (void)testDecodeEmptyClaims +{ + NSDictionary *claims = @{}; + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:claims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + XCTAssertNil([FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); +} + +- (void)testDecodeRandomClaims +{ + for (int i = 0; i < 100; i++) { + NSDictionary *randomizedClaims = [self randomizeDictionary:_claims]; + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:randomizedClaims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; + } +} + +// MARK: - Decoding Header + +- (void)testDecodeValidHeaderShouldSucceed +{ + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + NSDictionary *header = [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; + XCTAssertEqualObjects(header, _header); +} + +- (void)testDecodeInvalidFormatHeaderShouldFail +{ + NSData *headerData = [@"invalid_header" dataUsingEncoding:NSUTF8StringEncoding]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); +} + +- (void)testDecodeInvalidHeaderShouldFail +{ + NSMutableDictionary *invalidHeader = [_header mutableCopy]; + [FBSDKTypeUtility dictionary:invalidHeader setObject:@"wrong algorithm" forKey:@"alg"]; + NSData *invalidHeaderData = [FBSDKTypeUtility dataWithJSONObject:invalidHeader options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:invalidHeaderData]; + + XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); +} + +- (void)testDecodeEmptyHeader +{ + NSDictionary *header = @{}; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:header options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); +} + +// MARK: - Verifying Signature + +- (void)testVerifyValidSignatureShouldSucceed +{ + FBSDKAuthenticationTokenFactory *factory = [FBSDKAuthenticationTokenFactory new]; + [factory setCertificate:_certificate]; + + XCTAssertTrue( + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims] + ); +} + +- (void)testVerifyInvalidSignatureShouldFail +{ + FBSDKAuthenticationTokenFactory *factory = [FBSDKAuthenticationTokenFactory new]; + [factory setCertificate:_certificate]; + + NSString *invalidSignature = @"hH0uCpIx0BhjT_djfI52wPMp0sYuHAHYOes4GVasXykHsZAeuidFYshiCd8O-KpAo5m9jZWbXdaSN0JMbpBIJ9TwSk6e8bhX-N6BRKl3EZRby6SsZtK9J2X6mWomgMCfJZD54McLIdDQaTTtNsV1kgzm8iksywaT3f1GdicqlJPZn3m83xF3toSdfKdPoJJCpM7IidPru7gF8aZchkE1d-dUzZ9mV0CPfsl5lX4M64f470nm6PzyynAvyKwUBKO3v3x08V17NV8OkRAjtGPRhbs_d4B6ifEXS3piWUlxVm6w27nPbdmKeCqjV-WRfIJ6lOvumR2F26I1soEwtEWq9g"; + + XCTAssertFalse( + [factory verifySignature:invalidSignature + header:_encodedHeader + claims:_encodedClaims] + ); +} + +- (void)testVerifySignatureWithInvalidCertificateShouldFail +{ + FBSDKAuthenticationTokenFactory *factory = [FBSDKAuthenticationTokenFactory new]; + [factory setCertificate:@"invalid_certification"]; + + XCTAssertFalse( + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims] + ); +} + +// MARK: - Utilities + +- (void)testBase64FromBase64Url +{ + NSString *expectedString = @"testBase64FromBase64Url"; + NSData *data = [expectedString dataUsingEncoding:NSUTF8StringEncoding]; + NSString *base64UrlEncoded = [self base64URLEncodeData:data]; + NSString *base64Encoded = [FBSDKAuthenticationTokenFactory base64FromBase64Url:base64UrlEncoded]; + XCTAssertEqualObjects([FBSDKBase64 decodeAsString:base64Encoded], expectedString); + + // test nil + XCTAssertNil([FBSDKAuthenticationTokenFactory base64FromBase64Url:nil]); + + // test empty string + XCTAssertEqualObjects([FBSDKAuthenticationTokenFactory base64FromBase64Url:@""], @""); +} + +- (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value +{ + NSMutableDictionary *invalidClaims = [_claims mutableCopy]; + if (value) { + [FBSDKTypeUtility dictionary:invalidClaims setObject:value forKey:key]; + } else { + [invalidClaims removeObjectForKey:key]; + } + + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:invalidClaims options:0 error:nil]; + NSString *encodedClaims = [self base64URLEncodeData:claimsData]; + + XCTAssertNil([FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); +} + +- (NSString *)base64URLEncodeData:(NSData *)data +{ + NSString *base64 = [FBSDKBase64 encodeData:data]; + NSString *base64URL = [base64 stringByReplacingOccurrencesOfString:@"+" withString:@"-"]; + base64URL = [base64URL stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; + return [base64URL stringByReplacingOccurrencesOfString:@"=" withString:@""]; +} + +- (NSDictionary *)randomizeDictionary:(NSDictionary *)dictionary +{ + NSArray *values = @[@YES, @NO, @1, @0, @-1, @INT32_MAX, @LONG_MAX, @MAXFLOAT, @"1", @"a", @"[ { \"something\": nonexistent } ]"]; + NSMutableDictionary *randomized = [dictionary mutableCopy]; + for (NSString *key in dictionary) { + int randOption = arc4random() % 3; + switch (randOption) { + case 0: + [randomized removeObjectForKey:key]; + break; + case 1: + [FBSDKTypeUtility dictionary:randomized setObject:[FBSDKTypeUtility array:values objectAtIndex:arc4random() % values.count] forKey:key]; + break; + case 2: + default: + break; + } + } + + return randomized; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift index 49b354412d..e239995602 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift @@ -23,9 +23,7 @@ public class SampleAuthenticationToken: NSObject { return AuthenticationToken( tokenString: "fakeTokenString", nonce: "fakeNonce", - signature: "fakeSignature", - claims: [:], - header: [:] + claims: [:] ) } diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index d469422723..c4d0ac8b12 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -590,8 +590,7 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl if (isFacebookURL) { NSDictionary *urlParameters = [FBSDKLoginUtility queryParamsFromLoginURL:url]; id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:urlParameters - appID:[FBSDKSettings appID] - nonce:[self loadExpectedNonce]]; + appID:[FBSDKSettings appID]]; if (_logger == nil) { _logger = [FBSDKLoginManagerLogger loggerFromParameters:urlParameters]; @@ -599,8 +598,8 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl // any necessary strong reference is maintained by the FBSDKLoginURLCompleter handler [completer completeLoginWithHandler:^(FBSDKLoginCompletionParameters *parameters) { - [self completeAuthentication:parameters expectChallenge:YES]; - }]; + [self completeAuthentication:parameters expectChallenge:YES]; + } nonce:[self loadExpectedNonce]]; } return isFacebookURL; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h index 1ce89f7fc9..4fdf144557 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h @@ -26,6 +26,7 @@ @property (nonatomic, copy) NSString *accessTokenString; @property (nonatomic, copy) NSString *nonceString; +@property (nonatomic, copy) NSString *idTokenString; @property (nonatomic, copy) NSSet *permissions; @property (nonatomic, copy) NSSet *declinedPermissions; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h index 17dbe8008c..ef63296153 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h @@ -44,6 +44,7 @@ NS_SWIFT_NAME(LoginCompletionParameters) @property (nonatomic, copy, readonly) NSString *accessTokenString; @property (nonatomic, copy, readonly) NSString *nonceString; +@property (nonatomic, copy, readonly) NSString *idTokenString; @property (nonatomic, copy, readonly) NSSet *permissions; @property (nonatomic, copy, readonly) NSSet *declinedPermissions; @@ -71,6 +72,13 @@ NS_SWIFT_NAME(LoginCompleting) */ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler; +/** + Invoke \p handler with the login parameters derived from the authentication result. + See the implementing class's documentation for whether it completes synchronously or asynchronously. + */ +- (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler + nonce:(NSString *)nonce; + @end #pragma mark - Completers @@ -90,7 +98,6 @@ NS_SWIFT_NAME(LoginURLCompleter) - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID; -- (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID nonce:(NSString *)nonce NS_DESIGNATED_INITIALIZER; @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 3c2aabbcf2..8ee39baeaf 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -128,28 +128,14 @@ @implementation FBSDKLoginURLCompleter - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID -{ - return [self initWithURLParameters:parameters appID:appID nonce:nil]; -} - -- (instancetype)initWithURLParameters:(NSDictionary *)parameters - appID:(NSString *)appID - nonce:(NSString *)nonce { if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; - FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:parameters[@"id_token"] nonce:nonce]; - if ([parameters[@"access_token"] length] > 0 || [parameters[@"nonce"] length] > 0 - || token) { + || [parameters[@"id_token"] length] > 0) { [self setParametersWithDictionary:parameters appID:appID]; - - if (token) { - FBSDKProfile.currentProfile = [FBSDKLoginURLCompleter createProfileWithToken:token]; - [FBSDKAuthenticationToken setCurrentAuthenticationToken:token]; - } } else { [self setErrorWithDictionary:parameters]; } @@ -158,10 +144,28 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters } - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler +{ + [self completeLoginWithHandler:handler nonce:nil]; +} + +- (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler + nonce:(NSString *)nonce { if (_parameters.nonceString) { [self exchangeNonceForTokenWithHandler:handler]; return; + } else if (_parameters.idTokenString && nonce) { + FBSDKAuthenticationTokenBlock completion = ^(FBSDKAuthenticationToken *token) { + if (token) { + [FBSDKAuthenticationToken setCurrentAuthenticationToken:token]; + FBSDKProfile.currentProfile = [FBSDKLoginURLCompleter createProfileWithToken:token]; + } else { + self->_parameters.error = [FBSDKError errorWithCode:FBSDKLoginErrorInvalidIDToken message:@"Invalid ID token from login response."]; + } + handler(self->_parameters); + }; + [[FBSDKAuthenticationTokenFactory new] createTokenFromTokenString:_parameters.idTokenString nonce:nonce completion:completion]; + return; } else if (_parameters.accessTokenString && !_parameters.userID) { void (^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; FBSDKLoginRequestMeAndPermissions(_parameters, ^{ @@ -183,6 +187,7 @@ - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString * _parameters.accessTokenString = parameters[@"access_token"]; _parameters.nonceString = parameters[@"nonce"]; + _parameters.idTokenString = parameters[@"id_token"]; // check the string length so that we assign an empty set rather than a set with an empty string _parameters.permissions = (grantedPermissionsString.length > 0) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m index 1e48c07b07..21588573f8 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m @@ -164,8 +164,6 @@ + (NSError *)fbErrorFromReturnURLParameters:(NSDictionary *)parameters error = [NSError errorWithDomain:FBSDKErrorDomain code:FBSDKErrorGraphRequestGraphAPI userInfo:userInfo]; - } else if (parameters[@"id_token"]) { - error = [FBSDKError errorWithCode:FBSDKLoginErrorInvalidIDToken message:@"Invalid ID token from login response."]; } return error; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 48462f204b..1da1a499fd 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -43,7 +43,7 @@ - (void)storeExpectedNonce:(NSString *)nonceExpected keychainStore:(FBSDKKeychai @end -@interface FBSDKAuthenticationToken (Testing) +@interface FBSDKAuthenticationTokenFactory (Testing) + (void)setSkipSignatureVerification:(BOOL)value; @@ -313,7 +313,7 @@ - (void)testOpenURLAuthWithIDToken { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; FBSDKLoginManager *target = _mockLoginManager; - [FBSDKAuthenticationToken setSkipSignatureVerification:YES]; + [FBSDKAuthenticationTokenFactory setSkipSignatureVerification:YES]; long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; NSDictionary *expectedClaims = @{ @@ -361,7 +361,7 @@ - (void)testOpenURLAuthWithIDToken XCTAssertNil(error); }]; - [FBSDKAuthenticationToken setSkipSignatureVerification:NO]; + [FBSDKAuthenticationTokenFactory setSkipSignatureVerification:NO]; } - (void)testOpenURLAuthWithInvalidIDToken From 4499e956378cea37bb19c297fd5793ddac9a8566 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 7 Dec 2020 18:58:45 -0800 Subject: [PATCH 155/227] Clear the stored expected nonce when creating AuthenticationToken Summary: Clear the stored expected nonce from keychain store once it is used. Reviewed By: robtimp Differential Revision: D25382371 fbshipit-source-id: c0b830a71f5a3292f26bfebe4404cc7849e2b3a3 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 1 + FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index c4d0ac8b12..13c59b67c5 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -600,6 +600,7 @@ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceAppl [completer completeLoginWithHandler:^(FBSDKLoginCompletionParameters *parameters) { [self completeAuthentication:parameters expectChallenge:YES]; } nonce:[self loadExpectedNonce]]; + [self storeExpectedNonce:nil keychainStore:_keychainStore]; } return isFacebookURL; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 1da1a499fd..43809643d8 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -529,8 +529,10 @@ - (void)testStoreExpectedNonce FBSDKKeychainStore *keychainStore = [[FBSDKKeychainStore alloc] initWithService:self.name accessGroup:nil]; [_mockLoginManager storeExpectedNonce:@"some_nonce" keychainStore:keychainStore]; - XCTAssertEqualObjects([keychainStore stringForKey:@"expected_login_nonce"], @"some_nonce"); + + [_mockLoginManager storeExpectedNonce:nil keychainStore:keychainStore]; + XCTAssertNil([keychainStore stringForKey:@"expected_login_nonce"]); } - (void)validateCommonLoginParameters:(NSDictionary *)params From 93df9c66e48b3ee5a763f398b0c87151420c536a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 8 Dec 2020 08:32:57 -0800 Subject: [PATCH 156/227] Fix SPM header import Summary: $title Reviewed By: tianqibt Differential Revision: D25389972 fbshipit-source-id: 08c9fbac527798e114f9a8ec5d8947a987c3dd93 --- .../FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h index 6ba54ce113..633da6eae1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.h @@ -19,7 +19,7 @@ #import #if SWIFT_PACKAGE - #import "FBSDKAuthenticationToken" + #import "FBSDKAuthenticationToken.h" #else #import #endif From ec57dc0066a434542267c83280876dbccc72048d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 8 Dec 2020 10:35:48 -0800 Subject: [PATCH 157/227] Add back support for OIDC Summary: This is reverting the changes in D25343842 (https://github.com/facebook/facebook-ios-sdk/commit/ad23c6857e2bfbe2731972bddd5babf38619da0d) and testing with a matrix of users and app ids to make sure we didn't regress. It also comments out token signature verification since non-beta login will fail if the check for a valid auth token fails. Reviewed By: ppansy Differential Revision: D25398811 fbshipit-source-id: 1b8a29eda26522caf83fd081369b3ac34fbb0a49 --- .../Internal/FBSDKAuthenticationTokenFactory.m | 13 +++++++------ FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 9 ++------- .../FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 12 +++--------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m index 13715080f9..89d5f28bce 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -83,12 +83,13 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString return; } - if (![self verifySignature:signature - header:encodedHeader - claims:encodedClaims]) { - completion(nil); - return; - } + // TODO: Add back when signatures can be consistently verified - T81105008 + // if (![self verifySignature:signature + // header:encodedHeader + // claims:encodedClaims]) { + // completion(nil); + // return; + // } FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc]initWithTokenString:tokenString nonce:nonce claims:claims]; completion(token); diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 13c59b67c5..8b96dc828f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -353,10 +353,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0 forKey:@"ies"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings appURLSchemeSuffix] forKey:@"local_client_id"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKLoginUtility stringForAudience:self.defaultAudience] forKey:@"default_audience"]; - - // TODO: Re-implement when server issue resolved - T80884847 - // [configuration.requestedPermissions setByAddingObject:@"openid"]; - NSSet *permissions = configuration.requestedPermissions; + NSSet *permissions = [configuration.requestedPermissions setByAddingObject:@"openid"]; [FBSDKTypeUtility dictionary:loginParams setObject:[permissions.allObjects componentsJoinedByString:@","] forKey:@"scope"]; NSString *expectedChallenge = [FBSDKLoginManager stringForChallenge]; @@ -368,9 +365,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { responseType = @"id_token"; } else { - // TODO: Re-implement when server issue resolved - T80884847 - // responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; - responseType = @"token_or_nonce,signed_request,graph_domain"; + responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; } [FBSDKTypeUtility dictionary:loginParams setObject:responseType forKey:@"response_type"]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 43809643d8..11cf82237e 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -438,12 +438,8 @@ - (void)testBetaLoginExperienceEnabledLoginParams NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:config serverConfiguration:nil]; [self validateCommonLoginParameters:params]; - // TODO: Re-implement when server issue resolved - T80884847 - // XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); - XCTAssertEqualObjects(params[@"response_type"], @"token_or_nonce,signed_request,graph_domain"); - // TODO: Re-implement when server issue resolved - T80884847 - // XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); - XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); + XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertNotNil(params[@"nonce"]); } @@ -457,9 +453,7 @@ - (void)testBetaLoginExperienceRestrictedLoginParams NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:config serverConfiguration:nil]; [self validateCommonLoginParameters:params]; XCTAssertEqualObjects(params[@"response_type"], @"id_token"); - // TODO: Re-implement when server issue resolved - T80884847 - // XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); - XCTAssertEqualObjects(params[@"scope"], @"public_profile,email"); + XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); } From 9e681c47761bfbde739a0861a276354349ece46f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 8 Dec 2020 11:49:51 -0800 Subject: [PATCH 158/227] Login button Updates Summary: Integrates profile changes with login button. `FBSDKLoginButton` was solely depending on `FBSDKAccessToken` as a proxy for authentication but now it also looks at `FBSDKAuthenticationToken` since this with OICD this is a valid means of determining whether a login attempt was successful. Also adds support for responding to profile notifications. This creates an obvious issue because now we have a race condition between `Profile` and `AccessToken` notifications. This means we might wind up with an extra fetch if we handle the profile notification (which doesn't trigger a fetch) and then handle get the access token notification which does trigger a fetch. However, sometimes this is what we want since the information fetched by handling the access token might be more current than that of the current profile (which might be served from an old cache). So to solve this we could do a number of things: a) Write a bunch of delayed dispatches and locks to wait until we've received both token and then handle use the right one using the datestamps on each. b) Write some intermediate object that handles all of this outside of the button and dispatches a single notification to the button. c) Hold onto a potential fetch task so we can cancel if it we get a profile notification with a recently refreshed profile. I'm fairly sure that each of these will also cause their own edge cases so it's probably better to occasionally perform a needless fetch in order to keep everything easier to reason about. Reviewed By: ppansy Differential Revision: D25292523 fbshipit-source-id: 198725a66c2b15c1e77cc34dbfa428ab709d06f0 --- .../FBSDKCoreKit/FBSDKAuthenticationToken.h | 4 +- .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 14 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 15 +- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 16 +- .../FBSDKLoginKit/FBSDKLoginButton.m | 148 +++++-- .../FBSDKLoginKitTests-Bridging-Header.h | 33 ++ .../FBSDKLoginKitTests/LoginButtonTests.swift | 393 ++++++++++++++++++ .../SampleAccessToken.swift | 50 +++ 8 files changed, 633 insertions(+), 40 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/SampleAccessToken.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h index 5929fdd218..22ce95e2ba 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h @@ -30,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN `FBSDKAuthenticationTokenChangeNewKey`. */ FOUNDATION_EXPORT NSNotificationName const FBSDKAuthenticationTokenDidChangeNotification -NS_SWIFT_NAME(AuthenticationTokenDidChange); +NS_SWIFT_NAME(authenticationTokenDidChange); #else @@ -42,7 +42,7 @@ NS_SWIFT_NAME(AuthenticationTokenDidChange); `FBSDKAuthenticationTokenChangeNewKey`. */ FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenDidChangeNotification -NS_SWIFT_NAME(AuthenticationTokenDidChange); +NS_SWIFT_NAME(authenticationTokenDidChange); #endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index 1a6642f00b..a6a0227ed0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -64,6 +64,12 @@ + (FBSDKAuthenticationToken *)currentAuthenticationToken } + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token +{ + [self setCurrentAuthenticationToken:token shouldPostNotification:YES]; +} + ++ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token + shouldPostNotification:(BOOL)shouldPostNotification { if (token != g_currentAuthenticationToken) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; @@ -73,9 +79,11 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token g_currentAuthenticationToken = token; [[self tokenCache] setAuthenticationToken:token]; - [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAuthenticationTokenDidChangeNotification - object:[self class] - userInfo:userInfo]; + if (shouldPostNotification) { + [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAuthenticationTokenDidChangeNotification + object:[self class] + userInfo:userInfo]; + } } } diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index 838bf9401d..05323152a2 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -101,6 +101,12 @@ + (FBSDKProfile *)currentProfile } + (void)setCurrentProfile:(FBSDKProfile *)profile +{ + [self setCurrentProfile:profile shouldPostNotification:YES]; +} + ++ (void)setCurrentProfile:(nullable FBSDKProfile *)profile + shouldPostNotification:(BOOL)shouldPostNotification { if (profile != g_currentProfile && ![profile isEqualToProfile:g_currentProfile]) { [[self class] cacheProfile:profile]; @@ -109,9 +115,12 @@ + (void)setCurrentProfile:(FBSDKProfile *)profile [FBSDKTypeUtility dictionary:userInfo setObject:profile forKey:FBSDKProfileChangeNewKey]; [FBSDKTypeUtility dictionary:userInfo setObject:g_currentProfile forKey:FBSDKProfileChangeOldKey]; g_currentProfile = profile; - [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKProfileDidChangeNotification - object:[self class] - userInfo:userInfo]; + + if (shouldPostNotification) { + [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKProfileDidChangeNotification + object:[self class] + userInfo:userInfo]; + } } } diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 591818b872..624d4e01b2 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -148,6 +148,7 @@ C6CE2BC424EB73CF00CF2EB6 /* FBSDKReferralManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C6CE2BBE24EB72F200CF2EB6 /* FBSDKReferralManager.m */; }; C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */; }; C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */; }; + F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40BFD55257852E5007B85AC /* LoginButtonTests.swift */; }; F462DC0E23B958E000FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC0F23B958E100FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F462DC1023B95BA600FFCECA /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */; }; @@ -162,6 +163,7 @@ F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA659245347570060C902 /* FBLoginButton.swift */; }; F46FA65D245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; F46FA65E245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; + F46FE68B2579764F000F4F53 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */; }; F4AA32822574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; F4AA32832574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */; }; @@ -394,6 +396,7 @@ C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCodeTests.m; sourceTree = ""; }; C6E63D2224F8219A0015FC7C /* FBSDKReferralManagerLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerLogger.h; sourceTree = ""; }; C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerLogger.m; sourceTree = ""; }; + F40BFD55257852E5007B85AC /* LoginButtonTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginButtonTests.swift; sourceTree = ""; }; F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKLoginKitTests-Bridging-Header.h"; sourceTree = ""; }; F4647478256AEF8E00502449 /* NonceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonceTests.swift; sourceTree = ""; }; F464748E256B031600502449 /* FBSDKLoginConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginConfiguration.m; sourceTree = ""; }; @@ -401,6 +404,7 @@ F464749B256B048500502449 /* LoginConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginConfigurationTests.swift; sourceTree = ""; }; F46FA659245347570060C902 /* FBLoginButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBLoginButton.swift; sourceTree = ""; }; F46FA65C245347820060C902 /* LoginManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginManager.swift; sourceTree = ""; }; + F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; F4AA32812574448C005EDF04 /* LoginConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginConfiguration.swift; sourceTree = ""; }; F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKNonceUtility.h; sourceTree = ""; }; F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKNonceUtility.m; sourceTree = ""; }; @@ -660,15 +664,17 @@ 9D9DB8E81A114E500086167B /* FBSDKLoginKitTests */ = { isa = PBXGroup; children = ( - C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */, + F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */, + 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */, 6B6276321A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.h */, 6B6276331A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m */, - 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */, - 9D9DB8E91A114E500086167B /* Supporting Files */, C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */, - F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */, + C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */, + F40BFD55257852E5007B85AC /* LoginButtonTests.swift */, F464749B256B048500502449 /* LoginConfigurationTests.swift */, F4647478256AEF8E00502449 /* NonceTests.swift */, + 9D9DB8E91A114E500086167B /* Supporting Files */, + F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -1187,7 +1193,9 @@ F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, + F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, + F46FE68B2579764F000F4F53 /* SampleAccessToken.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index 2085f36c04..04c88c9be3 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -52,7 +52,7 @@ @implementation FBSDKLoginButton - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self _unsubscribeFromNotifications]; } #pragma mark - Properties @@ -67,6 +67,12 @@ - (void)setDefaultAudience:(FBSDKDefaultAudience)defaultAudience _loginManager.defaultAudience = defaultAudience; } +- (void)setBetaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +{ + _betaLoginExperience = betaLoginExperience; + [self _updateNotificationObservers]; +} + - (UIFont *)defaultFont { CGFloat size = 15; @@ -84,6 +90,8 @@ - (void)setNonce:(NSString *)nonce _nonce = nonce; } else { _nonce = nil; + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + formatString:@"Unable to set invalid nonce: %@ on FBSDKLoginButton", nonce]; } } @@ -195,28 +203,48 @@ - (void)configureButton attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:kButtonHeight]]; - [self _updateContent]; + [self _initializeContent]; [self addTarget:self action:@selector(_buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; + + [self _updateNotificationObservers]; +} + + #pragma mark - Helper Methods + +- (void)_unsubscribeFromNotifications +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)_updateNotificationObservers +{ + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_profileDidChangeNotification:) + name:FBSDKProfileDidChangeNotification + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessTokenDidChangeNotification:) name:FBSDKAccessTokenDidChangeNotification object:nil]; } - #pragma mark - Helper Methods - - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { if (notification.userInfo[FBSDKAccessTokenDidChangeUserIDKey] || notification.userInfo[FBSDKAccessTokenDidExpireKey]) { - [self _updateContent]; + [self _updateContentForAccessToken]; } } +- (void)_profileDidChangeNotification:(NSNotification *)notification +{ + [self _updateContentForUserProfile:FBSDKProfile.currentProfile]; +} + - (void)_buttonPressed:(id)sender { [self logTapEventWithEventName:FBSDKAppEventNameFBSDKLoginButtonDidTap parameters:self.analyticsParameters]; - if (FBSDKAccessToken.isCurrentAccessTokenActive || FBSDKProfile.currentProfile) { + if (self._isAuthenticated) { NSString *title = nil; if (_userName) { @@ -289,21 +317,26 @@ - (void)_buttonPressed:(id)sender } }; - FBSDKLoginConfiguration *loginConfig; - if (self.nonce) { - loginConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions - betaLoginExperience:self.betaLoginExperience - nonce:self.nonce]; - } else { - loginConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions - betaLoginExperience:self.betaLoginExperience]; - } + FBSDKLoginConfiguration *loginConfig = [self loginConfiguration]; + [_loginManager logInFromViewController:[FBSDKInternalUtility viewControllerForView:self] configuration:loginConfig completion:handler]; } } +- (FBSDKLoginConfiguration *)loginConfiguration +{ + if (self.nonce) { + return [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions + betaLoginExperience:self.betaLoginExperience + nonce:self.nonce]; + } else { + return [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions + betaLoginExperience:self.betaLoginExperience]; + } +} + - (NSString *)_logOutTitle { return NSLocalizedStringWithDefaultValue( @@ -339,7 +372,7 @@ - (NSString *)_shortLogInTitle - (void)_showTooltipIfNeeded { - if ([FBSDKAccessToken currentAccessToken] || self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorDisable) { + if (self._isAuthenticated || self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorDisable) { return; } else { FBSDKLoginTooltipView *tooltipView = [[FBSDKLoginTooltipView alloc] init]; @@ -351,26 +384,85 @@ - (void)_showTooltipIfNeeded } } -- (void)_updateContent +// On initial setting of button state. We want to update the button's user +// information using the most comprehensive available. +// If access token is available use that. +// If only profile is available, use that. +- (void)_initializeContent +{ + FBSDKAccessToken *accessToken = FBSDKAccessToken.currentAccessToken; + FBSDKProfile *profile = FBSDKProfile.currentProfile; + + if (accessToken) { + [self _updateContentForAccessToken]; + } else if (profile) { + [self _updateContentForUserProfile:profile]; + } else { + self.selected = NO; + } +} + +- (void)_updateContentForAccessToken { BOOL accessTokenIsValid = FBSDKAccessToken.isCurrentAccessTokenActive; self.selected = accessTokenIsValid; if (accessTokenIsValid) { - if (![[FBSDKAccessToken currentAccessToken].userID isEqualToString:_userID]) { - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me?fields=id,name" - parameters:nil - flags:FBSDKGraphRequestFlagDisableErrorRecovery]; - [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { - NSString *userID = [FBSDKTypeUtility stringValue:result[@"id"]]; - if (!error && [[FBSDKAccessToken currentAccessToken].userID isEqualToString:userID]) { - self->_userName = [FBSDKTypeUtility stringValue:result[@"name"]]; - self->_userID = userID; - } - }]; + if (![FBSDKAccessToken.currentAccessToken.userID isEqualToString:_userID]) { + [self _fetchAndSetContent]; } } } +- (void)_fetchAndSetContent +{ + FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me?fields=id,name" + parameters:nil + flags:FBSDKGraphRequestFlagDisableErrorRecovery]; + [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { + NSString *userID = [FBSDKTypeUtility stringValue:result[@"id"]]; + if (!error && [FBSDKAccessToken.currentAccessToken.userID isEqualToString:userID]) { + self->_userName = [FBSDKTypeUtility stringValue:result[@"name"]]; + self->_userID = userID; + } + }]; +} + +- (void)_updateContentForUserProfile:(FBSDKProfile *)profile +{ + self.selected = profile != nil; + + if (profile && [self _userInformationDoesNotMatchProfile:profile]) { + _userName = profile.name; + _userID = profile.userID; + } +} + +- (BOOL)_userInformationDoesNotMatchProfile:(FBSDKProfile *)profile +{ + return (profile.userID != _userID) || (profile.name != _userName); +} + +- (BOOL)_isAuthenticated +{ + return (FBSDKAccessToken.currentAccessToken || FBSDKAuthenticationToken.currentAuthenticationToken); +} + +// MARK: - Testability + + #if DEBUG + +- (NSString *)userName +{ + return _userName; +} + +- (NSString *)userID +{ + return _userID; +} + + #endif + @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h index c2adc2e24f..51cbc1dc6a 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -20,3 +20,36 @@ #import "FBSDKLoginConfiguration.h" #import "FBSDKNonceUtility.h" + +// Categories needed to expose private methods to Swift + +@interface FBSDKLoginButton (Testing) +- (FBSDKLoginConfiguration *)loginConfiguration; +- (BOOL)_isAuthenticated; +- (void)_fetchAndSetContent; +- (void)_initializeContent; +- (void)_updateContentForAccessToken; +- (void)_updateContentForUserProfile:(FBSDKProfile *)profile; +- (void)_accessTokenDidChangeNotification:(NSNotification *)notification; +- (void)_profileDidChangeNotification:(NSNotification *)notification; +- (NSString *)userName; +- (NSString *)userID; +@end + +@interface FBSDKAccessToken (Testing) ++ (void)setCurrentAccessToken:(FBSDKAccessToken *)token + shouldDispatchNotif:(BOOL)shouldDispatchNotif; +@end + +@interface FBSDKProfile (Testing) ++ (void)setCurrentProfile:(nullable FBSDKProfile *)profile + shouldPostNotification:(BOOL)shouldPostNotification; +@end + +@interface FBSDKAuthenticationToken (Testing) +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + claims:(NSDictionary *)claims; ++ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token + shouldPostNotification:(BOOL)shouldPostNotification; +@end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift new file mode 100644 index 0000000000..3899096eeb --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift @@ -0,0 +1,393 @@ +// 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 FBSDKCoreKit +import XCTest + +class LoginButtonTests: XCTestCase { + + let validNonce: NSString = "abc123" + var button: FBLoginButton! // swiftlint:disable:this force_unwrapping + var sampleProfile: Profile { + return Profile( + userID: "Sample ID", + firstName: nil, + middleName: nil, + lastName: nil, + name: "Sample Name", + linkURL: nil, + refreshDate: nil + ) + } + + override func setUp() { + super.setUp() + + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + AuthenticationToken.setCurrent(nil, shouldPostNotification: false) + Profile.current = nil + + button = FBLoginButton() + } + + func testDefaultNonce() { + XCTAssertNil(FBLoginButton().nonce, "Should not have a default nonce") + } + + func testSettingInvalidNonce() { + button.nonce = " " + + XCTAssertNil( + button.nonce, + "Should not set an invalid nonce" + ) + } + + func testSettingValidNonce() { + button.nonce = validNonce + + XCTAssertEqual( + button.nonce, + validNonce, + "Should set a valid nonce" + ) + } + + func testLoginConfigurationWithoutNonce() { + XCTAssertNotNil( + button.loginConfiguration(), + "Should be able to create a login configuration without a provided nonce" + ) + } + + func testLoginConfigurationWithInvalidNonce() { + button.nonce = " " + + XCTAssertNotNil( + button.loginConfiguration(), + "Should not create a login configuration with an invalid nonce" + ) + } + + // MARK: - Initial Content Update + + func testInitialContentUpdateWithInactiveAccessTokenWithProfile() { + let button = TestButton() + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + Profile.setCurrent(sampleProfile, shouldPostNotification: false) + + button._initializeContent() + + XCTAssertEqual( + button.updateContentForProfileCallCount, + 1, + "Should use the profile when there is no access token" + ) + XCTAssertEqual( + button.updateContentForAccessTokenCallCount, + 0, + "Should not use the access token when there is no access token" + ) + } + + func testInitialContentUpdateWithActiveAccessTokenWithProfile() { + let button = TestButton() + AccessToken.setCurrent(SampleAccessToken.validToken, shouldDispatchNotif: false) + let profile = Profile( + userID: "Sample ID", + firstName: nil, + middleName: nil, + lastName: nil, + name: "Sample Name", + linkURL: nil, + refreshDate: nil + ) + Profile.setCurrent(profile, shouldPostNotification: false) + + button._initializeContent() + + XCTAssertEqual( + button.updateContentForProfileCallCount, + 0, + "Should not use the profile when there is an access token" + ) + XCTAssertEqual( + button.updateContentForAccessTokenCallCount, + 1, + "Should use the access token when there is one available" + ) + } + + func testInitialContentUpdateWithoutAccessTokenWithoutProfile() { + let button = TestButton() + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + Profile.setCurrent(nil, shouldPostNotification: false); + + button._initializeContent() + + XCTAssertEqual( + button.updateContentForProfileCallCount, + 0, + "Should not use the profile when there is no access token or current profile" + ) + XCTAssertEqual( + button.updateContentForAccessTokenCallCount, + 0, + "Should not use the access token when there is no access token or current profile" + ) + XCTAssertFalse( + button.isSelected, + "Should not be selected when there is no access token or current profile" + ) + } + + // MARK: - Determining Authentication Status + + func testDeterminingAuthenticationWithAccessTokenWithoutAuthToken() { + AccessToken.setCurrent(SampleAccessToken.validToken, shouldDispatchNotif: false) + + XCTAssertTrue( + button._isAuthenticated(), + "Should consider a user authenticated if they have a current access token" + ) + } + + func testDeterminingAuthenticationWithoutAccessTokenWithAuthToken() { + let authToken = AuthenticationToken(tokenString: "abc", nonce: "123", claims: [:]) + AuthenticationToken.setCurrent(authToken, shouldPostNotification: false) + + XCTAssertTrue( + button._isAuthenticated(), + "Should consider a user authenticated if they have a current authentication token" + ) + } + + // MARK: - Handling Notifications + + func testReceivingAccessTokenNotificationWithDidChangeUserIdKey() { + let button = TestButton() + let notification = Notification( + name: .AccessTokenDidChange, + object: nil, + userInfo: [AccessTokenDidChangeUserIDKey: "foo"] + ) + + button._accessTokenDidChange(notification) + + XCTAssertEqual( + button.updateContentForAccessTokenCallCount, + 1, + "An access token notification with a changed user id key should trigger a content update" + ) + } + + func testReceivingAccessTokenNotificationWithTokenDidExpireKey() { + let button = TestButton() + let notification = Notification( + name: .AccessTokenDidChange, + object: nil, + userInfo: [AccessTokenDidExpireKey: "foo"] + ) + + button._accessTokenDidChange(notification) + + XCTAssertEqual( + button.updateContentForAccessTokenCallCount, + 1, + "An access token notification with an expired token key should trigger a content update" + ) + } + + func testReceivingAccessTokenNotificationWithoutRelevantUserInfo() { + let button = TestButton() + let notification = Notification( + name: .AccessTokenDidChange, + object: nil, + userInfo: nil + ) + + button._accessTokenDidChange(notification) + + XCTAssertEqual( + button.updateContentForAccessTokenCallCount, + 0, + "An access token notification without relevant user info should not trigger a content update" + ) + } + + func testReceivingProfileNotification() { + let button = TestButton() + let notification = Notification( + name: .ProfileDidChange, + object: nil, + userInfo: nil + ) + + button._profileDidChange(notification) + + XCTAssertEqual( + button.updateContentForProfileCallCount, + 1, + "An profile change should trigger a content update" + ) + } + + // MARK: - Updating Content + + func testUpdatingContentWithMissingProfile() { + button._updateContent(forUserProfile: nil) + + XCTAssertFalse( + button.isSelected, + "Should not be selected if there is not a profile" + ) + XCTAssertNil(button.userName()) + XCTAssertNil(button.userID()) + } + + func testUpdatingContentWithProfile() { + button._updateContent(forUserProfile: sampleProfile) + + XCTAssertTrue( + button.isSelected, + "Should be selected if there is a valid profile" + ) + XCTAssertEqual(button.userName(), sampleProfile.name) + XCTAssertEqual(button.userID(), sampleProfile.userID) + } + + func testUpdatingContentForProfileWithNewId() { + let button = TestButton() + let profile = sampleProfile(userID: name) + button._updateContent(forUserProfile: sampleProfile) + button._updateContent(forUserProfile: profile) + + XCTAssertEqual( + button.userName(), + profile.name, + "Should update the user information with the updated profile information" + ) + XCTAssertEqual( + button.userID(), + profile.userID, + "Should update the user information with the updated profile information" + ) + } + + func testUpdatingContentForProfileWithNewName() { + let button = TestButton() + let profile = sampleProfile(name: name) + button._updateContent(forUserProfile: sampleProfile) + button._updateContent(forUserProfile: profile) + + XCTAssertEqual( + button.userName(), + profile.name, + "Should update the user information with the updated profile information" + ) + XCTAssertEqual( + button.userID(), + profile.userID, + "Should update the user information with the updated profile information" + ) + } + + func testUpdatingContentWithValidAccessToken() { + let button = TestButton() + AccessToken.setCurrent(SampleAccessToken.validToken, shouldDispatchNotif: false) + + button._updateContentForAccessToken() + + XCTAssertEqual( + button.fetchAndSetContentCallCount, + 1, + "Should try to fetch content for a valid access token" + ) + } + + func testUpdatingContentWithInvalidAccessToken() { + let button = TestButton() + AccessToken.setCurrent(SampleAccessToken.expiredToken, shouldDispatchNotif: false) + + button._updateContentForAccessToken() + button._updateContentForAccessToken() + + XCTAssertEqual( + button.fetchAndSetContentCallCount, + 0, + "Should not try to fetch content for an invalid access token" + ) + } + + func testUpdatingContentWithIdenticalAccessToken() { + let button = TestButton() + + // Make sure the username and id properties on button are set to the same values + // as the access token. This is an easy way to do with without having to stub + // a network call + let profile = sampleProfile(userID: SampleAccessToken.validToken.userID) + button._updateContent(forUserProfile: profile) + + AccessToken.setCurrent(SampleAccessToken.validToken, shouldDispatchNotif: false) + + button._updateContentForAccessToken() + + XCTAssertEqual( + button.fetchAndSetContentCallCount, + 0, + "Should not try to fetch content for a token if the user identifier has not changed" + ) + } + + private func sampleProfile( + userID: String = "Sample ID", + name: String = "Sample Name" + ) -> Profile { + return Profile( + userID: userID, + firstName: nil, + middleName: nil, + lastName: nil, + name: name, + linkURL: nil, + refreshDate: nil + ) + } +} + +private class TestButton: FBLoginButton { + var fetchAndSetContentCallCount = 0 + var updateContentForAccessTokenCallCount = 0 + var updateContentForProfileCallCount = 0 + + override func _updateContentForAccessToken() { + updateContentForAccessTokenCallCount += 1 + + super._updateContentForAccessToken() + } + + override func _updateContent(forUserProfile profile: Profile!) { + updateContentForProfileCallCount += 1 + + super._updateContent(forUserProfile: profile) + } + + override func _fetchAndSetContent() { + fetchAndSetContentCallCount += 1 + } +} diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/SampleAccessToken.swift b/FBSDKLoginKit/FBSDKLoginKitTests/SampleAccessToken.swift new file mode 100644 index 0000000000..f7a6b8e153 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/SampleAccessToken.swift @@ -0,0 +1,50 @@ +// 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. + +@objcMembers +public class SampleAccessToken: NSObject { + + public static var validToken: AccessToken { + return AccessToken( + tokenString: "123", + permissions: [], + declinedPermissions: [], + expiredPermissions: [], + appID: "123", + userID: "user123", + expirationDate: nil, + refreshDate: nil, + dataAccessExpirationDate: nil + ) + } + + public static var expiredToken: AccessToken { + return AccessToken( + tokenString: "123", + permissions: [], + declinedPermissions: [], + expiredPermissions: [], + appID: "123", + userID: "user123", + expirationDate: .distantPast, + refreshDate: nil, + dataAccessExpirationDate: nil + ) + } + +} From c53961bf180ff65b0e07bc4018536e19b5b6db3a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 8 Dec 2020 11:51:14 -0800 Subject: [PATCH 159/227] Update Reauthorization Summary: Updating the `reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler` method to return early with an error if there is no current `AccessToken`. If there is no access token then reauthorization makes no sense. At that point you're just doing a standard login. Reviewed By: ppansy Differential Revision: D25400025 fbshipit-source-id: dea99e3b4dbbec6b15d5714064fab1c90f36074e --- .../FBSDKLoginKit/FBSDKLoginConstants.h | 5 +++ .../FBSDKLoginKit/FBSDKLoginManager.h | 6 ++- .../FBSDKLoginKit/FBSDKLoginManager.m | 9 ++++- .../FBSDKLoginManagerTests.m | 38 +++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h index 6796cbba3f..85bab47c9c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h @@ -105,6 +105,11 @@ typedef NS_ERROR_ENUM(FBSDKLoginErrorDomain, FBSDKLoginError) The ID token returned in login response was invalid */ FBSDKLoginErrorInvalidIDToken, + + /** + A current access token was required and not provided + */ + FBSDKLoginErrorMissingAccessToken, } NS_SWIFT_NAME(LoginError); /** diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index e1bbb3d183..82f04d5d0d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -192,11 +192,15 @@ NS_SWIFT_NAME(logIn(url:handler:)); @param fromViewController the view controller to present from. If nil, the topmost view controller will be automatically determined as best as possible. @param handler the callback. + +@warning This method will reauthorize using a `LoginConfiguration` with `FBSDKBetaLoginExperience` set to enabled. + Use this method when you need to reathorize your app's access to user data via Graph API, after such an access has expired. You should provide as much context to the user as possible as to why you need to reauthorize the access, the scope of access being reathorized, and what added value your app provides when the access is reathorized. You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. - This method will present UI the user. You typically should call this if `[FBSDKAccessToken isDataAccessExpired]` returns true. +This method will present UI the user. You typically should call this if `[FBSDKAccessToken isDataAccessExpired]` returns true. + */ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FBSDKLoginManagerLoginResultBlock)handler diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 8b96dc828f..c7196fde31 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -427,12 +427,19 @@ - (void)logInWithURL:(NSURL *)url - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler { + if (!FBSDKAccessToken.currentAccessToken) { + NSError *error = [NSError errorWithDomain:FBSDKLoginErrorDomain + code:FBSDKLoginErrorMissingAccessToken + userInfo:nil]; + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Must have an access token for which to reauthorize data access"]; + handler(nil, error); + return; + } FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; _logger = [[FBSDKLoginManagerLogger alloc] initWithLoggingToken:serverConfiguration.loggingToken]; _handler = [handler copy]; // Don't need to pass permissions for data reauthorization. _requestedPermissions = [NSSet set]; - _configuration = [FBSDKLoginConfiguration init]; self.authType = FBSDKLoginAuthTypeReauthorize; [_logger startSessionForLoginManager:self]; [self logIn]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 11cf82237e..068c52ab63 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -22,6 +22,7 @@ #import +#import "FBSDKLoginConstants.h" #import "FBSDKLoginManager.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLoginResult.h" @@ -529,6 +530,43 @@ - (void)testStoreExpectedNonce XCTAssertNil([keychainStore stringForKey:@"expected_login_nonce"]); } +- (void)testReauthorizingWithoutAccessToken +{ + [FBSDKAccessToken setCurrentAccessToken:nil shouldDispatchNotif:NO]; + + [_mockLoginManager reauthorizeDataAccess:[UIViewController new] + handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTAssertNil(result, "Should not have a result when reauthorizing without a current access token"); + XCTAssertEqual(error.domain, FBSDKLoginErrorDomain); + XCTAssertEqual(error.code, FBSDKLoginErrorMissingAccessToken); + }]; +} + +- (void)testReauthorizingWithAccessToken +{ + [FBSDKAccessToken setCurrentAccessToken:self.sampleAccessToken shouldDispatchNotif:NO]; + OCMStub([_mockLoginManager logIn]); + + [_mockLoginManager reauthorizeDataAccess:[UIViewController new] + handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTFail("Should not actually reauthorize and call the handler in this test"); + }]; + OCMVerify([_mockLoginManager logIn]); +} + +- (FBSDKAccessToken *)sampleAccessToken +{ + return [[FBSDKAccessToken alloc] initWithTokenString:self.name + permissions:@[] + declinedPermissions:@[] + expiredPermissions:@[] + appID:@"abc123" + userID:@"userID" + expirationDate:nil + refreshDate:nil + dataAccessExpirationDate:nil]; +} + - (void)validateCommonLoginParameters:(NSDictionary *)params { XCTAssertEqualObjects(params[@"client_id"], kFakeAppID); From c582293fdb67e8c43376641a40f4aa7f6de30124 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 8 Dec 2020 12:31:52 -0800 Subject: [PATCH 160/227] ID Token exclusive response Summary: Fixing bug where we are creating an empty access token when there is no token string in the response. This will result in weird behavior since things like `LoginButton` look at `AccessToken.current` Reviewed By: ppansy Differential Revision: D25384895 fbshipit-source-id: 2543121952ac66f046303af9a17e33ff75b33730 --- .../FBSDKLoginKit/FBSDKLoginManager.m | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index c7196fde31..e7e826c00d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -229,25 +229,34 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe declinedPermissions:declinedPermissions]; if (recentlyGrantedPermissions.count > 0) { - FBSDKAccessToken *token = [[FBSDKAccessToken alloc] initWithTokenString:tokenString - permissions:grantedPermissions.allObjects - declinedPermissions:declinedPermissions.allObjects - expiredPermissions:@[] - appID:parameters.appID - userID:parameters.userID - expirationDate:parameters.expirationDate - refreshDate:[NSDate date] - dataAccessExpirationDate:parameters.dataAccessExpirationDate - graphDomain:parameters.graphDomain]; - result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:token - isCancelled:NO - grantedPermissions:recentlyGrantedPermissions - declinedPermissions:recentlyDeclinedPermissions]; - - if ([FBSDKAccessToken currentAccessToken]) { - [self validateReauthentication:[FBSDKAccessToken currentAccessToken] withResult:result]; - // in a reauth, short circuit and let the login handler be called when the validation finishes. - return; + if (!tokenString) { + // If there is no token string then create a 'tokenless' result + // from the returned permissions + result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil + isCancelled:NO + grantedPermissions:grantedPermissions + declinedPermissions:declinedPermissions]; + } else { + FBSDKAccessToken *token = [[FBSDKAccessToken alloc] initWithTokenString:tokenString + permissions:grantedPermissions.allObjects + declinedPermissions:declinedPermissions.allObjects + expiredPermissions:@[] + appID:parameters.appID + userID:parameters.userID + expirationDate:parameters.expirationDate + refreshDate:[NSDate date] + dataAccessExpirationDate:parameters.dataAccessExpirationDate + graphDomain:parameters.graphDomain]; + result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:token + isCancelled:NO + grantedPermissions:recentlyGrantedPermissions + declinedPermissions:recentlyDeclinedPermissions]; + + if ([FBSDKAccessToken currentAccessToken]) { + [self validateReauthentication:[FBSDKAccessToken currentAccessToken] withResult:result]; + // in a reauth, short circuit and let the login handler be called when the validation finishes. + return; + } } } } From 0a4401eedd0bcedda333762ff393be4e1720ca7c Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 8 Dec 2020 12:42:52 -0800 Subject: [PATCH 161/227] Removing AuthenticationToken Notifications Summary: $title Reviewed By: ppansy Differential Revision: D25402658 fbshipit-source-id: 2a4f6d68c1e53649664880c1d0da2aeb1c77c08f --- .../FBSDKCoreKit/FBSDKAuthenticationToken.h | 42 ---------- .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 14 ---- .../FBSDKAuthenticationTokenTests.m | 79 +------------------ 3 files changed, 1 insertion(+), 134 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h index 22ce95e2ba..8180ddb1dc 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.h @@ -20,48 +20,6 @@ NS_ASSUME_NONNULL_BEGIN -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 - -/** - Notification indicating that the `currentAuthenticationToken` has changed. - - the userInfo dictionary of the notification will contain keys - `FBSDKAuthenticationTokenChangeOldKey` and - `FBSDKAuthenticationTokenChangeNewKey`. - */ -FOUNDATION_EXPORT NSNotificationName const FBSDKAuthenticationTokenDidChangeNotification -NS_SWIFT_NAME(authenticationTokenDidChange); - -#else - -/** - Notification indicating that the `currentAuthenticationToken` has changed. - - the userInfo dictionary of the notification will contain keys - `FBSDKAuthenticationTokenChangeOldKey` and - `FBSDKAuthenticationTokenChangeNewKey`. - */ -FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenDidChangeNotification -NS_SWIFT_NAME(authenticationTokenDidChange); - -#endif - -/** - A key in the `AuthenticationTokenDidChange` notification's userInfo object for getting the old token. - - If there was no old token, the key will not be present. - */ -FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenChangeOldKey -NS_SWIFT_NAME(AuthenticationTokenChangeOldKey); - -/** - A key in `AuthenticationTokenDidChange` notification's userInfo object for getting the new token. - - If there is no new token, the key will not be present. - */ -FOUNDATION_EXPORT NSString *const FBSDKAuthenticationTokenChangeNewKey -NS_SWIFT_NAME(AuthenticationTokenChangeNewKey); - /** Represent an AuthenticationToken used for a login attempt */ diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index a6a0227ed0..86c9e7cdd5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -37,10 +37,6 @@ NSString *const FBSDKAuthenticationTokenTokenStringCodingKey = @"FBSDKAuthenticationTokenTokenStringCodingKey"; NSString *const FBSDKAuthenticationTokenNonceCodingKey = @"FBSDKAuthenticationTokenNonceCodingKey"; -NSNotificationName const FBSDKAuthenticationTokenDidChangeNotification = @"com.facebook.sdk.FBSDKAuthenticationTokenData.FBSDKAuthenticationTokenDidChangeNotification"; -NSString *const FBSDKAuthenticationTokenChangeNewKey = @"FBSDKAuthenticationTokenChangeNew"; -NSString *const FBSDKAuthenticationTokenChangeOldKey = @"FBSDKAuthenticationTokenChangeOld"; - @implementation FBSDKAuthenticationToken { NSDictionary *_claims; @@ -72,18 +68,8 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token shouldPostNotification:(BOOL)shouldPostNotification { if (token != g_currentAuthenticationToken) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - [FBSDKTypeUtility dictionary:userInfo setObject:token forKey:FBSDKAuthenticationTokenChangeNewKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:g_currentAuthenticationToken forKey:FBSDKAuthenticationTokenChangeOldKey]; - g_currentAuthenticationToken = token; [[self tokenCache] setAuthenticationToken:token]; - - if (shouldPostNotification) { - [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAuthenticationTokenDidChangeNotification - object:[self class] - userInfo:userInfo]; - } } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m index 7a63bdbc03..4a704a07cc 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m @@ -57,7 +57,7 @@ - (void)setUp - (void)testRetrievingCurrentToken { FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]; - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; + _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@{}]; id partialTokenMock = OCMPartialMock(_token); OCMStub([partialTokenMock tokenCache]).andReturn(cache); @@ -111,81 +111,4 @@ - (void)testDecodingEntryWithMethodName ); } -// MARK: - Notifications - -- (void)testPostsNotificationOnSettingInitial -{ - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]];; - FBSDKAuthenticationToken.currentAuthenticationToken = _token; - - XCTAssertTrue( - [_notificationCenterSpy.capturedPostNames containsObject:FBSDKAuthenticationTokenDidChangeNotification], - "Should post a notification when the authentication token is initially set" - ); - XCTAssertTrue( - [_notificationCenterSpy.capturedPostObjects containsObject:FBSDKAuthenticationToken.class], - "Notification should contain information about the object that posted it" - ); - XCTAssertTrue( - [_notificationCenterSpy.capturedPostUserInfos containsObject:@{ - FBSDKAuthenticationTokenChangeNewKey : _token - }], - "Notification should contain information about the change that occured" - ); -} - -- (void)testPostsNotificationOnSettingNew -{ - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; - FBSDKAuthenticationToken *token2 = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; - FBSDKAuthenticationToken.currentAuthenticationToken = _token; - - [_notificationCenterSpy clearTestEvidence]; - FBSDKAuthenticationToken.currentAuthenticationToken = token2; - - NSDictionary *expectedUserInfo = @{ - FBSDKAuthenticationTokenChangeOldKey : _token, - FBSDKAuthenticationTokenChangeNewKey : token2 - }; - - XCTAssertTrue( - [_notificationCenterSpy.capturedPostNames containsObject:FBSDKAuthenticationTokenDidChangeNotification], - "Should post a notification when the authentication token is changed" - ); - XCTAssertTrue( - [_notificationCenterSpy.capturedPostObjects containsObject:FBSDKAuthenticationToken.class], - "Notification should contain information about the object that posted it" - ); - XCTAssertTrue( - [_notificationCenterSpy.capturedPostUserInfos containsObject:expectedUserInfo], - "Notification should contain information about the change that occured" - ); -} - -- (void)testPostsNotificationOnSettingNil -{ - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@[]]; - FBSDKAuthenticationToken.currentAuthenticationToken = _token; - - [_notificationCenterSpy clearTestEvidence]; - FBSDKAuthenticationToken.currentAuthenticationToken = nil; - - NSDictionary *expectedUserInfo = @{ - FBSDKAuthenticationTokenChangeOldKey : _token - }; - - XCTAssertTrue( - [_notificationCenterSpy.capturedPostNames containsObject:FBSDKAuthenticationTokenDidChangeNotification], - "Should post a notification when the authentication token is removed" - ); - XCTAssertTrue( - [_notificationCenterSpy.capturedPostObjects containsObject:FBSDKAuthenticationToken.class], - "Notification should contain information about the object that posted it" - ); - XCTAssertTrue( - [_notificationCenterSpy.capturedPostUserInfos containsObject:expectedUserInfo], - "Notification should contain information about the change that occured" - ); -} - @end From bf0c9ea06d1f30ab76863ddd46d6270dfe3cd5b1 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 9 Dec 2020 11:03:47 -0800 Subject: [PATCH 162/227] Check for nil configuration in login manager Summary: Trying to initialize `FBSDKLoginConfiguration` with invalid arguments will result in `nil`, developers might not check for that before passing it into LoginManager. We want to add a check for configuration passed into LoginManager, and returns an error if it is nil. Reviewed By: joesus Differential Revision: D25387251 fbshipit-source-id: 8ddee7f50a68bada059e21a5efe24ea7669f5086 --- .../FBSDKLoginKit/FBSDKLoginManager.m | 6 ++++++ .../FBSDKLoginManagerTests.m | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index e7e826c00d..e3f057abc6 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -91,6 +91,12 @@ - (void)logInFromViewController:(UIViewController *)viewController if (![self validateLoginStartState]) { return; } + if (!configuration) { + NSError *error = [FBSDKError errorWithCode:FBSDKErrorInvalidArgument message:@"Attempting to login with a nil configuration"]; + completion(nil, error); + return; + } + self.fromViewController = viewController; _configuration = configuration; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 068c52ab63..c2fd3ad693 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -431,6 +431,24 @@ - (void)testCallingLoginWhileAnotherLoginHasNotFinishedNoOps XCTAssertEqual(loginCount, 1); } +- (void)testCallingLoginWithNilConfigurationShouldFail +{ + __block BOOL resultBlockInvoked = NO; + FBSDKLoginManagerLoginResultBlock completion = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTAssertNil(result); + XCTAssertNotNil(error); + resultBlockInvoked = YES; + }; + + FBSDKLoginConfiguration *invalidConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[] + betaLoginExperience:FBSDKBetaLoginExperienceRestricted + nonce:@" "]; + XCTAssertNil(invalidConfig); + + [_mockLoginManager logInFromViewController:nil configuration:invalidConfig completion:completion]; + XCTAssertTrue(resultBlockInvoked, "Should invoke completion synchronously"); +} + - (void)testBetaLoginExperienceEnabledLoginParams { FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] From cb75888a2043173f36ee0db9d38f096c4157afa1 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 10 Dec 2020 09:14:10 -0800 Subject: [PATCH 163/227] Adding JTI to AuthenticationToken Summary: * Persisting claims so that we can derive JIT and future properties from it * Fails creation of auth token if response is missing a JIT Reviewed By: ppansy Differential Revision: D25408435 fbshipit-source-id: 5eaa9e12b6d4a524e7f14b6ef1d9054a225efce6 --- .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 25 ++++++++++++++++++- .../FBSDKAuthenticationToken+Internal.h | 1 + .../FBSDKAuthenticationTokenFactory.m | 7 ++++-- .../FBSDKAuthenticationTokenTests.m | 25 +++++++++++-------- .../FBSDKCoreKitTests-Bridging-Header.h | 3 ++- .../FBSDKAuthenticationTokenFactoryTests.m | 14 ++++++----- .../Helpers/SampleAuthenticationToken.swift | 3 ++- .../xcschemes/FBSDKLoginKit-Dynamic.xcscheme | 10 ++++++++ .../FBSDKLoginKitTests-Bridging-Header.h | 3 ++- .../FBSDKLoginManagerTests.m | 11 ++++++-- .../FBSDKLoginKitTests/LoginButtonTests.swift | 2 +- 11 files changed, 79 insertions(+), 25 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index 86c9e7cdd5..8a02e9d243 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -36,20 +36,35 @@ NSString *const FBSDKAuthenticationTokenTokenStringCodingKey = @"FBSDKAuthenticationTokenTokenStringCodingKey"; NSString *const FBSDKAuthenticationTokenNonceCodingKey = @"FBSDKAuthenticationTokenNonceCodingKey"; +NSString *const FBSDKAuthenticationTokenJtiCodingKey = @"FBSDKAuthenticationTokenJtiCodingKey"; @implementation FBSDKAuthenticationToken { NSDictionary *_claims; + NSString *_jti; } - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce claims:(NSDictionary *)claims +{ + self = [self initWithTokenString:tokenString + nonce:nonce + claims:claims + jti:claims[@"jti"]]; + return self; +} + +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + claims:(NSDictionary *)claims + jti:(NSString *)jti { if ((self = [super init])) { _tokenString = tokenString; _nonce = nonce; _claims = claims; + _jti = jti; } return self; } @@ -73,6 +88,11 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token } } +- (NSString *)jti +{ + return _jti; +} + #pragma mark Storage + (id)tokenCache @@ -89,16 +109,19 @@ - (instancetype)initWithCoder:(NSCoder *)decoder { NSString *tokenString = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenTokenStringCodingKey]; NSString *nonce = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenNonceCodingKey]; + NSString *jti = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenJtiCodingKey]; return [self initWithTokenString:tokenString nonce:nonce - claims:nil]; + claims:nil + jti:jti]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.tokenString forKey:FBSDKAuthenticationTokenTokenStringCodingKey]; [encoder encodeObject:self.nonce forKey:FBSDKAuthenticationTokenNonceCodingKey]; + [encoder encodeObject:_jti forKey:FBSDKAuthenticationTokenJtiCodingKey]; } #pragma mark - Test methods diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h index 4f0b078d08..5835ae3122 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h @@ -25,6 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @interface FBSDKAuthenticationToken (Internal) - (NSDictionary *)claims; +- (NSString *)jit; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m index 89d5f28bce..510c40fd77 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -91,7 +91,9 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString // return; // } - FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc]initWithTokenString:tokenString nonce:nonce claims:claims]; + FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc]initWithTokenString:tokenString + nonce:nonce + claims:claims]; completion(token); } @@ -112,8 +114,9 @@ + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims non BOOL issuedRecently = [claims[@"iat"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"iat"] longValue] >= currentTime - MaxTimeSinceTokenIssued; BOOL nonceMatched = [claims[@"nonce"] isKindOfClass:[NSString class]] && [claims[@"nonce"] isEqualToString:nonce]; BOOL userIDValid = [claims[@"sub"] isKindOfClass:[NSString class]] && [claims[@"sub"] length] > 0; + BOOL hasJTI = [claims[@"jti"] isKindOfClass:[NSString class]] && [claims[@"jti"] length] > 0; - if (isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid) { + if (isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid && hasJTI) { return claims; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m index 4a704a07cc..52ef28e100 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m @@ -26,14 +26,6 @@ #import "FBSDKTestCase.h" #import "FBSDKTestCoder.h" -@interface FBSDKAuthenticationToken (Testing) - -- (instancetype)initWithTokenString:(NSString *)tokenString - nonce:(NSString *)nonce - claims:(NSDictionary *)claims; - -@end - @interface FBSDKAuthenticationTokenTests : FBSDKTestCase @end @@ -57,7 +49,7 @@ - (void)setUp - (void)testRetrievingCurrentToken { FakeTokenCache *cache = [[FakeTokenCache alloc] initWithAccessToken:nil authenticationToken:nil]; - _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:@"" nonce:@"" claims:@{}]; + _token = SampleAuthenticationToken.validToken; id partialTokenMock = OCMPartialMock(_token); OCMStub([partialTokenMock tokenCache]).andReturn(cache); @@ -76,10 +68,13 @@ - (void)testEncoding { NSString *expectedTokenString = @"expectedTokenString"; NSString *expectedNonce = @"expectedNonce"; + NSString *expectedJTI = @"expectedJTI"; FBSDKTestCoder *coder = [FBSDKTestCoder new]; _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:expectedTokenString - nonce:expectedNonce claims:@{}]; + nonce:expectedNonce + claims:@{} + jti:expectedJTI]; [_token encodeWithCoder:coder]; XCTAssertEqualObjects( @@ -92,6 +87,11 @@ - (void)testEncoding expectedNonce, @"Should encode the expected nonce string" ); + XCTAssertEqualObjects( + coder.encodedObject[@"FBSDKAuthenticationTokenJtiCodingKey"], + expectedJTI, + @"Should encode the expected JTI" + ); } - (void)testDecodingEntryWithMethodName @@ -109,6 +109,11 @@ - (void)testDecodingEntryWithMethodName [NSString class], @"Initializing from a decoder should attempt to decode a String for the nonce key" ); + XCTAssertEqualObjects( + coder.decodedObject[@"FBSDKAuthenticationTokenJtiCodingKey"], + [NSString class], + @"Initializing from a decoder should attempt to decode a String for the jti key" + ); } @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 5e6672b375..4f5db46d51 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -47,5 +47,6 @@ @interface FBSDKAuthenticationToken (Testing) - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(NSDictionary *)claims; + claims:(NSDictionary *)claims + jti:(NSString *)jti; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index 5a71cf0204..3ad0659fc7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -24,17 +24,12 @@ #import "FBSDKTestCase.h" static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; - static NSString *const _encodedHeader = @"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; - static NSString *const _encodedClaims = @"eyJzdWIiOiIxMjM0IiwibmFtZSI6IlRlc3QgVXNlciIsImlzcyI6Imh0dHBzOi8vZmFjZWJvb2suY29tL2RpYWxvZy9vYXV0aCIsImF1ZCI6IjQzMjEiLCJub25jZSI6InNvbWVfbm9uY2UiLCJleHAiOjE1MTYyNTkwMjIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zb21lX3BpY3R1cmUiLCJpYXQiOjE1MTYyMzkwMjJ9"; - static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; - static NSString *const _mockAppID = @"4321"; - +static NSString *const _mockJTI = @"some_jti"; static NSString *const _mockNonce = @"some_nonce"; - static NSString *const _facebookURL = @"https://facebook.com/dialog/oauth"; @interface FBSDKAuthenticationTokenFactory (Testing) @@ -77,6 +72,7 @@ - (void)setUp @"nonce" : _mockNonce, @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later @"iat" : @(currentTime - 60), // 1 min ago + @"jti" : _mockJTI, @"sub" : @"1234", @"name" : @"Test User", @"email" : @"email@email.com", @@ -156,6 +152,12 @@ - (void)testDecodeInvalidClaimsShouldFail value:@1234]; [self assertDecodeClaimsFailWithInvalidEntry:@"sub" value:@""]; + + // invalid JIT + [self assertDecodeClaimsFailWithInvalidEntry:@"jti" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"jti" + value:@""]; } - (void)testDecodeEmptyClaims diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift index e239995602..65900e280d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift @@ -23,7 +23,8 @@ public class SampleAuthenticationToken: NSObject { return AuthenticationToken( tokenString: "fakeTokenString", nonce: "fakeNonce", - claims: [:] + claims: [:], + jti: "fakeJTI" ) } diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme index 24bdd14d8e..f08b351142 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme @@ -38,6 +38,16 @@ ReferencedContainer = "container:FBSDKLoginKit.xcodeproj">
+ + + +
Date: Thu, 10 Dec 2020 15:30:47 -0800 Subject: [PATCH 164/227] Update ProfilePictureView Summary: The purpose of this change is to integrate profile changes with `FBSDKProfilePictureView`. We need ProfilePictureView to listen to changes of `FBSDKProfile` and `FBSDKAuthenticationToken`, since a profile picture can come from two sources: graph request with access token, or from `imageURL` field in the shared Profile object. - When an AccessToken notification fires, the behavior is unchanged, ProfilePictureView will try to make a graph request to get the latest profile picture. - When a Profile notification fires, ProfilePictureView will use `imageURL` from the current profile object. Noop if an imageURL is not available. - When `setNeedsImageUpdate` is called, ProfilePictureView will prioritize fetching image through graph request, and fallback to Profile.imageURL only when an active access token is not available. Reviewed By: joesus Differential Revision: D25408579 fbshipit-source-id: 64b4f572a5283060bdcac345a778c8ec98f9e3d8 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 4 + .../FBSDKCoreKit/FBSDKProfilePictureView.m | 156 +++++++---- .../FBSDKCoreKitTests-Bridging-Header.h | 32 +++ .../Internal/Helpers/SampleAccessToken.swift | 14 + .../Helpers/SampleAuthenticationToken.swift | 2 +- .../ProfilePictureViewTests.swift | 264 ++++++++++++++++++ 6 files changed, 421 insertions(+), 51 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index f737ca24cf..cd8165e605 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -785,6 +785,7 @@ C638153D257EA7CC00B7690F /* FBSDKAuthenticationTokenFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */; }; C638158A257EA8F000B7690F /* FBSDKAuthenticationTokenFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */; }; C6381628257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6381619257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m */; }; + C67BED2A257F1A6300D356C9 /* ProfilePictureViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C67BED29257F1A6300D356C9 /* ProfilePictureViewTests.swift */; }; C6A308BD257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */; }; C6A308D8257AD227003C52FD /* FBSDKAuthenticationTokenFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */; }; C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */; }; @@ -1545,6 +1546,7 @@ C5EAFA5D255283C100458DF5 /* FBSDKUserDataStore+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKUserDataStore+Internal.h"; sourceTree = ""; }; C5F6EC851FA24FAF009EB258 /* FBSDKPaymentObserverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPaymentObserverTests.m; sourceTree = ""; }; C6381619257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenFactoryTests.m; sourceTree = ""; }; + C67BED29257F1A6300D356C9 /* ProfilePictureViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePictureViewTests.swift; sourceTree = ""; }; C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationTokenFactory.h; sourceTree = ""; }; C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenFactory.m; sourceTree = ""; }; C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterTests.m; sourceTree = ""; }; @@ -2388,6 +2390,7 @@ 9D2697571A5DF40700143BFC /* Supporting Files */, 2A3DA4151CB4C0F600339BD4 /* FBSDKAppLinkUtilityTests.swift */, 5D2165F12229C6A3004952D8 /* FBSDKGraphRequestTests.m */, + C67BED29257F1A6300D356C9 /* ProfilePictureViewTests.swift */, ); path = FBSDKCoreKitTests; sourceTree = ""; @@ -4195,6 +4198,7 @@ 7E55573C1A8D834B00344F86 /* FBSDKAppLinkResolverTests.m in Sources */, 5D2165E122264453004952D8 /* FBSDKAppEventsTests.m in Sources */, F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */, + C67BED2A257F1A6300D356C9 /* ProfilePictureViewTests.swift in Sources */, F4D80C082566D469008CCAF0 /* FBSDKDrawableTests.swift in Sources */, 9D18A8DB1A95405A00A41042 /* FBSDKAppEventsStateTests.m in Sources */, F4ED90DB24EDDC610048D283 /* NotificationCenterSpy.swift in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m index 9418b87975..1e98115c1f 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m @@ -221,7 +221,7 @@ - (void)setNeedsImageUpdate return; } self->_needsImageUpdate = YES; - [self _needsImageUpdate]; + [self _updateImage]; }); } @@ -241,11 +241,15 @@ - (void)configureProfilePictureView selector:@selector(_accessTokenDidChangeNotification:) name:FBSDKAccessTokenDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(_profileDidChangeNotification:) + name:FBSDKProfileDidChangeNotification + object:nil]; [self setNeedsImageUpdate]; } - #pragma mark - Helper Methods + #pragma mark - Notifications - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { @@ -253,9 +257,95 @@ - (void)_accessTokenDidChangeNotification:(NSNotification *)notification return; } _lastState = nil; - [self setNeedsImageUpdate]; + [self _updateImageWithAccessToken]; +} + +- (void)_profileDidChangeNotification:(NSNotification *)notification +{ + if (![_profileID isEqualToString:@"me"]) { + return; + } + _lastState = nil; + [self _updateImageWithProfile]; +} + + #pragma mark - Image Update + +- (void)_updateImageWithProfile +{ + if (!_profileID) { + if (!_placeholderImageIsValid) { + [self _setPlaceholderImage]; + } + return; + } + + // if the current image is no longer representative of the current state, clear the current value out; otherwise, + // leave the current value until the new resolution image is downloaded + FBSDKProfilePictureViewState *state = [self _state]; + if (![_lastState isValidForState:state]) { + [self _setPlaceholderImage]; + } + _lastState = state; + + FBSDKProfile *profile = FBSDKProfile.currentProfile; + if (![state.profileID isEqualToString:@"me"] || !profile.imageURL) { + return; + } + + [self _fetchAndSetImageWithURL:profile.imageURL state:state]; +} + +- (void)_updateImageWithAccessToken +{ + if (!_profileID) { + if (!_placeholderImageIsValid) { + [self _setPlaceholderImage]; + } + return; + } + + // if the current image is no longer representative of the current state, clear the current value out; otherwise, + // leave the current value until the new resolution image is downloaded + FBSDKProfilePictureViewState *state = [self _state]; + if (![_lastState isValidForState:state]) { + [self _setPlaceholderImage]; + } + + if ([state.profileID isEqualToString:@"me"] && !FBSDKAccessToken.currentAccessTokenIsActive) { + return; + } + _lastState = state; + + [self _fetchAndSetImageWithURL:[self _getProfileImageUrl:state] state:state]; +} + +- (void)_fetchAndSetImageWithURL:(NSURL *)imageURL state:(FBSDKProfilePictureViewState *)state +{ + __weak FBSDKProfilePictureView *weakSelf = self; + NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL]; + NSURLSession *session = [NSURLSession sharedSession]; + [[session + dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (!error && data.length) { + [weakSelf _updateImageWithData:data state:state]; + } + }] resume]; } +- (void)_updateImage +{ + _needsImageUpdate = NO; + if (![_profileID isEqualToString:@"me"] || FBSDKAccessToken.currentAccessTokenIsActive) { + [self _updateImageWithAccessToken]; + } else if (FBSDKProfile.currentProfile.imageURL) { + [self _updateImageWithProfile]; + } +} + + #pragma mark - Helper Methods + - (BOOL)_imageShouldFit { switch (self.contentMode) { @@ -306,60 +396,26 @@ - (CGSize)_imageSize:(BOOL)imageShouldFit scale:(CGFloat)scale return size; } -- (NSURL *)_getProfileImageUrl:(FBSDKProfilePictureViewState *)state +- (FBSDKProfilePictureViewState *)_state { - // If there's an existing profile, use that profile's image url handler - if (FBSDKProfile.currentProfile != nil) { - return [FBSDKProfile.currentProfile imageURLForPictureMode:self.pictureMode size:state.size]; - } - return [FBSDKProfile imageURLForProfileID:state.profileID PictureMode:self.pictureMode size:state.size]; -} - -- (void)_needsImageUpdate -{ - _needsImageUpdate = NO; - - if (!_profileID) { - if (!_placeholderImageIsValid) { - [self _setPlaceholderImage]; - } - return; - } - - // if the current image is no longer representative of the current state, clear the current value out; otherwise, - // leave the current value until the new resolution image is downloaded BOOL imageShouldFit = [self _imageShouldFit]; UIScreen *screen = self.window.screen ?: [UIScreen mainScreen]; CGFloat scale = screen.scale; CGSize imageSize = [self _imageSize:imageShouldFit scale:scale]; - FBSDKProfilePictureViewState *state = [[FBSDKProfilePictureViewState alloc] initWithProfileID:_profileID - size:imageSize - scale:scale - pictureMode:_pictureMode - imageShouldFit:imageShouldFit]; - if (![_lastState isValidForState:state]) { - [self _setPlaceholderImage]; - } - _lastState = state; + return [[FBSDKProfilePictureViewState alloc] initWithProfileID:_profileID + size:imageSize + scale:scale + pictureMode:_pictureMode + imageShouldFit:imageShouldFit]; +} - FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken]; - if ([state.profileID isEqualToString:@"me"] && !accessToken) { - return; +- (NSURL *)_getProfileImageUrl:(FBSDKProfilePictureViewState *)state +{ + // If there's an existing profile, use that profile's image url handler + if (FBSDKProfile.currentProfile != nil) { + return [FBSDKProfile.currentProfile imageURLForPictureMode:self.pictureMode size:state.size]; } - - __weak FBSDKProfilePictureView *weakSelf = self; - - NSURL *imageURL = [self _getProfileImageUrl:state]; - - NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL]; - NSURLSession *session = [NSURLSession sharedSession]; - [[session - dataTaskWithRequest:request - completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - if (!error && data.length) { - [weakSelf _updateImageWithData:data state:state]; - } - }] resume]; + return [FBSDKProfile imageURLForProfileID:state.profileID PictureMode:self.pictureMode size:state.size]; } - (void)_setPlaceholderImage diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 4f5db46d51..9d6c4006ee 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -50,3 +50,35 @@ claims:(NSDictionary *)claims jti:(NSString *)jti; @end + +NS_SWIFT_NAME(FBProfilePictureViewState) +@interface FBSDKProfilePictureViewState +@end + +@interface FBSDKProfilePictureView (Testing) +- (void)_accessTokenDidChangeNotification:(NSNotification *)notification; +- (void)_profileDidChangeNotification:(NSNotification *)notification; +- (void)_updateImageWithProfile; +- (void)_updateImageWithAccessToken; +- (void)_updateImage; +- (void)_fetchAndSetImageWithURL:(NSURL *)imageURL state:(FBSDKProfilePictureViewState *)state; +@end + +@interface FBSDKAccessToken (Testing) ++ (void)setCurrentAccessToken:(FBSDKAccessToken *)token + shouldDispatchNotif:(BOOL)shouldDispatchNotif; +@end + +@interface FBSDKProfile (Testing) ++ (void)setCurrentProfile:(nullable FBSDKProfile *)profile + shouldPostNotification:(BOOL)shouldPostNotification; +@end + +@interface FBSDKAuthenticationToken (Testing) +- (instancetype)initWithTokenString:(NSString *)tokenString + nonce:(NSString *)nonce + claims:(NSDictionary *)claims + jti:(NSString *)jti; ++ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token + shouldPostNotification:(BOOL)shouldPostNotification; +@end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift index 0c372b3a47..34369f827e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAccessToken.swift @@ -32,6 +32,20 @@ public class SampleAccessToken: NSObject { dataAccessExpirationDate: nil ) } + + public static var expiredToken: AccessToken { + return AccessToken( + tokenString: "123", + permissions: [], + declinedPermissions: [], + expiredPermissions: [], + appID: "123", + userID: "user123", + expirationDate: .distantPast, + refreshDate: nil, + dataAccessExpirationDate: nil + ) + } public static func valid(withRefreshDate date: Date?) -> AccessToken { return AccessToken( diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift index 65900e280d..bc9ac8f08d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift @@ -25,7 +25,7 @@ public class SampleAuthenticationToken: NSObject { nonce: "fakeNonce", claims: [:], jti: "fakeJTI" - ) + )! // swiftlint:disable:this force_unwrapping } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift new file mode 100644 index 0000000000..14ce8ee913 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift @@ -0,0 +1,264 @@ +// 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 FBSDKCoreKit +import XCTest + +class ProfilePictureView: XCTestCase { + var sampleProfile: Profile { + return Profile( + userID: "Sample ID", + firstName: nil, + middleName: nil, + lastName: nil, + name: "Sample Name", + linkURL: nil, + refreshDate: nil, + imageURL: URL(string:"https://www.facebook.com/"), + email:nil + ) + } + var sampleProfileWithoutImageURL: Profile { + return Profile( + userID: "Sample ID", + firstName: nil, + middleName: nil, + lastName: nil, + name: "Sample Name", + linkURL: nil, + refreshDate: nil + ) + } + + override func setUp() { + super.setUp() + + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + Profile.setCurrent(nil, shouldPostNotification: false) + } + + // MARK: - Update Image + + func testImageUpdateWithoutAccessTokenWithProfile() { + let view = TestView() + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + Profile.setCurrent(sampleProfile, shouldPostNotification: false) + + view._updateImage() + + XCTAssertEqual( + view.updateImageWithProfileCount, + 1, + "Should use the profile when there is no access token" + ) + XCTAssertEqual( + view.updateImageWithAccessTokenCount, + 0, + "Should not use the access token when there is no access token" + ) + } + + func testImageUpdateWithAccessTokenWithProfile() { + let view = TestView() + AccessToken.setCurrent(SampleAccessToken.validToken, shouldDispatchNotif: false) + Profile.setCurrent(sampleProfile, shouldPostNotification: false) + + view._updateImage() + + XCTAssertEqual( + view.updateImageWithProfileCount, + 0, + "Should not use the profile when there is an access token" + ) + XCTAssertEqual( + view.updateImageWithAccessTokenCount, + 1, + "Should use the access token when there is one available" + ) + } + + func testImageUpdateWithoutAccessTokenWithoutProfile() { + let view = TestView() + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + Profile.setCurrent(nil, shouldPostNotification: false) + + view._updateImage() + + XCTAssertEqual( + view.updateImageWithProfileCount, + 0, + "Should not use the profile when there is no access token or current profile" + ) + XCTAssertEqual( + view.updateImageWithAccessTokenCount, + 0, + "Should not use the access token when there is no access token or current profile" + ) + } + + func testImageUpdateWithoutAccessTokenWithProfileNoImageURL() { + let view = TestView() + AccessToken.setCurrent(nil, shouldDispatchNotif: false) + Profile.setCurrent(sampleProfileWithoutImageURL, shouldPostNotification: false) + + view._updateImage() + + XCTAssertEqual( + view.updateImageWithProfileCount, + 0, + "Should not use the profile when there is no image url available" + ) + XCTAssertEqual( + view.updateImageWithAccessTokenCount, + 0, + "Should not use the access token when there is no access token" + ) + } + + // MARK: - Token Notifications + + func testReceivingAccessTokenNotificationWithDidChangeUserIdKey() { + let view = TestView() + let notification = Notification( + name: .AccessTokenDidChange, + object: nil, + userInfo: [AccessTokenDidChangeUserIDKey: "foo"] + ) + + view._accessTokenDidChange(notification) + + XCTAssertEqual( + view.updateImageWithAccessTokenCount, + 1, + "An access token notification with a changed user id key should trigger an image update" + ) + } + + + func testReceivingAccessTokenNotificationWithoutRelevantUserInfo() { + let view = TestView() + let notification = Notification( + name: .AccessTokenDidChange, + object: nil, + userInfo: nil + ) + + view._accessTokenDidChange(notification) + + XCTAssertEqual( + view.updateImageWithAccessTokenCount, + 0, + "An access token notification without relevant user info should not trigger an image update" + ) + } + + func testReceivingProfileNotification() { + let view = TestView() + Profile.setCurrent(sampleProfile, shouldPostNotification: false) + let notification = Notification( + name: .ProfileDidChange, + object: nil, + userInfo: nil + ) + + view._profileDidChange(notification) + + XCTAssertEqual( + view.updateImageWithProfileCount, + 1, + "An profile change should trigger an image update" + ) + } + + // MARK: - Updating Content + + func testUpdatinImageWithProfileWithImageURL() { + let view = TestView() + Profile.setCurrent(sampleProfile, shouldPostNotification: false) + + view._updateImageWithProfile() + + XCTAssertEqual( + view.fetchAndSetImageCount, + 1, + "Should try to fetch image for a profile that have an imageURL" + ) + } + + func testUpdatinImageWithProfileWithoutImageURL() { + let view = TestView() + Profile.setCurrent(sampleProfileWithoutImageURL, shouldPostNotification: false) + + view._updateImageWithProfile() + + XCTAssertEqual( + view.fetchAndSetImageCount, + 0, + "Should try to fetch image for a profile that does not have an imageURL" + ) + } + + func testUpdatingImageWithValidAccessToken() { + let view = TestView() + AccessToken.setCurrent(SampleAccessToken.validToken, shouldDispatchNotif: false) + + view._updateImageWithAccessToken() + + XCTAssertEqual( + view.fetchAndSetImageCount, + 1, + "Should try to fetch image for a valid access token" + ) + } + + func testUpdatingImageWithInvalidAccessToken() { + let view = TestView() + AccessToken.setCurrent(SampleAccessToken.expiredToken, shouldDispatchNotif: false) + + view._updateImageWithAccessToken() + + XCTAssertEqual( + view.fetchAndSetImageCount, + 0, + "Should not try to fetch image for an invalid access token" + ) + } +} + +class TestView: FBProfilePictureView { + var updateImageWithAccessTokenCount = 0 + var updateImageWithProfileCount = 0 + var updateImageWithDataCount = 0 + var fetchAndSetImageCount = 0 + + override func _updateImageWithAccessToken() { + updateImageWithAccessTokenCount += 1 + + super._updateImageWithAccessToken() + } + + override func _updateImageWithProfile() { + updateImageWithProfileCount += 1 + + super._updateImageWithProfile() + } + + override func _fetchAndSetImage(with url:URL?, state:FBProfilePictureViewState!) { + fetchAndSetImageCount += 1 + } +} From fbcbac8b9a211e4fea7232af7a0964f715e3fcba Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Thu, 10 Dec 2020 15:32:32 -0800 Subject: [PATCH 165/227] Add beta login parameter Summary: title Reviewed By: joesus Differential Revision: D25473255 fbshipit-source-id: 8113cfe17eb25b26fe7cfa45a9fed49aad106057 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 1 + FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 2 ++ 2 files changed, 3 insertions(+) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index e3f057abc6..56667fea81 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -379,6 +379,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co NSString *responseType; if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { responseType = @"id_token"; + [FBSDKTypeUtility dictionary:loginParams setObject:@"beta_login" forKey:@"tp"]; } else { responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; } diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 6176d4a6ae..57ab9fb543 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -467,6 +467,7 @@ - (void)testBetaLoginExperienceEnabledLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertNotNil(params[@"nonce"]); + XCTAssertNil(params[@"tp"]); } - (void)testBetaLoginExperienceRestrictedLoginParams @@ -481,6 +482,7 @@ - (void)testBetaLoginExperienceRestrictedLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); + XCTAssertEqualObjects(params[@"tp"], @"beta_login"); } - (void)testlogInParametersFromURL From f310329b160c8444ad8f710d23f2da11e3f88752 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 10 Dec 2020 21:03:47 -0800 Subject: [PATCH 166/227] Token Management 2/n Summary: This fixes the bug from the previous diff. Trying to log in without a valid configuration will not make a network call. Reviewed By: ppansy Differential Revision: D25430056 fbshipit-source-id: e4630867fc40a8b30b2f83d08f293b49331ab706 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 56667fea81..315fa56a78 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -92,7 +92,10 @@ - (void)logInFromViewController:(UIViewController *)viewController return; } if (!configuration) { - NSError *error = [FBSDKError errorWithCode:FBSDKErrorInvalidArgument message:@"Attempting to login with a nil configuration"]; + NSString *failureMessage = @"Cannot login without a valid login configuration. Please make sure the `LoginConfiguration` provided is non-nil"; + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors + logEntry:failureMessage]; + NSError *error = [FBSDKError errorWithCode:FBSDKErrorInvalidArgument message:failureMessage]; completion(nil, error); return; } From 1251cf325266dd38a67bc1f8c467cbb699d97be4 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 10 Dec 2020 21:03:47 -0800 Subject: [PATCH 167/227] Token Management 3/n Summary: Updates login completion to return rather than set the authentication token so that setting it or not can be managed in a broader context. Reviewed By: ppansy Differential Revision: D25446217 fbshipit-source-id: 0e684f863901a661a07cfa09ba71507c7f58ca34 --- .../FBSDKLoginKit/FBSDKLoginManager.m | 69 +++++++++++++------ .../Internal/FBSDKLoginCompletion+Internal.h | 5 +- .../Internal/FBSDKLoginCompletion.h | 17 +++-- .../Internal/FBSDKLoginCompletion.m | 55 ++++++++++----- 4 files changed, 105 insertions(+), 41 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 315fa56a78..0131442525 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -207,22 +207,11 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe FBSDKLoginManagerLoginResult *result = nil; NSError *error = parameters.error; - NSString *tokenString = parameters.accessTokenString; - BOOL cancelled = ((tokenString == nil) && (FBSDKAuthenticationToken.currentAuthenticationToken == nil)); - - BOOL challengePassed = YES; - if (expectChallenge) { - // Perform this check early so we be sure to clear expected challenge in all cases. - NSString *challengeReceived = parameters.challenge; - NSString *challengeExpected = [[self loadExpectedChallenge] stringByReplacingOccurrencesOfString:@"+" withString:@" "]; - if (![challengeExpected isEqualToString:challengeReceived]) { - challengePassed = NO; - } + NSString *accessTokenString = parameters.accessTokenString; + BOOL cancelled = ((accessTokenString == nil) && (parameters.authenticationToken == nil)); - // Don't overwrite an existing error, if any. - if (!error && !cancelled && !challengePassed) { - error = [NSError fbErrorForFailedLoginWithCode:FBSDKLoginErrorBadChallengeString]; - } + if (expectChallenge && !cancelled && !error) { + error = [self _verifyChallengeWithCompletionParameters:parameters]; } [self storeExpectedChallenge:nil]; @@ -232,13 +221,18 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe NSSet *grantedPermissions = parameters.permissions; NSSet *declinedPermissions = parameters.declinedPermissions; + // Recent permissions are largely based on the existence of an access token + // without an access token the 'recent' permissions will match the + // intersect of the granted permissions and the requested permissions. + // This is important because we want to create a 'result' that accurately reflects + // the currently granted permissions even when there is no access token. [self determineRecentlyGrantedPermissions:&recentlyGrantedPermissions recentlyDeclinedPermissions:&recentlyDeclinedPermissions forGrantedPermission:grantedPermissions declinedPermissions:declinedPermissions]; if (recentlyGrantedPermissions.count > 0) { - if (!tokenString) { + if (!accessTokenString) { // If there is no token string then create a 'tokenless' result // from the returned permissions result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil @@ -246,7 +240,7 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe grantedPermissions:grantedPermissions declinedPermissions:declinedPermissions]; } else { - FBSDKAccessToken *token = [[FBSDKAccessToken alloc] initWithTokenString:tokenString + FBSDKAccessToken *token = [[FBSDKAccessToken alloc] initWithTokenString:accessTokenString permissions:grantedPermissions.allObjects declinedPermissions:declinedPermissions.allObjects expiredPermissions:@[] @@ -285,13 +279,48 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe } } - if (result.token) { - [FBSDKAccessToken setCurrentAccessToken:result.token]; - } + [self _setGlobalPropertiesWithParameters:parameters result:result]; [self invokeHandler:result error:error]; } +- (void)_setGlobalPropertiesWithParameters:(FBSDKLoginCompletionParameters *)parameters + result:(FBSDKLoginManagerLoginResult *)result +{ + BOOL hasNewAuthenticationToken = (parameters.authenticationToken != nil); + BOOL hasNewOrUpdatedAccessToken = (result.token != nil); + + if (!hasNewAuthenticationToken && !hasNewOrUpdatedAccessToken) { + // Assume cancellation. Don't do anything + } else { + [self _setSharedAuthenticationToken:parameters.authenticationToken + accessToken:result.token + profile:parameters.profile]; + } +} + +/// Helper for setting global properties +- (void)_setSharedAuthenticationToken:(FBSDKAuthenticationToken *_Nullable)authToken + accessToken:(FBSDKAccessToken *_Nullable)accessToken + profile:(FBSDKProfile *_Nullable)profile +{ + FBSDKAuthenticationToken.currentAuthenticationToken = authToken; + FBSDKAccessToken.currentAccessToken = accessToken; + FBSDKProfile.currentProfile = profile; +} + +/// Returns an error if a stored challenge cannot be obtained from the completion parameters +- (NSError *)_verifyChallengeWithCompletionParameters:(FBSDKLoginCompletionParameters *)parameters +{ + NSString *challengeReceived = parameters.challenge; + NSString *challengeExpected = [[self loadExpectedChallenge] stringByReplacingOccurrencesOfString:@"+" withString:@" "]; + if (![challengeExpected isEqualToString:challengeReceived]) { + return [NSError fbErrorForFailedLoginWithCode:FBSDKLoginErrorBadChallengeString]; + } else { + return nil; + } +} + - (void)determineRecentlyGrantedPermissions:(NSSet **)recentlyGrantedPermissionsRef recentlyDeclinedPermissions:(NSSet **)recentlyDeclinedPermissionsRef forGrantedPermission:(NSSet *)grantedPermissions diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h index 4fdf144557..9a0138cc56 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h @@ -24,9 +24,12 @@ @interface FBSDKLoginCompletionParameters () +@property (nonatomic) FBSDKAuthenticationToken *authenticationToken; +@property (nonatomic) FBSDKProfile *profile; + @property (nonatomic, copy) NSString *accessTokenString; @property (nonatomic, copy) NSString *nonceString; -@property (nonatomic, copy) NSString *idTokenString; +@property (nonatomic, copy) NSString *authenticationTokenString; @property (nonatomic, copy) NSSet *permissions; @property (nonatomic, copy) NSSet *declinedPermissions; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h index ef63296153..44568353fe 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h @@ -22,8 +22,12 @@ #import -@class FBSDKLoginManager; +@class FBSDKAuthenticationToken; @class FBSDKLoginCompletionParameters; +@class FBSDKLoginManager; +@class FBSDKProfile; + +NS_ASSUME_NONNULL_BEGIN /** Success Block @@ -33,7 +37,7 @@ NS_SWIFT_NAME(LoginCompletionParametersBlock); /** Structured interface for accessing the parameters used to complete a log in request. - If \c accessTokenString is non-nil, the authentication succeeded. If \c error is + If \c authenticationTokenString is non-nil, the authentication succeeded. If \c error is non-nil the request failed. If both are \c nil, the request was cancelled. */ NS_SWIFT_NAME(LoginCompletionParameters) @@ -42,9 +46,12 @@ NS_SWIFT_NAME(LoginCompletionParameters) - (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithError:(NSError *)error; +@property (nonatomic, readonly) FBSDKAuthenticationToken *authenticationToken; +@property (nonatomic, readonly) FBSDKProfile *profile; + @property (nonatomic, copy, readonly) NSString *accessTokenString; @property (nonatomic, copy, readonly) NSString *nonceString; -@property (nonatomic, copy, readonly) NSString *idTokenString; +@property (nonatomic, copy, readonly) NSString *authenticationTokenString; @property (nonatomic, copy, readonly) NSSet *permissions; @property (nonatomic, copy, readonly) NSSet *declinedPermissions; @@ -77,7 +84,7 @@ NS_SWIFT_NAME(LoginCompleting) See the implementing class's documentation for whether it completes synchronously or asynchronously. */ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler - nonce:(NSString *)nonce; + nonce:(nullable NSString *)nonce; @end @@ -101,4 +108,6 @@ NS_SWIFT_NAME(LoginURLCompleter) @end +NS_ASSUME_NONNULL_END + #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 8ee39baeaf..8532c1d097 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -132,9 +132,16 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; + BOOL hasNonEmptyNonceString = [parameters[@"nonce"] length] > 0; + BOOL hasNonEmptyIdTokenString = [parameters[@"id_token"] length] > 0; + + // TODO: T81282385 - Error if nonce and ID Token + // Nonce and id token are mutually exclusive parameters + // BOOL isInvalid = (hasNonEmptyNonceString && hasNonEmptyIdTokenString); + if ([parameters[@"access_token"] length] > 0 - || [parameters[@"nonce"] length] > 0 - || [parameters[@"id_token"] length] > 0) { + || hasNonEmptyNonceString + || hasNonEmptyIdTokenString) { [self setParametersWithDictionary:parameters appID:appID]; } else { [self setErrorWithDictionary:parameters]; @@ -148,23 +155,22 @@ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler [self completeLoginWithHandler:handler nonce:nil]; } +/// Performs the work needed to populate the login completion parameters before they +/// are used to determine login success, failure or cancellation. - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler - nonce:(NSString *)nonce + nonce:(nullable NSString *)nonce { + // If there is a nonceString then it means we logged in from the app. if (_parameters.nonceString) { [self exchangeNonceForTokenWithHandler:handler]; return; - } else if (_parameters.idTokenString && nonce) { - FBSDKAuthenticationTokenBlock completion = ^(FBSDKAuthenticationToken *token) { - if (token) { - [FBSDKAuthenticationToken setCurrentAuthenticationToken:token]; - FBSDKProfile.currentProfile = [FBSDKLoginURLCompleter createProfileWithToken:token]; - } else { - self->_parameters.error = [FBSDKError errorWithCode:FBSDKLoginErrorInvalidIDToken message:@"Invalid ID token from login response."]; - } - handler(self->_parameters); - }; - [[FBSDKAuthenticationTokenFactory new] createTokenFromTokenString:_parameters.idTokenString nonce:nonce completion:completion]; + } else if (_parameters.authenticationTokenString && !nonce) { + // If there is no nonce then somehow an auth token string was provided + // but the call did not originate from the sdk. This is not a valid state + _parameters.error = [FBSDKError errorWithCode:FBSDKLoginErrorUnknown message:@"Please try to login again"]; + handler(_parameters); + } else if (_parameters.authenticationTokenString && nonce) { + [self fetchAndSetPropertiesForParameters:_parameters nonce:nonce handler:handler]; return; } else if (_parameters.accessTokenString && !_parameters.userID) { void (^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; @@ -172,9 +178,26 @@ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler handlerCopy(self->_parameters); }); return; + } else { + handler(_parameters); } +} - handler(_parameters); +/// Sets authenticationToken and profile onto the provided parameters and calls the provided completion handler +- (void)fetchAndSetPropertiesForParameters:(nonnull FBSDKLoginCompletionParameters *)parameters + nonce:(nonnull NSString *)nonce + handler:(FBSDKLoginCompletionParametersBlock)handler +{ + FBSDKAuthenticationTokenBlock completion = ^(FBSDKAuthenticationToken *token) { + if (token) { + parameters.authenticationToken = token; + parameters.profile = [FBSDKLoginURLCompleter createProfileWithToken:token]; + } else { + parameters.error = [FBSDKError errorWithCode:FBSDKLoginErrorInvalidIDToken message:@"Invalid ID token from login response."]; + } + handler(parameters); + }; + [[FBSDKAuthenticationTokenFactory new] createTokenFromTokenString:_parameters.authenticationTokenString nonce:nonce completion:completion]; } - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString *)appID @@ -187,7 +210,7 @@ - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString * _parameters.accessTokenString = parameters[@"access_token"]; _parameters.nonceString = parameters[@"nonce"]; - _parameters.idTokenString = parameters[@"id_token"]; + _parameters.authenticationTokenString = parameters[@"id_token"]; // check the string length so that we assign an empty set rather than a set with an empty string _parameters.permissions = (grantedPermissionsString.length > 0) From 4619bffd7d48664c3230086f39a43e9a8aa9884a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 10 Dec 2020 21:03:47 -0800 Subject: [PATCH 168/227] Remove unreachable code Summary: $title All calls coming from app switching will include a nonce string that will be exchanged for an access token. This assumes that app switching returns an access token which it will not. Reviewed By: ppansy Differential Revision: D25446407 fbshipit-source-id: 4d721ad1406a0f98734b2cdf39f5d45ad27d0d47 --- .../Internal/FBSDKLoginCompletion.m | 67 ------------------- 1 file changed, 67 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 8532c1d097..b7766654e2 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -39,67 +39,6 @@ - (NSDictionary *)claims; @end -static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *parameters, void (^completionBlock)(void)) -{ - __block NSUInteger pendingCount = 1; - void (^didCompleteBlock)(void) = ^{ - if (--pendingCount == 0) { - completionBlock(); - } - }; - - NSString *tokenString = parameters.accessTokenString; - FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; - - pendingCount++; - FBSDKGraphRequest *userIDRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" - parameters:@{ @"fields" : @"id" } - tokenString:tokenString - HTTPMethod:nil - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; - - [connection addRequest:userIDRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, - id result, - NSError *error) { - parameters.userID = result[@"id"]; - if (error) { - parameters.error = error; - } - didCompleteBlock(); - }]; - - pendingCount++; - FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/permissions" - parameters:@{@"fields" : @""} - tokenString:tokenString - HTTPMethod:nil - flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; - - [connection addRequest:permissionsRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, - id result, - NSError *error) { - NSMutableSet *grantedPermissions = [NSMutableSet set]; - NSMutableSet *declinedPermissions = [NSMutableSet set]; - NSMutableSet *expiredPermissions = [NSMutableSet set]; - - [FBSDKInternalUtility extractPermissionsFromResponse:result - grantedPermissions:grantedPermissions - declinedPermissions:declinedPermissions - expiredPermissions:expiredPermissions]; - - parameters.permissions = [grantedPermissions copy]; - parameters.declinedPermissions = [declinedPermissions copy]; - parameters.expiredPermissions = [expiredPermissions copy]; - if (error) { - parameters.error = error; - } - didCompleteBlock(); - }]; - - [connection start]; - didCompleteBlock(); -} - @implementation FBSDKLoginCompletionParameters - (instancetype)init @@ -172,12 +111,6 @@ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler } else if (_parameters.authenticationTokenString && nonce) { [self fetchAndSetPropertiesForParameters:_parameters nonce:nonce handler:handler]; return; - } else if (_parameters.accessTokenString && !_parameters.userID) { - void (^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; - FBSDKLoginRequestMeAndPermissions(_parameters, ^{ - handlerCopy(self->_parameters); - }); - return; } else { handler(_parameters); } From 973f9e535f6dc8c9c60a66b9d68c1867d67d650e Mon Sep 17 00:00:00 2001 From: Nolan O'Brien Date: Fri, 11 Dec 2020 09:27:46 -0800 Subject: [PATCH 169/227] Unit Test Hardening - FBSDKAppEventsTests.m Summary: Harden `FBSDKAppEventsTests.m` and `FBSDKAppEvents` in general **1) Ensure no networking** Already stubbed with *OHHTTPStubs* **2) Ensure no singleton accessing** Instead of replacing the `self.appEventsMock` with a partial mock of `[FBSDKAppEvents singleton]`, we can partially mock a fresh instance (w/ `alloc/init`) in `FBSDKTestCase` itself (benefitting all unit tests that would access `self.appEventsMock`). Then, we can stub `[FBSDKAppEvents singleton]` to return the partial mock instead of the singleton instance, also benefitting all unit tests that would access `[FBSDKAppEvents singleton]` As cleanup, we can eliminate the `resetSingleton` `DEBUG` code that was being used but was not effective across all unit tests. **3) Ensure the mocks are cleaned up** Cleanup of mocking/stubbing will happen on during `-tearDown` of `FBSDKTestCase` superclass. Cleanup of the *OHHTTPStubs* stubbing will happen during `tearDown` Reviewed By: joesus Differential Revision: D25479013 fbshipit-source-id: 2b4111a4ed8696ec8f1e0df2b88cb2547549d6dd --- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 14 -------------- .../Internal/FBSDKAppEvents+Internal.h | 4 ---- .../FBSDKApplicationDelegateTests.m | 1 - .../Internal/AppEvents/FBSDKAppEventsTests.m | 10 +++++++--- .../AppEvents/FBSDKAppEventsUtilityTests.m | 2 ++ .../FBSDKRestrictiveDataFilterTests.m | 6 +++--- .../Internal/Helpers/FBSDKTestCase.h | 6 +++--- .../Internal/Helpers/FBSDKTestCase.m | 18 ++++++++++++------ 8 files changed, 27 insertions(+), 34 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index 99a7ef6dcb..476f243212 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -920,23 +920,9 @@ + (void)logImplicitEvent:(NSString *)eventName accessToken:accessToken]; } -#ifdef DEBUG -static dispatch_once_t *onceTokenPointer; -+ (void)resetSingleton -{ - if (onceTokenPointer) { - *onceTokenPointer = 0; - } -} - -#endif - + (FBSDKAppEvents *)singleton { static dispatch_once_t onceToken; -#ifdef DEBUG - onceTokenPointer = &onceToken; -#endif static FBSDKAppEvents *shared = nil; dispatch_once(&onceToken, ^{ shared = [[self alloc] init]; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h index d099b7ce1e..a2e8b1a48e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h @@ -203,10 +203,6 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventsWKWebViewMessagesPixelIDKey; @property (class, nonatomic, readonly, strong) FBSDKAppEvents *singleton; -#ifdef DEBUG -+ (void)resetSingleton; -#endif - + (void)logInternalEvent:(FBSDKAppEventName)eventName isImplicitlyLogged:(BOOL)isImplicitlyLogged; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index 0e03fb40a1..d5a6696f37 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -80,7 +80,6 @@ - (void)setUp [_delegate resetApplicationObserverCache]; - [self stubAppEventsSingletonWith:self.appEventsMock]; [self stubLoadingAdNetworkReporterConfiguration]; [self stubServerConfigurationFetchingWithConfiguration:FBSDKServerConfigurationFixtures.defaultConfig error:nil]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index 4a6ad276d2..2fd28f2108 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -110,6 +110,8 @@ @implementation FBSDKAppEventsTests - (void)setUp { + self.shouldAppEventsMockBePartial = YES; + [super setUp]; [self stubLoadingAdNetworkReporterConfiguration]; @@ -122,8 +124,6 @@ - (void)setUp [FBSDKAppEvents setLoggingOverrideAppID:_mockAppID]; - self.appEventsMock = OCMPartialMock([FBSDKAppEvents singleton]); - // Mock FBSDKAppEventsUtility methods [self stubAppEventsUtilityShouldDropAppEventWith:NO]; @@ -136,7 +136,11 @@ - (void)tearDown [super tearDown]; [OHHTTPStubs removeAllStubs]; - [FBSDKAppEvents resetSingleton]; +} + +- (void)testAppEventsMockIsSingleton +{ + XCTAssertEqual(self.appEventsMock, [FBSDKAppEvents singleton]); } - (void)testLogPurchaseFlush diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m index 07b105789c..d4f1a0370a 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsUtilityTests.m @@ -48,6 +48,8 @@ @implementation FBSDKAppEventsUtilityTests - (void)setUp { + self.shouldAppEventsMockBePartial = YES; + [super setUp]; [self stubServerConfigurationFetchingWithConfiguration:[FBSDKServerConfiguration defaultServerConfigurationForAppID:nil] error:nil]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m index ccd8495d81..625b4d8e36 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/Integrity/FBSDKRestrictiveDataFilterTests.m @@ -51,6 +51,8 @@ @implementation FBSDKRestrictiveDataFilterTests - (void)setUp { + self.shouldAppEventsMockBePartial = YES; + [super setUp]; NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:@{ @@ -74,9 +76,7 @@ - (void)setUp [self stubAllocatingGraphRequestConnection]; [self stubLoadingAdNetworkReporterConfiguration]; - FBSDKAppEvents *appEvents = FBSDKAppEvents.singleton; - appEvents.disableTimer = YES; - [self stubAppEventsSingletonWith:appEvents]; + [self.appEventsMock setDisableTimer:YES]; [FBSDKRestrictiveDataFilterManager enable]; } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 5634ea8327..55bd7b4872 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -62,6 +62,9 @@ Also, to get a better understanding of mocking, please read the documentation at /// Used for sharing a common app identifier between tests. This is not a valid FB App ID @property (nullable, assign) NSString *appID; +/// Used during `-setUp` to determine the type of mock for `appEventsMock` (partial or nice), default is `NO` +@property (assign) BOOL shouldAppEventsMockBePartial; + /// Used for sharing an `FBSDKAppEvents` mock between tests @property (nullable, assign) id appEventsMock; @@ -212,9 +215,6 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `NSNotificationCenter.defaultCenter` and returns the provided notification center - (void)stubDefaultNotificationCenterWith:(NSNotificationCenter *)notificationCenter; -/// Stubs `AppEvents.singleton` and return the provided app events instance -- (void)stubAppEventsSingletonWith:(FBSDKAppEvents *)appEventsInstance; - /// Stubs `MeasurementEventListener.defaultListener` and returns the provided listener. - (void)stubDefaultMeasurementEventListenerWith:(FBSDKMeasurementEventListener *)eventListener; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index faf8ebb855..b0359975ed 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -246,7 +246,18 @@ - (void)setUpServerConfigurationManagerMock - (void)setUpAppEventsMock { - _appEventsMock = OCMClassMock(FBSDKAppEvents.class); + if (self.shouldAppEventsMockBePartial) { + // Since the `init` method is marked unavailable but just as a measure to prevent creating multiple + // instances and enforce the singleton pattern, we will circumvent that by casting to a plain `NSObject` + // after `alloc` in order to call `init`. + _appEventsMock = OCMPartialMock([(NSObject *)[FBSDKAppEvents alloc] init]); + } else { + _appEventsMock = OCMClassMock([FBSDKAppEvents class]); + } + + // Since numerous areas in FBSDK can end up calling `[FBSDKAppEvents singleton]`, + // we will stub the singleton accessor out for our mock instance. + OCMStub([_appEventsMock singleton]).andReturn(_appEventsMock); _appEventStatesMock = OCMClassMock([FBSDKAppEventsState class]); OCMStub([_appEventStatesMock alloc]).andReturn(_appEventStatesMock); @@ -481,11 +492,6 @@ - (void)stubDefaultNotificationCenterWith:(NSNotificationCenter *)notificationCe OCMStub(ClassMethod([_nsNotificationCenterClassMock defaultCenter])).andReturn(notificationCenter); } -- (void)stubAppEventsSingletonWith:(FBSDKAppEvents *)appEventsInstance -{ - OCMStub([_appEventsMock singleton]).andReturn(appEventsInstance); -} - - (void)stubDefaultMeasurementEventListenerWith:(FBSDKMeasurementEventListener *)eventListener { OCMStub([_measurementEventListenerClassMock defaultListener]).andReturn(eventListener); From 82ee6e49b7961b8cc42e5ac7227c51bad8f017cb Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 11 Dec 2020 10:38:20 -0800 Subject: [PATCH 170/227] Pull logout endpoint upon app launch Summary: After each app launch, pull the server to check if the current Authentication token is still valid. Log the user out of the returned status is not authorized Reviewed By: joesus Differential Revision: D25452718 fbshipit-source-id: d31151fe4acaa6825594752d7b1f02340cbceb4e --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 16 +++ .../FBSDKCoreKit/FBSDKApplicationDelegate.m | 1 + .../FBSDKAuthenticationStatusUtility.h | 30 ++++ .../FBSDKAuthenticationStatusUtility.m | 103 ++++++++++++++ .../FBSDKAuthenticationToken+Internal.h | 2 +- .../Internal/FBSDKCoreKit+Internal.h | 3 + .../FBSDKAuthenticationStatusUtilityTests.m | 134 ++++++++++++++++++ 7 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index cd8165e605..b2dc94f886 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -788,6 +788,11 @@ C67BED2A257F1A6300D356C9 /* ProfilePictureViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C67BED29257F1A6300D356C9 /* ProfilePictureViewTests.swift */; }; C6A308BD257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */; }; C6A308D8257AD227003C52FD /* FBSDKAuthenticationTokenFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */; }; + C6C5CBCC2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */; }; + C6C5CBCD2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */; }; + C6C5CBDC2581875600AA3BB3 /* FBSDKAuthenticationStatusUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6C5CBDB2581875600AA3BB3 /* FBSDKAuthenticationStatusUtilityTests.m */; }; + C6C5CBF7258192E800AA3BB3 /* FBSDKAuthenticationStatusUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */; }; + C6C5CC05258192ED00AA3BB3 /* FBSDKAuthenticationStatusUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */; }; C77C07A62486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */; }; E4416C0123F61902009CCBFA /* FBSDKModelParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */; }; E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4416C0023F61902009CCBFA /* FBSDKModelParser.mm */; }; @@ -1549,6 +1554,9 @@ C67BED29257F1A6300D356C9 /* ProfilePictureViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePictureViewTests.swift; sourceTree = ""; }; C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationTokenFactory.h; sourceTree = ""; }; C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenFactory.m; sourceTree = ""; }; + C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationStatusUtility.m; sourceTree = ""; }; + C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationStatusUtility.h; sourceTree = ""; }; + C6C5CBDB2581875600AA3BB3 /* FBSDKAuthenticationStatusUtilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationStatusUtilityTests.m; sourceTree = ""; }; C77C07A52486BAC600345460 /* FBSDKRestrictiveDataFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKRestrictiveDataFilterTests.m; sourceTree = ""; }; E4416BFF23F61902009CCBFA /* FBSDKModelParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKModelParser.h; sourceTree = ""; }; E4416C0023F61902009CCBFA /* FBSDKModelParser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FBSDKModelParser.mm; sourceTree = ""; }; @@ -2016,6 +2024,8 @@ 52963A9B215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h */, 894C0ACD1A6F0D3F009137EF /* FBSDKApplicationDelegate+Internal.h */, C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */, + C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */, + C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */, C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */, C5188DF8222F388400F4D8BC /* FBSDKApplicationObserving.h */, 89D05AA71AA1134000609300 /* FBSDKAudioResourceLoader.h */, @@ -2087,6 +2097,7 @@ isa = PBXGroup; children = ( C6381619257EDF2100B7690F /* FBSDKAuthenticationTokenFactoryTests.m */, + C6C5CBDB2581875600AA3BB3 /* FBSDKAuthenticationStatusUtilityTests.m */, 40853B9324C8C43300A7CB16 /* FBSDKJSONValueTests.m */, 9D18A8D91A95403F00A41042 /* AppEvents */, 7E5557391A8D833800344F86 /* AppLinks */, @@ -2989,6 +3000,7 @@ F40F6562241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h in Headers */, F9CBE51324E085E70097B442 /* FBSDKSKAdNetworkReporter.h in Headers */, 5DB7B07D230363190012E8CB /* FBSDKInstrumentManager.h in Headers */, + C6C5CBF7258192E800AA3BB3 /* FBSDKAuthenticationStatusUtility.h in Headers */, 81B71D631D19C87400933E93 /* FBSDKProfile+Internal.h in Headers */, 5D41131F229F27DD002FF65A /* FBSDKRestrictiveDataFilterManager.h in Headers */, F4D8D8DD2422887600C28384 /* FBSDKMonitorNetworker.h in Headers */, @@ -3202,6 +3214,7 @@ FD9E154D23777AC900A005EC /* FBSDKModelRuntime.hpp in Headers */, 9D0BC1571A8D23E200BE8BA4 /* FBSDKAppEvents.h in Headers */, C57044CF24E26678009637AD /* FBSDKUserDataStore.h in Headers */, + C6C5CBCD2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h in Headers */, 9DC658951A6EE5C500B85AAF /* FBSDKGraphRequest.h in Headers */, C5188DF9222F388400F4D8BC /* FBSDKApplicationObserving.h in Headers */, 894C0AF61A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */, @@ -4040,6 +4053,7 @@ 81B71D401D19C87400933E93 /* FBSDKWebDialogView.m in Sources */, 81B71D411D19C87400933E93 /* FBSDKErrorConfiguration.m in Sources */, C4FC99F2202CD56D0038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, + C6C5CC05258192ED00AA3BB3 /* FBSDKAuthenticationStatusUtility.m in Sources */, F4F98C5424CB820A00F0D6EC /* FBSDKSafeCast.m in Sources */, 52D4F0BC1D91A18D0030B7FC /* FBSDKDeviceRequestsHelper.m in Sources */, 81B71D421D19C87400933E93 /* FBSDKKeychainStoreViaBundleID.m in Sources */, @@ -4171,6 +4185,7 @@ 894C0AF71A6F2278009137EF /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */, 89FB8C4B1A842A8A003CAE60 /* FBSDKWebDialogView.m in Sources */, 9D3AF4511A9EA4BE00EEF724 /* FBSDKErrorConfiguration.m in Sources */, + C6C5CBCC2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m in Sources */, 520223F81D83C8D200CE0AB5 /* FBSDKDeviceRequestsHelper.m in Sources */, 9DE1F3CE1A89D9CD00B54D98 /* FBSDKKeychainStoreViaBundleID.m in Sources */, 89830F301A7805E100226ABB /* FBSDKServerConfiguration.m in Sources */, @@ -4256,6 +4271,7 @@ F40B24B2247324BB0059351C /* RawServerConfigurationResponseFixtures.swift in Sources */, F41200D0255F45FE009E323F /* FBSDKBridgeAPI+ApplicationOpenUrlTests.m in Sources */, F46C4857243E34C600D03401 /* FBSDKMonitoringConfigurationTestHelper.swift in Sources */, + C6C5CBDC2581875600AA3BB3 /* FBSDKAuthenticationStatusUtilityTests.m in Sources */, F4EB31D32540A35800736B67 /* SampleGraphRequest.swift in Sources */, F402B062255C645600473083 /* FakeLoginManager.m in Sources */, F4D80B582565D6B3008CCAF0 /* FBSDKRestrictiveDataTests.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m index 0d1d43b20d..41c8db0311 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m @@ -264,6 +264,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( FBSDKAuthenticationToken *cachedAuthToken = FBSDKSettings.tokenCache.authenticationToken; [FBSDKAuthenticationToken setCurrentAuthenticationToken:cachedAuthToken]; + [FBSDKAuthenticationStatusUtility checkAuthenticationStatus]; #endif NSArray> *observers = [_applicationObservers allObjects]; BOOL handled = NO; diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.h new file mode 100644 index 0000000000..c43b4ec071 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.h @@ -0,0 +1,30 @@ +/* FBSDKAuthenticationTokenStatusChecker_h */ +// 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 + +@interface FBSDKAuthenticationStatusUtility : NSObject + +/** + Fetches the latest authentication status from server. This will invalidate + the current user session if the returned status is not authorized. + */ ++ (void)checkAuthenticationStatus; + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m new file mode 100644 index 0000000000..1fb1d2adba --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m @@ -0,0 +1,103 @@ +// 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. + +#if !TARGET_OS_TV + +#import "FBSDKAuthenticationStatusUtility.h" + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +#import "FBSDKAuthenticationToken+Internal.h" + +static NSString *const FBSDKFacebookDomain = @"facebook.com"; +static NSString *const FBSDKOIDCStatusPath = @"/platform/oidc/status"; + +@implementation FBSDKAuthenticationStatusUtility + ++ (void)checkAuthenticationStatus +{ + NSURL *requestURL = [self _requestURL]; + if (!requestURL) { + return; + } + + NSURLRequest *request = [NSURLRequest requestWithURL:requestURL]; + if (request) { + [[NSURLSession.sharedSession dataTaskWithRequest:request + completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + if (!error) { + fb_dispatch_on_main_thread(^{ + [self _handleResponse:response]; + }); + } else { + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorNetworkRequests + formatString:@"%@", [error localizedDescription]]; + } + }] resume]; + } +} + ++ (void)_handleResponse:(NSURLResponse *)response +{ + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if ([httpResponse respondsToSelector:@selector(allHeaderFields)]) { + NSDictionary *header = [httpResponse allHeaderFields]; + NSString *status = [FBSDKTypeUtility dictionary:header objectForKey:@"fb-s" ofType:NSString.class]; + if ([status isEqualToString:@"not_authorized"]) { + [self _invalidateCurrentSession]; + } + } +} + ++ (NSURL *)_requestURL +{ + FBSDKAuthenticationToken *token = FBSDKAuthenticationToken.currentAuthenticationToken; + + if (!token || !token.jti) { + return nil; + } + + NSDictionary *params = @{@"jti" : token.jti}; + NSError *urlError; + NSString *host; + + if (FBSDKSettings.facebookDomainPart.length > 0) { + host = [NSString stringWithFormat:@"m.%@.%@", FBSDKSettings.facebookDomainPart, FBSDKFacebookDomain]; + } else { + host = [NSString stringWithFormat:@"m.%@", FBSDKFacebookDomain]; + } + + NSURL *requestURL = [FBSDKInternalUtility URLWithScheme:@"https" + host:host path:FBSDKOIDCStatusPath queryParameters:params error:&urlError]; + return urlError == nil ? requestURL : nil; +} + ++ (void)_invalidateCurrentSession +{ + FBSDKAccessToken.currentAccessToken = nil; + FBSDKAuthenticationToken.currentAuthenticationToken = nil; + FBSDKProfile.currentProfile = nil; +} + +@end + +#endif diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h index 5835ae3122..34f79c3238 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN @interface FBSDKAuthenticationToken (Internal) - (NSDictionary *)claims; -- (NSString *)jit; +- (NSString *)jti; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 1da2e2d46f..4d97ce7cf2 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -36,6 +36,7 @@ #if !TARGET_OS_TV #import "FBSDKAudioResourceLoader.h" + #import "FBSDKAuthenticationStatusUtility.h" #import "FBSDKBridgeAPI.h" #import "FBSDKBridgeAPI+Internal.h" #import "FBSDKCloseIcon.h" @@ -70,6 +71,7 @@ #import "FBSDKAppEventsUtility.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" + #import "FBSDKAuthenticationStatusUtility.h" #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKBase64.h" #import "FBSDKButton+Subclass.h" @@ -119,6 +121,7 @@ #import "BridgeAPI/FBSDKBridgeAPI+Internal.h" #import "Cryptography/FBSDKCrypto.h" #import "FBSDKAudioResourceLoader.h" + #import "FBSDKAuthenticationStatusUtility.h" #import "FBSDKContainerViewController.h" #import "FBSDKMonotonicTime.h" #import "UI/FBSDKCloseIcon.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m new file mode 100644 index 0000000000..c980392ee8 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m @@ -0,0 +1,134 @@ +// 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 "FBSDKAuthenticationToken+Internal.h" +#import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKTestCase.h" + +@interface FBSDKAuthenticationToken (Testing) + ++ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token + shouldPostNotification:(BOOL)shouldPostNotification; + +@end + +@interface FBSDKProfile (Testing) + ++ (void)setCurrentProfile:(nullable FBSDKProfile *)profile + shouldPostNotification:(BOOL)shouldPostNotification; + +@end + +@interface FBSDKAuthenticationStatusUtility (Testing) + ++ (void)_handleResponse:(NSURLResponse *)response; ++ (NSURL *)_requestURL; + +@end + +@interface FBSDKAuthenticationStatusUtilityTests : FBSDKTestCase + +@end + +@implementation FBSDKAuthenticationStatusUtilityTests + +- (void)setUp +{ + [super setUp]; + [FBSDKAuthenticationToken setCurrentAuthenticationToken:SampleAuthenticationToken.validToken shouldPostNotification:NO]; + [FBSDKAccessToken setCurrentAccessToken:SampleAccessToken.validToken shouldDispatchNotif:NO]; + [FBSDKProfile setCurrentProfile:SampleUserProfile.valid shouldPostNotification:NO]; +} + +// MARK: checkAuthenticationStatus + +- (void)testCheckAuthenticationStatusWithNoToken +{ + [FBSDKAuthenticationToken setCurrentAuthenticationToken:nil shouldPostNotification:NO]; + + [FBSDKAuthenticationStatusUtility checkAuthenticationStatus]; + + XCTAssertNotNil(FBSDKAccessToken.currentAccessToken, @"Access token should not be cleared"); + XCTAssertNotNil(FBSDKProfile.currentProfile, @"Profile should not be cleared"); +} + +// MARK: _requestURL + +- (void)testRequestURL +{ + NSURL *url = [FBSDKAuthenticationStatusUtility _requestURL]; + + XCTAssertEqualObjects(url.host, @"m.facebook.com"); + XCTAssertEqualObjects(url.path, @"/platform/oidc/status"); + + NSDictionary *params = [FBSDKInternalUtility parametersFromFBURL:url]; + XCTAssertEqualObjects(params[@"jti"], FBSDKAuthenticationToken.currentAuthenticationToken.jti, @"Incorrent JTI parameter in request url"); +} + +// MARK: _handleResponse + +- (void)testHandleNotAuthorizedResponse +{ + NSURL *url = [NSURL URLWithString:@"m.facebook.com/platform/oidc/status/"]; + NSDictionary *header = @{@"fb-s" : @"not_authorized"}; + NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url + statusCode:200 + HTTPVersion:nil + headerFields:header]; + + [FBSDKAuthenticationStatusUtility _handleResponse:response]; + + XCTAssertNil(FBSDKAuthenticationToken.currentAuthenticationToken, @"Authentication token should be cleared when not authorized"); + XCTAssertNil(FBSDKAccessToken.currentAccessToken, @"Access token should be cleared when not authorized"); + XCTAssertNil(FBSDKProfile.currentProfile, @"Profile should be cleared when not authorized"); +} + +- (void)testHandleConnectedResponse +{ + NSURL *url = [NSURL URLWithString:@"m.facebook.com/platform/oidc/status/"]; + NSDictionary *header = @{@"fb-s" : @"connected"}; + NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url + statusCode:200 + HTTPVersion:nil + headerFields:header]; + + [FBSDKAuthenticationStatusUtility _handleResponse:response]; + + XCTAssertNotNil(FBSDKAuthenticationToken.currentAuthenticationToken, @"Authentication token should not be cleared when connected"); + XCTAssertNotNil(FBSDKAccessToken.currentAccessToken, @"Access token should not be cleared when connected"); + XCTAssertNotNil(FBSDKProfile.currentProfile, @"Profile should not be cleared when connected"); +} + +- (void)testHandleNoStatusResponse +{ + NSURL *url = [NSURL URLWithString:@"m.facebook.com/platform/oidc/status/"]; + NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url + statusCode:200 + HTTPVersion:nil + headerFields:@{}]; + + [FBSDKAuthenticationStatusUtility _handleResponse:response]; + + XCTAssertNotNil(FBSDKAuthenticationToken.currentAuthenticationToken, @"Authentication token should not be cleared when no status returned"); + XCTAssertNotNil(FBSDKAccessToken.currentAccessToken, @"Access token should not be cleared when no status returned"); + XCTAssertNotNil(FBSDKProfile.currentProfile, @"Profile should not be cleared when no status returned"); +} + +@end From e64024187fdeac39cf7b9094f9d5dc59aea62469 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 11 Dec 2020 11:16:05 -0800 Subject: [PATCH 171/227] Back out "Add beta login parameter" Summary: Original commit changeset: 8113cfe17eb2 Reviewed By: joesus Differential Revision: D25499779 fbshipit-source-id: b7a3109fe37bc6b863b2d72a5190d5462f820c06 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 1 - FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 2 -- 2 files changed, 3 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 0131442525..bcb1087b12 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -411,7 +411,6 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co NSString *responseType; if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { responseType = @"id_token"; - [FBSDKTypeUtility dictionary:loginParams setObject:@"beta_login" forKey:@"tp"]; } else { responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; } diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 57ab9fb543..6176d4a6ae 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -467,7 +467,6 @@ - (void)testBetaLoginExperienceEnabledLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertNotNil(params[@"nonce"]); - XCTAssertNil(params[@"tp"]); } - (void)testBetaLoginExperienceRestrictedLoginParams @@ -482,7 +481,6 @@ - (void)testBetaLoginExperienceRestrictedLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); - XCTAssertEqualObjects(params[@"tp"], @"beta_login"); } - (void)testlogInParametersFromURL From f1dad7c2200687b8e292d082d3d17bd6b058fa98 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 11 Dec 2020 11:19:30 -0800 Subject: [PATCH 172/227] Add authentication token to login manager result Summary: Adding authentication token as an extra field in FBSDKLoginManagerResult Reviewed By: joesus Differential Revision: D25488848 fbshipit-source-id: 7bbeec35d56cc70cd6a66ff3f0e740d39ba6663c --- .../FBSDKLoginKit/FBSDKLoginManager.m | 4 + .../FBSDKLoginManagerLoginResult.h | 9 ++ .../FBSDKLoginManagerLoginResult.m | 2 + .../FBSDKLoginManagerTests.m | 130 +++++++++++++----- 4 files changed, 110 insertions(+), 35 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index bcb1087b12..3c9912ca18 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -144,6 +144,7 @@ - (void)raiseLoginException:(NSException *)exception - (void)handleImplicitCancelOfLogIn { FBSDKLoginManagerLoginResult *result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil + authenticationToken:nil isCancelled:YES grantedPermissions:NSSet.set declinedPermissions:NSSet.set]; @@ -236,6 +237,7 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe // If there is no token string then create a 'tokenless' result // from the returned permissions result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil + authenticationToken:parameters.authenticationToken isCancelled:NO grantedPermissions:grantedPermissions declinedPermissions:declinedPermissions]; @@ -251,6 +253,7 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe dataAccessExpirationDate:parameters.dataAccessExpirationDate graphDomain:parameters.graphDomain]; result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:token + authenticationToken:parameters.authenticationToken isCancelled:NO grantedPermissions:recentlyGrantedPermissions declinedPermissions:recentlyDeclinedPermissions]; @@ -273,6 +276,7 @@ - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expe } result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil + authenticationToken:nil isCancelled:cancelled grantedPermissions:NSSet.set declinedPermissions:declinedPermissions]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.h index d87d0f66f2..be4279098f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.h @@ -34,6 +34,7 @@ NS_ASSUME_NONNULL_BEGIN @interface LoginManagerLoginResult : NSObject @property (copy, nonatomic, nullable) FBSDKAccessToken *token; +@property (copy, nonatomic, nullable) FBSDKAuthenticationToken *authenticationToken; @property (readonly, nonatomic) BOOL isCancelled; @property (copy, nonatomic) NSSet *grantedPermissions; @property (copy, nonatomic) NSSet *declinedPermissions; @@ -43,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN #else @class FBSDKAccessToken; +@class FBSDKAuthenticationToken; /** Describes the result of a login attempt. @@ -58,6 +60,11 @@ NS_SWIFT_NAME(LoginManagerLoginResult) */ @property (copy, nonatomic, nullable) FBSDKAccessToken *token; +/** + the authentication token. + */ +@property (copy, nonatomic, nullable) FBSDKAuthenticationToken *authenticationToken; + /** whether the login was cancelled by the user. */ @@ -80,11 +87,13 @@ NS_SWIFT_NAME(LoginManagerLoginResult) /** Initializes a new instance. @param token the access token + @param authenticationToken the authentication token @param isCancelled whether the login was cancelled by the user @param grantedPermissions the set of granted permissions @param declinedPermissions the set of declined permissions */ - (instancetype)initWithToken:(nullable FBSDKAccessToken *)token + authenticationToken:(nullable FBSDKAuthenticationToken *)authenticationToken isCancelled:(BOOL)isCancelled grantedPermissions:(NSSet *)grantedPermissions declinedPermissions:(NSSet *)declinedPermissions diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m index 708685570b..d1e22771eb 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m @@ -34,6 +34,7 @@ @implementation FBSDKLoginManagerLoginResult } - (instancetype)initWithToken:(FBSDKAccessToken *)token + authenticationToken:(FBSDKAuthenticationToken *)authenticationToken isCancelled:(BOOL)isCancelled grantedPermissions:(NSSet *)grantedPermissions declinedPermissions:(NSSet *)declinedPermissions @@ -41,6 +42,7 @@ - (instancetype)initWithToken:(FBSDKAccessToken *)token if ((self = [super init])) { _mutableLoggingExtras = [NSMutableDictionary dictionary]; _token = token ? [token copy] : nil; + _authenticationToken = authenticationToken; _isCancelled = isCancelled; _grantedPermissions = [grantedPermissions copy]; _declinedPermissions = [declinedPermissions copy]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 6176d4a6ae..1496660e5e 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -67,6 +67,9 @@ @implementation FBSDKLoginManagerTests id _mockAccessTokenClass; id _mockAuthenticationTokenClass; id _mockProfileClass; + + NSDictionary *_claims; + NSDictionary *_header; } - (void)setUp @@ -88,6 +91,25 @@ - (void)setUp _mockAccessTokenClass = OCMClassMock(FBSDKAccessToken.class); _mockAuthenticationTokenClass = OCMClassMock(FBSDKAuthenticationToken.class); _mockProfileClass = OCMClassMock(FBSDKProfile.class); + + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + _claims = @{ + @"iss" : @"https://facebook.com/dialog/oauth", + @"aud" : kFakeAppID, + @"nonce" : kFakeNonce, + @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later + @"iat" : @(currentTime - 60), // 1 min ago + @"jti" : kFakeJTI, + @"sub" : @"1234", + @"name" : @"Test User", + @"email" : @"email@email.com", + @"picture" : @"https://www.facebook.com/some_picture", + }; + + _header = @{ + @"alg" : @"RS256", + @"typ" : @"JWT" + }; } - (void)tearDown @@ -315,50 +337,28 @@ - (void)testOpenURLWithNoChallengeAndError }]; } -- (void)testOpenURLAuthWithIDToken +- (void)testOpenURLAuthWithAuthenticationToken { XCTestExpectation *expectation = [self expectationWithDescription:self.name]; FBSDKLoginManager *target = _mockLoginManager; [FBSDKAuthenticationTokenFactory setSkipSignatureVerification:YES]; - long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; - NSDictionary *expectedClaims = @{ - @"iss" : @"https://facebook.com/dialog/oauth", - @"aud" : kFakeAppID, - @"nonce" : kFakeNonce, - @"exp" : @(currentTime + 60 * 60 * 48), // 2 days later - @"iat" : @(currentTime - 60), // 1 min ago - @"jti" : kFakeJTI, - @"sub" : @"1234", - @"name" : @"Test User", - @"picture" : @"https://www.facebook.com/some_picture", - }; - NSData *expectedClaimsData = [FBSDKTypeUtility dataWithJSONObject:expectedClaims options:0 error:nil]; - NSString *encodedClaims = [FBSDKBase64 encodeData:expectedClaimsData]; - NSDictionary *expectedHeader = @{ - @"alg" : @"RS256", - @"typ" : @"JWT" - }; - NSData *expectedHeaderData = [FBSDKTypeUtility dataWithJSONObject:expectedHeader options:0 error:nil]; - NSString *encodedHeader = [FBSDKBase64 encodeData:expectedHeaderData]; + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; + NSString *encodedClaims = [FBSDKBase64 encodeData:claimsData]; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; + NSString *encodedHeader = [FBSDKBase64 encodeData:headerData]; NSString *tokenString = [NSString stringWithFormat:@"%@.%@.%@", encodedHeader, encodedClaims, @"signature"]; - NSURL *url = [self authorizeURLWithFragment:[NSString stringWithFormat:@"id_token=%@", tokenString] challenge:kFakeChallenge]; + NSURL *url = [self authorizeURLWithFragment:[NSString stringWithFormat:@"granted_scopes=public_profile,email&id_token=%@", tokenString] challenge:kFakeChallenge]; [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { - // XCTAssertFalse(result.isCancelled); + XCTAssertFalse(result.isCancelled); - FBSDKAuthenticationToken *authToken = FBSDKAuthenticationToken.currentAuthenticationToken; - XCTAssertNotNil(authToken, @"An Authentication token should be created after successful login"); - XCTAssertEqualObjects(authToken.tokenString, tokenString, @"A raw authentication token string should be stored"); - XCTAssertEqualObjects(authToken.nonce, kFakeNonce, @"The nonce claims in the authentication token should be stored"); - XCTAssertEqualObjects(authToken.jti, kFakeJTI, @"The jit on the auth token should be derived from the claims"); + FBSDKAuthenticationToken *authToken = result.authenticationToken; + XCTAssertEqualObjects(authToken, FBSDKAuthenticationToken.currentAuthenticationToken); + [self validateAuthenticationToken:authToken expectedTokenString:tokenString]; - FBSDKProfile *profile = [FBSDKProfile currentProfile]; - XCTAssertNotNil(profile, @"user profile should be updated"); - XCTAssertEqualObjects(profile.name, expectedClaims[@"name"], @"failed to parse user name"); - XCTAssertEqualObjects(profile.userID, expectedClaims[@"sub"], @"failed to parse userID"); - XCTAssertEqualObjects(profile.imageURL.absoluteString, expectedClaims[@"picture"], @"failed to parse user profile picture"); + [self validateProfile:FBSDKProfile.currentProfile]; [expectation fulfill]; }]; @@ -372,9 +372,9 @@ - (void)testOpenURLAuthWithIDToken [FBSDKAuthenticationTokenFactory setSkipSignatureVerification:NO]; } -- (void)testOpenURLAuthWithInvalidIDToken +- (void)testOpenURLAuthWithInvalidAuthenticationToken { - XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + __block BOOL resultBlockInvoked = NO; FBSDKLoginManager *target = _mockLoginManager; NSURL *url = [self authorizeURLWithFragment:@"id_token=invalid_token" challenge:kFakeChallenge]; @@ -383,6 +383,46 @@ - (void)testOpenURLAuthWithInvalidIDToken OCMReject([self->_mockAccessTokenClass setCurrentAccessToken:OCMOCK_ANY]); OCMReject([self->_mockAuthenticationTokenClass setCurrentAuthenticationToken:OCMOCK_ANY]); OCMReject([self->_mockProfileClass setCurrentProfile:OCMOCK_ANY]); + resultBlockInvoked = YES; + }]; + + XCTAssertTrue([target application:nil openURL:url sourceApplication:@"com.apple.mobilesafari" annotation:nil]); + XCTAssertTrue(resultBlockInvoked, "Should invoke completion synchronously"); +} + +- (void)testOpenURLAuthWithAuthenticationTokenWithAccessToken +{ + XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + FBSDKLoginManager *target = _mockLoginManager; + [FBSDKAuthenticationTokenFactory setSkipSignatureVerification:YES]; + + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; + NSString *encodedClaims = [FBSDKBase64 encodeData:claimsData]; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; + NSString *encodedHeader = [FBSDKBase64 encodeData:headerData]; + + NSString *tokenString = [NSString stringWithFormat:@"%@.%@.%@", encodedHeader, encodedClaims, @"signature"]; + NSString *fragment = [@"granted_scopes=public_profile%2Cemail%2Cuser_friends&signed_request=ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0&access_token=sometoken&expires_in=5183949&id_token=" stringByAppendingString:tokenString]; + NSURL *url = [self authorizeURLWithFragment:fragment challenge:kFakeChallenge]; + + [target setHandler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTAssertFalse(result.isCancelled); + + FBSDKAuthenticationToken *authToken = result.authenticationToken; + XCTAssertEqualObjects(authToken, FBSDKAuthenticationToken.currentAuthenticationToken); + [self validateAuthenticationToken:authToken expectedTokenString:tokenString]; + + [self validateProfile:FBSDKProfile.currentProfile]; + + FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken]; + XCTAssertEqualObjects(accessToken, result.token); + XCTAssertEqualObjects(accessToken.userID, @"123", @"failed to parse userID"); + NSSet *permissions = [NSSet setWithObjects:@"public_profile", @"email", @"user_friends", nil]; + XCTAssertEqualObjects(accessToken.permissions, permissions, @"unexpected permissions"); + XCTAssertEqualObjects(result.grantedPermissions, permissions, @"unexpected permissions"); + XCTAssertFalse(accessToken.declinedPermissions.count, @"unexpected permissions"); + XCTAssertFalse(result.declinedPermissions.count, @"unexpected permissions"); + [expectation fulfill]; }]; @@ -391,6 +431,8 @@ - (void)testOpenURLAuthWithInvalidIDToken [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) { XCTAssertNil(error); }]; + + [FBSDKAuthenticationTokenFactory setSkipSignatureVerification:NO]; } - (void)testLoginManagerRetainsItselfForLoginMethod @@ -608,4 +650,22 @@ - (void)validateCommonLoginParameters:(NSDictionary *)params XCTAssertEqualWithAccuracy(cbt, currentMilliseconds, 500); } +- (void)validateAuthenticationToken:(FBSDKAuthenticationToken *)authToken + expectedTokenString:(NSString *)tokenString +{ + XCTAssertNotNil(authToken, @"An Authentication token should be created after successful login"); + XCTAssertEqualObjects(authToken.tokenString, tokenString, @"A raw authentication token string should be stored"); + XCTAssertEqualObjects(authToken.nonce, kFakeNonce, @"The nonce claims in the authentication token should be stored"); + XCTAssertEqualObjects(authToken.jti, kFakeJTI, @"The jit on the auth token should be derived from the claims"); +} + +- (void)validateProfile:(FBSDKProfile *)profile +{ + XCTAssertNotNil(profile, @"user profile should be updated"); + XCTAssertEqualObjects(profile.name, _claims[@"name"], @"failed to parse user name"); + XCTAssertEqualObjects(profile.userID, _claims[@"sub"], @"failed to parse userID"); + XCTAssertEqualObjects(profile.imageURL.absoluteString, _claims[@"picture"], @"failed to parse user profile picture"); + XCTAssertEqualObjects(profile.email, _claims[@"email"], @"failed to parse user email"); +} + @end From 89560f69163755d7d0c08ea89787cd7ac899022b Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Fri, 11 Dec 2020 18:15:02 -0800 Subject: [PATCH 173/227] Fix test errors Summary: Add nullability specifiers to get the test targets building again. Reviewed By: joesus Differential Revision: D25503287 fbshipit-source-id: 0ed815a7e842b9f0ed09c2f6b5b049c487f13131 --- .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 2 +- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 2 +- .../FBSDKCoreKitTests-Bridging-Header.h | 33 +++++++++---------- .../Helpers/SampleAuthenticationToken.swift | 2 +- .../ProfilePictureViewTests.swift | 2 +- .../FBSDKLoginKit/FBSDKLoginButton.m | 2 +- .../FBSDKLoginKitTests-Bridging-Header.h | 16 +++++---- .../FBSDKLoginKitTests/LoginButtonTests.swift | 2 +- 8 files changed, 31 insertions(+), 30 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index 8a02e9d243..a39b8a35d7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -69,7 +69,7 @@ - (instancetype)initWithTokenString:(NSString *)tokenString return self; } -+ (FBSDKAuthenticationToken *)currentAuthenticationToken ++ (nullable FBSDKAuthenticationToken *)currentAuthenticationToken { return g_currentAuthenticationToken; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index 05323152a2..bdea0bf342 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -95,7 +95,7 @@ - (instancetype)initWithUserID:(NSString *)userID return self; } -+ (FBSDKProfile *)currentProfile ++ (nullable FBSDKProfile *)currentProfile { return g_currentProfile; } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 9d6c4006ee..3697b52cf1 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -28,27 +28,22 @@ #import "FBSDKTestCase.h" #import "FakeBundle.h" +NS_ASSUME_NONNULL_BEGIN + // Interfaces for Swift extensions on Objective-C Test classes @interface FBSDKAppEventsUtilityTests : FBSDKTestCase @end // Categories needed to expose private methods to Swift @interface FBSDKAppEventsConfigurationManager (Testing) -+ (void)_processResponse:(id)response error:(NSError *)error; ++ (void)_processResponse:(id)response error:(nullable NSError *)error; @end @interface FBSDKCloseIcon (Testing) -- (UIImage *)imageWithSize:(CGSize)size - primaryColor:(UIColor *)primaryColor - secondaryColor:(UIColor *)secondaryColor - scale:(CGFloat)scale; -@end - -@interface FBSDKAuthenticationToken (Testing) -- (instancetype)initWithTokenString:(NSString *)tokenString - nonce:(NSString *)nonce - claims:(NSDictionary *)claims - jti:(NSString *)jti; +- (nullable UIImage *)imageWithSize:(CGSize)size + primaryColor:(UIColor *)primaryColor + secondaryColor:(UIColor *)secondaryColor + scale:(CGFloat)scale; @end NS_SWIFT_NAME(FBProfilePictureViewState) @@ -65,20 +60,22 @@ NS_SWIFT_NAME(FBProfilePictureViewState) @end @interface FBSDKAccessToken (Testing) -+ (void)setCurrentAccessToken:(FBSDKAccessToken *)token - shouldDispatchNotif:(BOOL)shouldDispatchNotif; ++ (void)setCurrentAccessToken:(nullable FBSDKAccessToken *)token + shouldDispatchNotif:(BOOL)shouldDispatchNotif; @end @interface FBSDKProfile (Testing) + (void)setCurrentProfile:(nullable FBSDKProfile *)profile - shouldPostNotification:(BOOL)shouldPostNotification; + shouldPostNotification:(BOOL)shouldPostNotification; @end @interface FBSDKAuthenticationToken (Testing) - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(NSDictionary *)claims + claims:(nullable NSDictionary *)claims jti:(NSString *)jti; -+ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token - shouldPostNotification:(BOOL)shouldPostNotification; ++ (void)setCurrentAuthenticationToken:(nullable FBSDKAuthenticationToken *)token + shouldPostNotification:(BOOL)shouldPostNotification; @end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift index bc9ac8f08d..65900e280d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift @@ -25,7 +25,7 @@ public class SampleAuthenticationToken: NSObject { nonce: "fakeNonce", claims: [:], jti: "fakeJTI" - )! // swiftlint:disable:this force_unwrapping + ) } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift index 14ce8ee913..aee27cea67 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift @@ -258,7 +258,7 @@ class TestView: FBProfilePictureView { super._updateImageWithProfile() } - override func _fetchAndSetImage(with url:URL?, state:FBProfilePictureViewState!) { + override func _fetchAndSetImage(with url:URL?, state:FBProfilePictureViewState) { fetchAndSetImageCount += 1 } } diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index 04c88c9be3..375f133b49 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -427,7 +427,7 @@ - (void)_fetchAndSetContent }]; } -- (void)_updateContentForUserProfile:(FBSDKProfile *)profile +- (void)_updateContentForUserProfile:(nullable FBSDKProfile *)profile { self.selected = profile != nil; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h index 0051e02f7d..b322db47da 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -21,6 +21,8 @@ #import "FBSDKLoginConfiguration.h" #import "FBSDKNonceUtility.h" +NS_ASSUME_NONNULL_BEGIN + // Categories needed to expose private methods to Swift @interface FBSDKLoginButton (Testing) @@ -29,15 +31,15 @@ - (void)_fetchAndSetContent; - (void)_initializeContent; - (void)_updateContentForAccessToken; -- (void)_updateContentForUserProfile:(FBSDKProfile *)profile; +- (void)_updateContentForUserProfile:(nullable FBSDKProfile *)profile; - (void)_accessTokenDidChangeNotification:(NSNotification *)notification; - (void)_profileDidChangeNotification:(NSNotification *)notification; -- (NSString *)userName; -- (NSString *)userID; +- (nullable NSString *)userName; +- (nullable NSString *)userID; @end @interface FBSDKAccessToken (Testing) -+ (void)setCurrentAccessToken:(FBSDKAccessToken *)token ++ (void)setCurrentAccessToken:(nullable FBSDKAccessToken *)token shouldDispatchNotif:(BOOL)shouldDispatchNotif; @end @@ -49,8 +51,10 @@ @interface FBSDKAuthenticationToken (Testing) - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(NSDictionary *)claims + claims:(nullable NSDictionary *)claims jti:(NSString *)jti; -+ (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token ++ (void)setCurrentAuthenticationToken:(nullable FBSDKAuthenticationToken *)token shouldPostNotification:(BOOL)shouldPostNotification; @end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift index 812a95b438..0c35f180d5 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift @@ -381,7 +381,7 @@ private class TestButton: FBLoginButton { super._updateContentForAccessToken() } - override func _updateContent(forUserProfile profile: Profile!) { + override func _updateContent(forUserProfile profile: Profile?) { updateContentForProfileCallCount += 1 super._updateContent(forUserProfile: profile) From 8de8dbd1d664383c6c9c2b428df2b4b1174c3b93 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 11 Dec 2020 20:20:17 -0800 Subject: [PATCH 174/227] Update beta login parameter value Summary: title Reviewed By: joesus Differential Revision: D25485075 fbshipit-source-id: 7a11c6223eb501ab2273a1122d33c9d8ee1ae956 --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 1 + FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 2 ++ 2 files changed, 3 insertions(+) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 3c9912ca18..084bc84c25 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -415,6 +415,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co NSString *responseType; if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { responseType = @"id_token"; + [FBSDKTypeUtility dictionary:loginParams setObject:@"sentinel_test_value" forKey:@"tp"]; } else { responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; } diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 1496660e5e..e743e09fd2 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -509,6 +509,7 @@ - (void)testBetaLoginExperienceEnabledLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertNotNil(params[@"nonce"]); + XCTAssertNil(params[@"tp"]); } - (void)testBetaLoginExperienceRestrictedLoginParams @@ -523,6 +524,7 @@ - (void)testBetaLoginExperienceRestrictedLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); + XCTAssertEqualObjects(params[@"tp"], @"sentinel_test_value"); } - (void)testlogInParametersFromURL From 6ca66cb4bc3aaa95bbaaeae1ff3651b9019fdfbe Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Sun, 13 Dec 2020 20:16:37 -0800 Subject: [PATCH 175/227] Do not hide claims behind debug macro Summary: We need to expose the claims symbol so that it is available in production builds. Reviewed By: KylinChang Differential Revision: D25525171 fbshipit-source-id: 3c1c3edaa423acb3cb61d8f32a2b21714cd9d1b3 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m | 10 +++++----- .../FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index a39b8a35d7..c1d9ee99f7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -88,6 +88,11 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token } } +- (NSDictionary *)claims +{ + return _claims; +} + - (NSString *)jti { return _jti; @@ -133,11 +138,6 @@ + (void)resetCurrentAuthenticationTokenCache g_currentAuthenticationToken = nil; } -- (NSDictionary *)claims -{ - return _claims; -} - #endif @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 4d97ce7cf2..79770883b1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -72,6 +72,7 @@ #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" #import "FBSDKAuthenticationStatusUtility.h" + #import "FBSDKAuthenticationToken+Internal.h" #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKBase64.h" #import "FBSDKButton+Subclass.h" @@ -152,6 +153,7 @@ #import "FBSDKAccessToken+Internal.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" + #import "FBSDKAuthenticationToken+Internal.h" #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKDeviceRequestsHelper.h" #import "FBSDKDynamicFrameworkLoader.h" From 0b88ca48f3558a1da21b1d1a36c3d0d3673de269 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Sun, 13 Dec 2020 22:07:40 -0800 Subject: [PATCH 176/227] Fixing Auth Token internal header Summary: $title Reviewed By: ppansy, KylinChang Differential Revision: D25526549 fbshipit-source-id: 52b1001038d4ce06b269bd2b27349941d7ef593e --- .../Internal/FBSDKAuthenticationToken+Internal.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h index 34f79c3238..d9dfcb9a43 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h @@ -18,7 +18,11 @@ #import -#import "FBSDKAuthenticationToken.h" +#if SWIFT_PACKAGE + #import "FBSDKAuthenticationToken.h" +#else + #import +#endif NS_ASSUME_NONNULL_BEGIN From 98c9c588b4e0efb045fadd4b494c00a12259c11a Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 14 Dec 2020 10:45:34 -0800 Subject: [PATCH 177/227] Add post-login heartbeat event to FB Login Summary: Currently our last client-side event is passing access token back to the app. If something suddenly breaks after this, we have no visibility. Similar to D24403530, adding a new event that will be logged 5 seconds after passing token back to the app. If app breaks after login, this event won't be logged and we'll see a sudden drop. Differential Revision: D25172326 fbshipit-source-id: af1a2de2a29b0e84d6815bf7539ee62078f69235 --- FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 1 + .../AppEvents/Internal/FBSDKAppEvents+Internal.h | 3 +++ FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 1 + .../FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h | 2 ++ .../FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m | 11 +++++++++++ 5 files changed, 18 insertions(+) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index 476f243212..9b6d866d0e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -175,6 +175,7 @@ FBSDKAppEventName FBSDKAppEventNameFBSessionAuthEnd = @"fb_mobile_login_complete"; FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodStart = @"fb_mobile_login_method_start"; FBSDKAppEventName FBSDKAppEventNameFBSessionAuthMethodEnd = @"fb_mobile_login_method_complete"; +FBSDKAppEventName FBSDKAppEventNameFBSessionAuthHeartbeat = @"fb_mobile_login_heartbeat"; FBSDKAppEventName FBSDKAppEventNameFBReferralStart = @"fb_referral_start"; FBSDKAppEventName FBSDKAppEventNameFBReferralEnd = @"fb_referral_end"; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h index a2e8b1a48e..f2adaaddb5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h @@ -79,6 +79,9 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionAuthMethodStart; /** Use to log the end of the last tried auth method as part of an auth request */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionAuthMethodEnd; +/** Use to log the post-login heartbeat event after the end of an auth request*/ +FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionAuthHeartbeat; + /** Use to log the start of a referral request */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBReferralStart; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 084bc84c25..9956d8dac8 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -357,6 +357,7 @@ - (void)invokeHandler:(FBSDKLoginManagerLoginResult *)result error:(NSError *)er { [_logger endLoginWithResult:result error:error]; [_logger endSession]; + [_logger postLoginHeartbeat]; _logger = nil; _state = FBSDKLoginManagerStateIdle; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h index e214e78ae0..eb133f696d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h @@ -44,6 +44,8 @@ NS_SWIFT_NAME(LoginManagerLogger) - (void)startAuthMethod:(NSString *)authMethod; - (void)endLoginWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error; +- (void)postLoginHeartbeat; + - (NSDictionary *)parametersWithTimeStampAndClientState:(NSDictionary *)loginParams forAuthMethod:(NSString *)authMethod; - (void)willAttemptAppSwitchingBehavior; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m index a345eab3ef..7792db82bc 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m @@ -120,6 +120,7 @@ - (void)startSessionForLoginManager:(FBSDKLoginManager *)loginManager - (void)endSession { [self logEvent:FBSDKAppEventNameFBSessionAuthEnd result:_lastResult error:_lastError]; + [FBSDKAppEvents flush]; } - (void)startAuthMethod:(NSString *)authMethod @@ -152,6 +153,16 @@ - (void)endLoginWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError [self logEvent:FBSDKAppEventNameFBSessionAuthMethodEnd result:resultString error:error]; } +- (void)postLoginHeartbeat +{ + [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(heartbestTimerDidFire) userInfo:nil repeats:NO]; +} + +- (void)heartbestTimerDidFire +{ + [self logEvent:FBSDKAppEventNameFBSessionAuthHeartbeat result:_lastResult error:_lastError]; +} + - (NSDictionary *)parametersWithTimeStampAndClientState:(NSDictionary *)loginParams forAuthMethod:(NSString *)authMethod { NSMutableDictionary *params = [loginParams mutableCopy]; From 96fe45e6ee25e349d08b70ac7b205909f5657994 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Mon, 14 Dec 2020 14:13:29 -0800 Subject: [PATCH 178/227] Fetch certificate from endpoint Summary: Fetches public key and uses it to verify signature. Reviewed By: joesus Differential Revision: D25349345 fbshipit-source-id: b40b7ce0d74cce3a3a13d461601125c86cb53bbf --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 10 + .../ViewHierarchy/FBSDKViewHierarchy.h | 3 - .../ViewHierarchy/FBSDKViewHierarchy.m | 18 -- .../FBSDKAuthenticationTokenFactory.m | 201 +++++++++++----- .../Internal/FBSDKInternalUtility.h | 13 ++ .../Internal/FBSDKInternalUtility.m | 35 ++- .../Internal/FBSDKSessionProviding.h | 45 ++++ .../FBSDKCoreKitTests-Bridging-Header.h | 1 + .../FBSDKAuthenticationTokenFactoryTests.m | 219 +++++++++++++++--- .../Helpers/FakeSessionProvider.swift | 51 ++++ .../FBSDKLoginManagerTests.m | 3 +- .../FBSDKCoreKit_Basics/FBSDKBasicUtility.m | 18 ++ .../include/FBSDKBasicUtility.h | 12 + 13 files changed, 512 insertions(+), 117 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSessionProviding.h create mode 100644 FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeSessionProvider.swift diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index b2dc94f886..5695afffd1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -941,6 +941,9 @@ F48AD348257700B80052C056 /* SampleAuthenticationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F48AD347257700B80052C056 /* SampleAuthenticationToken.swift */; }; F492C0A224E1F5F600BA21F7 /* KeychainStoreSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */; }; F492C0A324E1F5F600BA21F7 /* UserDefaultsSpy.m in Sources */ = {isa = PBXBuildFile; fileRef = F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */; }; + F494285D25829C72008FE009 /* FakeSessionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F494285C25829C72008FE009 /* FakeSessionProvider.swift */; }; + F494286B25829CE8008FE009 /* FBSDKSessionProviding.h in Headers */ = {isa = PBXBuildFile; fileRef = F494284025829B98008FE009 /* FBSDKSessionProviding.h */; }; + F494287925829CE8008FE009 /* FBSDKSessionProviding.h in Headers */ = {isa = PBXBuildFile; fileRef = F494284025829B98008FE009 /* FBSDKSessionProviding.h */; }; F496E58F24E49DBC006231A2 /* SampleAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */; }; F496E5FE24E5D0D5006231A2 /* FakeTokenCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E5FD24E5D0D5006231A2 /* FakeTokenCache.swift */; }; F496E60F24E5D195006231A2 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F496E60E24E5D195006231A2 /* SampleAccessToken.swift */; }; @@ -1620,6 +1623,8 @@ F492C09F24E1F5F600BA21F7 /* UserDefaultsSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserDefaultsSpy.h; sourceTree = ""; }; F492C0A024E1F5F600BA21F7 /* KeychainStoreSpy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainStoreSpy.swift; sourceTree = ""; }; F492C0A124E1F5F600BA21F7 /* UserDefaultsSpy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserDefaultsSpy.m; sourceTree = ""; }; + F494284025829B98008FE009 /* FBSDKSessionProviding.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKSessionProviding.h; sourceTree = ""; }; + F494285C25829C72008FE009 /* FakeSessionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeSessionProvider.swift; sourceTree = ""; }; F496E58E24E49DBC006231A2 /* SampleAppEvents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SampleAppEvents.swift; path = FBSDKCoreKitTests/Internal/Helpers/SampleAppEvents.swift; sourceTree = SOURCE_ROOT; }; F496E5FD24E5D0D5006231A2 /* FakeTokenCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeTokenCache.swift; sourceTree = ""; }; F496E60E24E5D195006231A2 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; @@ -2064,6 +2069,7 @@ 89FB8C3E1A842393003CAE60 /* UI */, 89FB8C431A842644003CAE60 /* WebDialog */, B301910D253622A2001A8DB0 /* FBSDKProfilePictureView+Internal.h */, + F494284025829B98008FE009 /* FBSDKSessionProviding.h */, ); path = Internal; sourceTree = ""; @@ -2760,6 +2766,7 @@ F402B061255C645600473083 /* FakeLoginManager.m */, F408C6E8256309A500372D61 /* FakeBridgeApiRequest.swift */, F44B051025645DAC0059A3A6 /* FakeDylibResolver.swift */, + F494285C25829C72008FE009 /* FakeSessionProvider.swift */, ); path = Helpers; sourceTree = ""; @@ -3039,6 +3046,7 @@ 52963AA92159A13400C7B252 /* FBSDKMeasurementEvent_Internal.h in Headers */, 81B71D7B1D19C87400933E93 /* FBSDKGraphRequest+Internal.h in Headers */, 81B71D7C1D19C87400933E93 /* FBSDKUtility.h in Headers */, + F494287925829CE8008FE009 /* FBSDKSessionProviding.h in Headers */, F420D1892433BABD00D4FA82 /* FBSDKMonitoringConfiguration.h in Headers */, 81B71D7D1D19C87400933E93 /* FBSDKApplicationDelegate.h in Headers */, 81B71D7F1D19C87400933E93 /* FBSDKColor.h in Headers */, @@ -3115,6 +3123,7 @@ 52963A7E215992F400C7B252 /* FBSDKAppLinkResolving.h in Headers */, 894C0AF31A6F21A1009137EF /* FBSDKBridgeAPIProtocol.h in Headers */, C5696F93209BBC35009C931F /* FBSDKEventBinding.h in Headers */, + F494286B25829CE8008FE009 /* FBSDKSessionProviding.h in Headers */, 5D90CDE62343D4D200AF326A /* FBSDKCrashShield.h in Headers */, 9DD50A3C1A9BBA1B0088AAAA /* FBSDKGraphErrorRecoveryProcessor.h in Headers */, 894C0B111A7021F8009137EF /* FBSDKBase64.h in Headers */, @@ -4259,6 +4268,7 @@ 40853B9424C8C43300A7CB16 /* FBSDKJSONValueTests.m in Sources */, F408C6E9256309A500372D61 /* FakeBridgeApiRequest.swift in Sources */, F4181B342416EC06006DB452 /* FBSDKMonitorTests.m in Sources */, + F494285D25829C72008FE009 /* FakeSessionProvider.swift in Sources */, 5C49DF9E2554C9ED00E0FD91 /* SampleUserProfile.swift in Sources */, F4BF22A0241954B400BFB494 /* FBSDKMonitorStoreTests.m in Sources */, 89C8B19C1A8D7A27009B07F5 /* FBSDKUtilityTests.swift in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.h index 48ecef7891..f0eac712c1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.h @@ -47,9 +47,6 @@ typedef NS_ENUM(NSUInteger, FBCodelessClassBitmask) { NS_ASSUME_NONNULL_BEGIN -extern void fb_dispatch_on_main_thread(dispatch_block_t block); -extern void fb_dispatch_on_default_thread(dispatch_block_t block); - NS_SWIFT_NAME(ViewHierarchy) @interface FBSDKViewHierarchy : NSObject diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m index b44d13c726..df11cde138 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/ViewHierarchy/FBSDKViewHierarchy.m @@ -34,24 +34,6 @@ NS_ASSUME_NONNULL_BEGIN -void fb_dispatch_on_main_thread(dispatch_block_t block) -{ - if (block != nil) { - if ([NSThread isMainThread]) { - block(); - } else { - dispatch_async(dispatch_get_main_queue(), block); - } - } -} - -void fb_dispatch_on_default_thread(dispatch_block_t block) -{ - if (block != nil) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); - } -} - _Nullable id getVariableFromInstance(NSObject *instance, NSString *variableName); @implementation FBSDKViewHierarchy diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m index 510c40fd77..0331157c9e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -34,8 +34,18 @@ #import +#import "FBSDKSessionProviding.h" + static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins +static NSString *const FBSDKDefaultDomain = @"facebook.com"; +static NSString *const FBSDKBeginCertificate = @"-----BEGIN CERTIFICATE-----"; +static NSString *const FBSDKEndCertificate = @"-----END CERTIFICATE-----"; + +typedef void (^FBSDKPublicCertCompletionBlock)(SecCertificateRef cert); +typedef void (^FBSDKPublicKeyCompletionBlock)(SecKeyRef key); +typedef void (^FBSDKVerifySignatureCompletionBlock)(BOOL success); + @interface FBSDKAuthenticationToken (FactoryInitializer) - (instancetype)initWithTokenString:(NSString *)tokenString @@ -50,13 +60,28 @@ @implementation FBSDKAuthenticationTokenFactory NSDictionary *_claims; NSDictionary *_header; NSString *_signature; + id _sessionProvider; +} + +- (instancetype)init +{ + self = [self initWithSessionProvider:NSURLSession.sharedSession]; + return self; +} + +- (instancetype)initWithSessionProvider:(id)sessionProvider +{ + if ((self = [super init])) { + _sessionProvider = sessionProvider; + } + return self; } - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString nonce:(NSString *)nonce completion:(FBSDKAuthenticationTokenBlock)completion { - if (!tokenString || tokenString.length == 0 || !nonce || nonce.length == 0) { + if (tokenString.length == 0 || nonce.length == 0) { completion(nil); return; } @@ -76,25 +101,30 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; claims = [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; + + // TODO: Make header a qualified object - T81294823 header = [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; + NSString *certificateKey = [FBSDKTypeUtility dictionary:header + objectForKey:@"kid" + ofType:NSString.class]; - if (!claims || !header) { + if (!claims || !header || !certificateKey) { completion(nil); return; } - // TODO: Add back when signatures can be consistently verified - T81105008 - // if (![self verifySignature:signature - // header:encodedHeader - // claims:encodedClaims]) { - // completion(nil); - // return; - // } - - FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc]initWithTokenString:tokenString - nonce:nonce - claims:claims]; - completion(token); + [self verifySignature:signature + header:encodedHeader + claims:encodedClaims + certificateKey:certificateKey + completion:^(BOOL success) { + if (success) { + FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:tokenString nonce:nonce claims:claims]; + completion(token); + } else { + completion(nil); + } + }]; } + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce @@ -140,73 +170,120 @@ + (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader return nil; } -- (BOOL)verifySignature:(NSString *)signature +- (void)verifySignature:(NSString *)signature header:(NSString *)header claims:(NSString *)claims + certificateKey:(NSString *)certificateKey + completion:(FBSDKVerifySignatureCompletionBlock)completion { #if DEBUG // skip signature checking for tests - if (_skipSignatureVerification) { - return YES; + if (_skipSignatureVerification && completion) { + completion(YES); } #endif - NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory base64FromBase64Url:signature]]; + NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory + base64FromBase64Url:signature]]; NSString *signedString = [NSString stringWithFormat:@"%@.%@", header, claims]; NSData *signedData = [signedString dataUsingEncoding:NSASCIIStringEncoding]; - SecKeyRef publicKey = [self getPublicKey]; - - if (publicKey && signatureData && signedData) { - OSStatus status = -1; - - size_t signatureBytesSize = SecKeyGetBlockSize(publicKey); - const void *signatureBytes = signatureData.bytes; - - size_t digestSize = CC_SHA256_DIGEST_LENGTH; - uint8_t digestBytes[digestSize]; - CC_SHA256(signedData.bytes, (CC_LONG)signedData.length, digestBytes); - - status = SecKeyRawVerify( - publicKey, - kSecPaddingPKCS1SHA256, - digestBytes, - digestSize, - signatureBytes, - signatureBytesSize - ); - return status == errSecSuccess; - } - return NO; + [self getPublicKeyWithCertificateKey:certificateKey + completion:^(SecKeyRef key) { + if (key && signatureData && signedData) { + size_t signatureBytesSize = SecKeyGetBlockSize(key); + const void *signatureBytes = signatureData.bytes; + + size_t digestSize = CC_SHA256_DIGEST_LENGTH; + uint8_t digestBytes[digestSize]; + CC_SHA256(signedData.bytes, (CC_LONG)signedData.length, digestBytes); + + OSStatus status = SecKeyRawVerify( + key, + kSecPaddingPKCS1SHA256, + digestBytes, + digestSize, + signatureBytes, + signatureBytesSize + ); + fb_dispatch_on_main_thread(^{ + completion(status == errSecSuccess); + }); + } else { + fb_dispatch_on_main_thread(^{ + completion(NO); + }); + } + }]; } -- (NSString *)getCertificate +- (void)getPublicKeyWithCertificateKey:(NSString *)certificateKey + completion:(FBSDKPublicKeyCompletionBlock)completion { - // TODO(T79340096): replace with certificate retrieved from crypto keychain service - return _cert; -} + [self getCertificateWithKey:certificateKey + completion:^(SecCertificateRef cert) { + SecKeyRef publicKey = nil; -- (SecKeyRef)getPublicKey -{ - SecKeyRef publicKey = nil; - NSData *certData = [FBSDKBase64 decodeAsData:[self getCertificate]]; - SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certData); + if (cert) { + SecPolicyRef policy = SecPolicyCreateBasicX509(); + OSStatus status = -1; + SecTrustRef trust; - if (cert) { - SecPolicyRef policy = SecPolicyCreateBasicX509(); - OSStatus status = -1; - SecTrustRef trust; + status = SecTrustCreateWithCertificates(cert, policy, &trust); - status = SecTrustCreateWithCertificates(cert, policy, &trust); + if (status == errSecSuccess && trust) { + publicKey = SecTrustCopyPublicKey(trust); + } - if (status == errSecSuccess && trust) { - publicKey = SecTrustCopyPublicKey(trust); - } + CFRelease(policy); + CFRelease(cert); + } - CFRelease(policy); - CFRelease(cert); - } + completion(publicKey); + }]; +} + +- (void)getCertificateWithKey:(NSString *)certificateKey + completion:(FBSDKPublicCertCompletionBlock)completion +{ + NSURLRequest *request = [NSURLRequest requestWithURL:[self _certificateEndpoint]]; + [[_sessionProvider dataTaskWithRequest:request + completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { + if (error || !data) { + return completion(nil); + } + + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + if (httpResponse.statusCode != 200) { + return completion(nil); + } + } + + SecCertificateRef result = NULL; + NSDictionary *certs = [FBSDKTypeUtility JSONObjectWithData:data options:0 error:nil]; + NSString *certString = [FBSDKTypeUtility dictionary:certs objectForKey:certificateKey ofType:NSString.class]; + if (!certString) { + return completion(nil); + } + certString = [certString stringByReplacingOccurrencesOfString:FBSDKBeginCertificate withString:@""]; + certString = [certString stringByReplacingOccurrencesOfString:FBSDKEndCertificate withString:@""]; + certString = [certString stringByReplacingOccurrencesOfString:@"\n" withString:@""]; + + NSData *secCertificateData = [[NSData alloc] initWithBase64EncodedString:certString options:0]; + result = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)secCertificateData); + completion(result); + }] resume]; +} + +- (NSURL *)_certificateEndpoint +{ + NSError *error; + NSURL *url = [FBSDKInternalUtility unversionedFacebookURLWithHostPrefix:@"m" + path:@"/.well-known/oauth/openid/certs/" + queryParameters:@{} + error:&error]; - return publicKey; + return url; } + (NSString *)base64FromBase64Url:(NSString *)base64Url diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h index 2a3bd210cc..d640606e9e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h @@ -124,6 +124,19 @@ NS_SWIFT_NAME(InternalUtility) defaultVersion:(NSString *)defaultVersion error:(NSError *__autoreleasing *)errorRef; +/** + Constructs a Facebook URL that doesn't need to specify an API version. + @param hostPrefix The prefix for the host, such as 'm', 'graph', etc. + @param path The path for the URL. This may or may not include a version. + @param queryParameters The query parameters for the URL. This will be converted into a query string. + @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. + @return The Facebook URL. + */ ++ (NSURL *)unversionedFacebookURLWithHostPrefix:(NSString *)hostPrefix + path:(NSString *)path + queryParameters:(NSDictionary *)queryParameters + error:(NSError *__autoreleasing *)errorRef; + /** Tests whether the supplied URL is a valid URL for opening in the browser. @param URL The URL to test. diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m index 594f264bf7..ba4a21f3de 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m @@ -156,6 +156,36 @@ + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix queryParameters:(NSDictionary *)queryParameters defaultVersion:(NSString *)defaultVersion error:(NSError *__autoreleasing *)errorRef +{ + NSString *version = (defaultVersion.length > 0) ? defaultVersion : [FBSDKSettings graphAPIVersion]; + if (version.length) { + version = [@"/" stringByAppendingString:version]; + } + + return [self _facebookURLWithHostPrefix:hostPrefix + path:path + queryParameters:queryParameters + defaultVersion:version + error:errorRef]; +} + ++ (NSURL *)unversionedFacebookURLWithHostPrefix:(NSString *)hostPrefix + path:(NSString *)path + queryParameters:(NSDictionary *)queryParameters + error:(NSError *__autoreleasing *)errorRef +{ + return [self _facebookURLWithHostPrefix:hostPrefix + path:path + queryParameters:queryParameters + defaultVersion:@"" + error:errorRef]; +} + ++ (NSURL *)_facebookURLWithHostPrefix:(NSString *)hostPrefix + path:(NSString *)path + queryParameters:(NSDictionary *)queryParameters + defaultVersion:(NSString *)version + error:(NSError *__autoreleasing *)errorRef { if (hostPrefix.length && ![hostPrefix hasSuffix:@"."]) { hostPrefix = [hostPrefix stringByAppendingString:@"."]; @@ -172,11 +202,6 @@ + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix } host = [NSString stringWithFormat:@"%@%@", hostPrefix ?: @"", host ?: @""]; - NSString *version = (defaultVersion.length > 0) ? defaultVersion : [FBSDKSettings graphAPIVersion]; - if (version.length) { - version = [@"/" stringByAppendingString:version]; - } - if (path.length) { NSScanner *versionScanner = [[NSScanner alloc] initWithString:path]; if ([versionScanner scanString:@"/v" intoString:NULL] diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSessionProviding.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSessionProviding.h new file mode 100644 index 0000000000..917e9f1204 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSessionProviding.h @@ -0,0 +1,45 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// An internal protocol used to describe a session data task +NS_SWIFT_NAME(SessionDataTask) +@protocol FBSDKSessionDataTask +- (void)resume; +- (void)cancel; +@end + +/// An internal protocol used to describe a url session +NS_SWIFT_NAME(SessionProviding) +@protocol FBSDKSessionProviding +- (id)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler; +@end + +// MARK: Default Protocol Conformances + +@interface NSURLSessionDataTask (SessionDataTask) +@end + +@interface NSURLSession (SessionProviding) +@end + + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 3697b52cf1..41ad33682d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -25,6 +25,7 @@ #import "FBSDKSKAdNetworkEvent.h" #import "FBSDKSKAdNetworkRule.h" #import "FBSDKServerConfigurationFixtures.h" +#import "FBSDKSessionProviding.h" #import "FBSDKTestCase.h" #import "FakeBundle.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index 3ad0659fc7..a83e813573 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -21,32 +21,34 @@ #import "FBSDKCoreKit+Internal.h" #import "FBSDKCoreKitTests-Swift.h" +#import "FBSDKSessionProviding.h" #import "FBSDKTestCase.h" static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; static NSString *const _encodedHeader = @"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; static NSString *const _encodedClaims = @"eyJzdWIiOiIxMjM0IiwibmFtZSI6IlRlc3QgVXNlciIsImlzcyI6Imh0dHBzOi8vZmFjZWJvb2suY29tL2RpYWxvZy9vYXV0aCIsImF1ZCI6IjQzMjEiLCJub25jZSI6InNvbWVfbm9uY2UiLCJleHAiOjE1MTYyNTkwMjIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zb21lX3BpY3R1cmUiLCJpYXQiOjE1MTYyMzkwMjJ9"; static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; +static NSString *const _certificateKey = @"some_key"; static NSString *const _mockAppID = @"4321"; static NSString *const _mockJTI = @"some_jti"; static NSString *const _mockNonce = @"some_nonce"; static NSString *const _facebookURL = @"https://facebook.com/dialog/oauth"; -@interface FBSDKAuthenticationTokenFactory (Testing) +typedef void (^FBSDKVerifySignatureCompletionBlock)(BOOL success); +@interface FBSDKAuthenticationTokenFactory (Testing) + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; + (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; - -- (void)setCertificate:(NSString *)certificate; - + (NSString *)base64FromBase64Url:(NSString *)base64Url; +- (instancetype)initWithSessionProvider:(id)sessionProvider; +- (void)setCertificate:(NSString *)certificate; - (BOOL)verifySignature:(NSString *)signature header:(NSString *)header - claims:(NSString *)claims; - + claims:(NSString *)claims + certificateKey:(NSString *)key + completion:(FBSDKVerifySignatureCompletionBlock)completion; - (NSDictionary *)claims; - @end @interface FBSDKAuthenticationTokenFactoryTests : FBSDKTestCase @@ -220,42 +222,178 @@ - (void)testDecodeEmptyHeader // MARK: - Verifying Signature -- (void)testVerifyValidSignatureShouldSucceed +- (void)testVerifySignatureWithoutDataWithoutResponseWithoutError { - FBSDKAuthenticationTokenFactory *factory = [FBSDKAuthenticationTokenFactory new]; - [factory setCertificate:_certificate]; + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + __block BOOL wasCalled = NO; + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + XCTAssertFalse( + success, + "A signature cannot be verified if the certificate request returns no data" + ); + wasCalled = YES; + }]; + + XCTAssertEqual( + dataTask.resumeCallCount, + 1, + "Should start the session data task when verifying a signature" + ); + XCTAssertTrue(wasCalled); +} - XCTAssertTrue( - [factory verifySignature:_signature - header:_encodedHeader - claims:_encodedClaims] +- (void)testVerifySignatureWithDataWithInvalidResponseWithoutError +{ + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.data = [@"foo" dataUsingEncoding:NSUTF8StringEncoding]; + session.urlResponse = [[NSHTTPURLResponse alloc] initWithURL:self.sampleURL statusCode:401 HTTPVersion:nil headerFields:nil]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + __block BOOL wasCalled = NO; + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + XCTAssertFalse( + success, + "A signature cannot be verified if the certificate request returns a non-200 response" + ); + wasCalled = YES; + }]; + + XCTAssertEqual( + dataTask.resumeCallCount, + 1, + "Should start the session data task when verifying a signature" ); + XCTAssertTrue(wasCalled); } -- (void)testVerifyInvalidSignatureShouldFail +- (void)testVerifySignatureWithInvalidDataWithValidResponseWithoutError { - FBSDKAuthenticationTokenFactory *factory = [FBSDKAuthenticationTokenFactory new]; - [factory setCertificate:_certificate]; + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.data = [@"foo" dataUsingEncoding:NSUTF8StringEncoding]; + session.urlResponse = [[NSHTTPURLResponse alloc] initWithURL:self.sampleURL statusCode:200 HTTPVersion:nil headerFields:nil]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + __block BOOL wasCalled = NO; + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + XCTAssertFalse( + success, + "A signature cannot be verified if the certificate request returns invalid data" + ); + wasCalled = YES; + }]; + + XCTAssertEqual( + dataTask.resumeCallCount, + 1, + "Should start the session data task when verifying a signature" + ); + XCTAssertTrue(wasCalled); +} - NSString *invalidSignature = @"hH0uCpIx0BhjT_djfI52wPMp0sYuHAHYOes4GVasXykHsZAeuidFYshiCd8O-KpAo5m9jZWbXdaSN0JMbpBIJ9TwSk6e8bhX-N6BRKl3EZRby6SsZtK9J2X6mWomgMCfJZD54McLIdDQaTTtNsV1kgzm8iksywaT3f1GdicqlJPZn3m83xF3toSdfKdPoJJCpM7IidPru7gF8aZchkE1d-dUzZ9mV0CPfsl5lX4M64f470nm6PzyynAvyKwUBKO3v3x08V17NV8OkRAjtGPRhbs_d4B6ifEXS3piWUlxVm6w27nPbdmKeCqjV-WRfIJ6lOvumR2F26I1soEwtEWq9g"; +- (void)testVerifySignatureWithValidDataWithValidResponseWithError +{ + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.data = [self validCertificateData]; + session.urlResponse = [[NSHTTPURLResponse alloc] initWithURL:self.sampleURL statusCode:200 HTTPVersion:nil headerFields:nil]; + session.error = [self sampleError]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + __block BOOL wasCalled = NO; + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + XCTAssertFalse( + success, + "A signature cannot be verified if the certificate request returns an error" + ); + wasCalled = YES; + }]; + + XCTAssertEqual( + dataTask.resumeCallCount, + 1, + "Should start the session data task when verifying a signature" + ); + XCTAssertTrue(wasCalled); +} - XCTAssertFalse( - [factory verifySignature:invalidSignature - header:_encodedHeader - claims:_encodedClaims] +- (void)testVerifySignatureWithValidDataWithValidResponseWithoutError +{ + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.data = [self validCertificateData]; + session.urlResponse = [[NSHTTPURLResponse alloc] initWithURL:self.sampleURL statusCode:200 HTTPVersion:nil headerFields:nil]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + __block BOOL wasCalled = NO; + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + XCTAssertTrue( + success, + "Should verify a signature when the response contains the expected key" + ); + wasCalled = YES; + }]; + + XCTAssertEqual( + dataTask.resumeCallCount, + 1, + "Should start the session data task when verifying a signature" ); + XCTAssertTrue(wasCalled); } -- (void)testVerifySignatureWithInvalidCertificateShouldFail +- (void)testVerifySignatureWithFuzzyData { - FBSDKAuthenticationTokenFactory *factory = [FBSDKAuthenticationTokenFactory new]; - [factory setCertificate:@"invalid_certification"]; + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.urlResponse = [[NSHTTPURLResponse alloc] initWithURL:self.sampleURL statusCode:200 HTTPVersion:nil headerFields:nil]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + for (int i = 0; i < 100; i++) { + NSDictionary *randomizedCertificates = [self randomizeDictionary:self.validRawCertificateResponse]; + NSData *data = [FBSDKTypeUtility dataWithJSONObject:randomizedCertificates options:0 error:nil]; + session.data = data; - XCTAssertFalse( + __block BOOL wasCalled = NO; [factory verifySignature:_signature header:_encodedHeader - claims:_encodedClaims] - ); + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + wasCalled = YES; + }]; + XCTAssertTrue(wasCalled); + } } // MARK: - Utilities @@ -320,4 +458,29 @@ - (NSDictionary *)randomizeDictionary:(NSDictionary *)dictionary return randomized; } +// MARK: - Helpers + +- (NSDictionary *)validRawCertificateResponse +{ + return @{ + _certificateKey : _certificate, + @"foo" : @"Not a certificate" + }; +} + +- (NSData *)validCertificateData +{ + return [FBSDKTypeUtility dataWithJSONObject:self.validRawCertificateResponse options:0 error:nil]; +} + +- (NSURL *)sampleURL +{ + return [NSURL URLWithString:@"https://example.com"]; +} + +- (NSError *)sampleError +{ + return [NSError errorWithDomain:self.name code:0 userInfo:nil]; +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeSessionProvider.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeSessionProvider.swift new file mode 100644 index 0000000000..c59bd3c46d --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FakeSessionProvider.swift @@ -0,0 +1,51 @@ +// 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. + +@objcMembers +public class FakeSessionDataTask: NSObject, SessionDataTask { + var resumeCallCount = 0 + var cancelCallCount = 0 + + public func resume() { + resumeCallCount += 1 + } + + public func cancel() { + cancelCallCount += 1 + } +} + +@objcMembers +public class FakeSessionProvider: NSObject, SessionProviding { + /// Data to return in a data task completion handler + var data: Data? + /// A url response to return in a data task completion handler + var urlResponse: URLResponse? + /// An error to return in a data task completion handler + var error: Error? + /// A data task to return from `dataTask(with:completion:)` + var stubbedDataTask: SessionDataTask? + + public func dataTask( + with request: URLRequest, + completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void + ) -> SessionDataTask { + completionHandler(data, urlResponse, error) + return stubbedDataTask ?? FakeSessionDataTask() + } +} diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index e743e09fd2..b6941c4f1e 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -108,7 +108,8 @@ - (void)setUp _header = @{ @"alg" : @"RS256", - @"typ" : @"JWT" + @"typ" : @"JWT", + @"kid" : @"abcd1234", }; } diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m b/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m index 4d58701a17..c27d8d81ab 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKBasicUtility.m @@ -28,6 +28,24 @@ static NSString *const FBSDK_BASICUTILITY_ANONYMOUSIDFILENAME = @"com-facebook-sdk-PersistedAnonymousID.json"; static NSString *const FBSDK_BASICUTILITY_ANONYMOUSID_KEY = @"anon_id"; +void fb_dispatch_on_main_thread(dispatch_block_t block) +{ + if (block != nil) { + if ([NSThread isMainThread]) { + block(); + } else { + dispatch_async(dispatch_get_main_queue(), block); + } + } +} + +void fb_dispatch_on_default_thread(dispatch_block_t block) +{ + if (block != nil) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); + } +} + @protocol BASIC_FBSDKError + (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message; diff --git a/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h b/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h index d18f44e037..37629ca23f 100644 --- a/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h +++ b/Sources/FBSDKCoreKit_Basics/include/FBSDKBasicUtility.h @@ -20,6 +20,18 @@ NS_ASSUME_NONNULL_BEGIN +/** + Dispatches the specified block on the main thread. + @param block the block to dispatch + */ +extern void fb_dispatch_on_main_thread(dispatch_block_t block); + +/** + Dispatches the specified block on the default thread. + @param block the block to dispatch + */ +extern void fb_dispatch_on_default_thread(dispatch_block_t block); + /** Describes the callback for appLinkFromURLInBackground. @param object the FBSDKAppLink representing the deferred App Link From 0725aebd2b53e97a1158d2da899db1e15d634808 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 14 Dec 2020 15:19:47 -0800 Subject: [PATCH 179/227] Handle logout failed error code for logout endpoint Summary: title Reviewed By: joesus Differential Revision: D25538425 fbshipit-source-id: 08f29bb67ecfe29b081af56408a97d13a27399e6 --- .../Internal/FBSDKAuthenticationStatusUtility.m | 5 +++++ .../FBSDKAuthenticationStatusUtilityTests.m | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m index 1fb1d2adba..327037c0af 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m @@ -59,6 +59,11 @@ + (void)checkAuthenticationStatus + (void)_handleResponse:(NSURLResponse *)response { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; + + if (httpResponse.statusCode != 200) { + return; + } + if ([httpResponse respondsToSelector:@selector(allHeaderFields)]) { NSDictionary *header = [httpResponse allHeaderFields]; NSString *status = [FBSDKTypeUtility dictionary:header objectForKey:@"fb-s" ofType:NSString.class]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m index c980392ee8..4105422d90 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m @@ -131,4 +131,20 @@ - (void)testHandleNoStatusResponse XCTAssertNotNil(FBSDKProfile.currentProfile, @"Profile should not be cleared when no status returned"); } +- (void)testHandleFailedResponse +{ + NSURL *url = [NSURL URLWithString:@"m.facebook.com/platform/oidc/status/"]; + NSDictionary *header = @{@"fb-s" : @"connected"}; + NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url + statusCode:401 + HTTPVersion:nil + headerFields:header]; + + [FBSDKAuthenticationStatusUtility _handleResponse:response]; + + XCTAssertNotNil(FBSDKAuthenticationToken.currentAuthenticationToken, @"Authentication token should not be cleared when the request failed"); + XCTAssertNotNil(FBSDKAccessToken.currentAccessToken, @"Access token should not be cleared when the request failed"); + XCTAssertNotNil(FBSDKProfile.currentProfile, @"Profile should not be cleared when the request failed"); +} + @end From 92ff94acaaaecf7192acb5d210a78cc1e950ed6e Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 14 Dec 2020 16:34:50 -0800 Subject: [PATCH 180/227] Add profile info for manual testers Summary: Also fixes removes unnecessary return statements that I missed earlier. Reviewed By: ppansy Differential Revision: D25507355 fbshipit-source-id: a83664ffdb31f314ee4bf983c31960cb11c21731 --- FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index b7766654e2..4843d8587b 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -102,7 +102,6 @@ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler // If there is a nonceString then it means we logged in from the app. if (_parameters.nonceString) { [self exchangeNonceForTokenWithHandler:handler]; - return; } else if (_parameters.authenticationTokenString && !nonce) { // If there is no nonce then somehow an auth token string was provided // but the call did not originate from the sdk. This is not a valid state @@ -110,7 +109,6 @@ - (void)completeLoginWithHandler:(FBSDKLoginCompletionParametersBlock)handler handler(_parameters); } else if (_parameters.authenticationTokenString && nonce) { [self fetchAndSetPropertiesForParameters:_parameters nonce:nonce handler:handler]; - return; } else { handler(_parameters); } From 876713f5b543b3b217901884a60e965b7b9727d3 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Tue, 15 Dec 2020 15:45:26 -0800 Subject: [PATCH 181/227] Add FBSDKAuthenticationClaims object Summary: Refactor claims from an NSDictionary to a custom object (FBSDKAuthenticationClaims) and update tests. Reviewed By: joesus Differential Revision: D25385509 fbshipit-source-id: 245417ff9dd855a5fe24acac2c14f52b820e2a59 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 14 +- .../FBSDKCoreKit/FBSDKAuthenticationToken.m | 26 ++-- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h | 1 + FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m | 2 +- .../Internal/Base64/FBSDKBase64.h | 7 + .../Internal/Base64/FBSDKBase64.m | 8 + .../FBSDKAuthenticationStatusUtility.m | 5 +- .../FBSDKAuthenticationToken+Internal.h | 4 +- .../Internal/FBSDKAuthenticationTokenClaims.h | 67 +++++++++ .../Internal/FBSDKAuthenticationTokenClaims.m | 141 ++++++++++++++++++ .../FBSDKAuthenticationTokenFactory.m | 57 +------ .../Internal/FBSDKCoreKit+Internal.h | 2 + .../FBSDKAuthenticationTokenTests.m | 2 +- .../FBSDKCoreKitTests-Bridging-Header.h | 15 +- .../Internal/Base64/FBSDKBase64Tests.swift | 6 + .../FBSDKAuthenticationTokenFactoryTests.m | 77 ++++++---- .../Helpers/SampleAuthenticationToken.swift | 2 +- .../Internal/FBSDKLoginCompletion.h | 1 + .../Internal/FBSDKLoginCompletion.m | 37 ++--- .../FBSDKLoginKitTests-Bridging-Header.h | 14 +- .../FBSDKLoginKitTests/LoginButtonTests.swift | 7 +- 21 files changed, 366 insertions(+), 129 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 5695afffd1..8d5b5f9664 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -184,6 +184,10 @@ 5DBC72D22373793400A9D859 /* FBSDKModelManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBC72D02373792A00A9D859 /* FBSDKModelManager.h */; }; 5DBC72D82373795600A9D859 /* FBSDKModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */; }; 5DBC72D92373795600A9D859 /* FBSDKModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */; }; + 5E47555D2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */; }; + 5E47555E2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */; }; + 5EF17EE52582DE3300FAA5D2 /* FBSDKAuthenticationTokenClaims.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */; }; + 5EF17F172582DE3D00FAA5D2 /* FBSDKAuthenticationTokenClaims.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */; }; 5F7063FB1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */; }; 5F7064091AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */; }; 7E253D811A8EAEF500CCCFE7 /* FBSDKInternalUtilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 893F44A51A6445C1001DB0B6 /* FBSDKInternalUtilityTests.m */; }; @@ -1303,6 +1307,8 @@ 5DBB0446227FEF700009E0A6 /* FBSDKBasicUtilityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBasicUtilityTests.m; sourceTree = ""; }; 5DBC72D02373792A00A9D859 /* FBSDKModelManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKModelManager.h; sourceTree = ""; }; 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = FBSDKModelManager.mm; sourceTree = ""; }; + 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationTokenClaims.h; sourceTree = ""; }; + 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenClaims.m; sourceTree = ""; }; 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsDeviceInfo.h; sourceTree = ""; }; 5F7064081AF7342600E42ED7 /* FBSDKAppEventsDeviceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAppEventsDeviceInfo.m; sourceTree = ""; }; 6BE0966D1AAE687F00CCD61A /* FBSDKServerConfigurationManager+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FBSDKServerConfigurationManager+Internal.h"; sourceTree = ""; }; @@ -2028,6 +2034,8 @@ 52963A9E215993C100C7B252 /* FBSDKAppLink_Internal.h */, 52963A9B215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h */, 894C0ACD1A6F0D3F009137EF /* FBSDKApplicationDelegate+Internal.h */, + 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */, + 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */, C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */, C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */, C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */, @@ -2953,6 +2961,7 @@ files = ( F916581624F6BB4D00BB759A /* FBSDKSKAdNetworkConversionConfiguration.h in Headers */, F943110424F8D613002441F1 /* FBSDKSKAdNetworkRule.h in Headers */, + 5EF17EE52582DE3300FAA5D2 /* FBSDKAuthenticationTokenClaims.h in Headers */, C638153D257EA7CC00B7690F /* FBSDKAuthenticationTokenFactory.h in Headers */, 81B71D481D19C87400933E93 /* FBSDKAppLinkUtility.h in Headers */, 81B71D491D19C87400933E93 /* FBSDKAppLinkResolver.h in Headers */, @@ -3102,7 +3111,6 @@ files = ( F9A06DB72510FAD3007E6386 /* FBSDKAppEventsConfiguration.h in Headers */, 7E30917B1AA92A95004E91D5 /* FBSDKAppLinkUtility.h in Headers */, - C6A308D8257AD227003C52FD /* FBSDKAuthenticationTokenFactory.h in Headers */, 7E5557381A8D833100344F86 /* FBSDKAppLinkResolver.h in Headers */, 9D32A8401A69941A000A936D /* FBSDKTokenCaching.h in Headers */, F9A06DCF2510FB0F007E6386 /* FBSDKAppEventsConfigurationManager.h in Headers */, @@ -3132,6 +3140,8 @@ 9D0BC1541A8D23DB00BE8BA4 /* FBSDKAppEvents+Internal.h in Headers */, 9D28F1931DB14DBB0057D709 /* FBSDKImageDownloader.h in Headers */, 9D3AF4501A9EA4BE00EEF724 /* FBSDKErrorConfiguration.h in Headers */, + C6A308D8257AD227003C52FD /* FBSDKAuthenticationTokenFactory.h in Headers */, + 5E47555D2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.h in Headers */, 9D0BC1511A8D236200BE8BA4 /* FBSDKTimeSpentData.h in Headers */, F952EA482339403900B20652 /* FBSDKMetadataIndexer.h in Headers */, 891687D21AB33CA200F55364 /* FBSDKIcon.h in Headers */, @@ -4019,6 +4029,7 @@ F468B32324C25AB600979F8D /* FBSDKCrashHandler.m in Sources */, 81B71D301D19C87400933E93 /* FBSDKAppLinkResolver.m in Sources */, F420D18F2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, + 5EF17F172582DE3D00FAA5D2 /* FBSDKAuthenticationTokenClaims.m in Sources */, 81B71D311D19C87400933E93 /* FBSDKIcon.m in Sources */, C638158A257EA8F000B7690F /* FBSDKAuthenticationTokenFactory.m in Sources */, F468B2A724C2457000979F8D /* FBSDKRestrictiveData.m in Sources */, @@ -4151,6 +4162,7 @@ F420D18E2433BABD00D4FA82 /* FBSDKMonitoringConfiguration.m in Sources */, 9DBA6A311A80265A00B4DE6A /* FBSDKColor.m in Sources */, E4416C0223F61902009CCBFA /* FBSDKModelParser.mm in Sources */, + 5E47555E2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m in Sources */, F468B35224C25AB600979F8D /* FBSDKLibAnalyzer.m in Sources */, C6A308BD257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m in Sources */, 7E5557371A8D833100344F86 /* FBSDKAppLinkResolver.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m index c1d9ee99f7..771d574809 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKAuthenticationToken.m @@ -32,6 +32,8 @@ #import "FBSDKCoreKit+Internal.h" #endif +#import "FBSDKAuthenticationTokenClaims.h" + static FBSDKAuthenticationToken *g_currentAuthenticationToken; NSString *const FBSDKAuthenticationTokenTokenStringCodingKey = @"FBSDKAuthenticationTokenTokenStringCodingKey"; @@ -40,24 +42,23 @@ @implementation FBSDKAuthenticationToken { - NSDictionary *_claims; + FBSDKAuthenticationTokenClaims *_claims; NSString *_jti; } - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(NSDictionary *)claims + claims:(nullable FBSDKAuthenticationTokenClaims *)claims { - self = [self initWithTokenString:tokenString + return [self initWithTokenString:tokenString nonce:nonce claims:claims - jti:claims[@"jti"]]; - return self; + jti:claims.jti]; } - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(NSDictionary *)claims + claims:(nullable FBSDKAuthenticationTokenClaims *)claims jti:(NSString *)jti { if ((self = [super init])) { @@ -88,14 +89,14 @@ + (void)setCurrentAuthenticationToken:(FBSDKAuthenticationToken *)token } } -- (NSDictionary *)claims +- (NSString *)jti { - return _claims; + return _jti; } -- (NSString *)jti +- (nullable FBSDKAuthenticationTokenClaims *)claims { - return _jti; + return _claims; } #pragma mark Storage @@ -116,10 +117,7 @@ - (instancetype)initWithCoder:(NSCoder *)decoder NSString *nonce = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenNonceCodingKey]; NSString *jti = [decoder decodeObjectOfClass:NSString.class forKey:FBSDKAuthenticationTokenJtiCodingKey]; - return [self initWithTokenString:tokenString - nonce:nonce - claims:nil - jti:jti]; + return [self initWithTokenString:tokenString nonce:nonce claims:nil jti:jti]; } - (void)encodeWithCoder:(NSCoder *)encoder diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h index 7076323f5d..e85324ec5d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h @@ -22,6 +22,7 @@ #import "FBSDKProfilePictureView.h" +@class FBSDKAuthenticationTokenClaims; @class FBSDKProfile; NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m index bdea0bf342..7edfac253b 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m @@ -100,7 +100,7 @@ + (nullable FBSDKProfile *)currentProfile return g_currentProfile; } -+ (void)setCurrentProfile:(FBSDKProfile *)profile ++ (void)setCurrentProfile:(nullable FBSDKProfile *)profile { [self setCurrentProfile:profile shouldPostNotification:YES]; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.h index ccc976e3fa..1378c226c3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.h @@ -49,4 +49,11 @@ NS_SWIFT_NAME(Base64) */ + (NSString *)encodeString:(NSString *)string; +/** + Encodes URL string into a base-64 representation. + @param base64Url The URL string to be encoded. + @return The base-64 encoded string. + */ ++ (NSString *)base64FromBase64Url:(NSString *)base64Url; + @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m index c4c27c46d6..726f868780 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m @@ -53,6 +53,14 @@ + (NSString *)encodeString:(NSString *)string return [_encoder encodeString:string]; } ++ (NSString *)base64FromBase64Url:(NSString *)base64Url +{ + NSString *base64 = [base64Url stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; + base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; + + return base64; +} + #pragma mark - Object Lifecycle #pragma mark - Implementation Methods diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m index 327037c0af..4c3dd2af81 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m @@ -92,7 +92,10 @@ + (NSURL *)_requestURL } NSURL *requestURL = [FBSDKInternalUtility URLWithScheme:@"https" - host:host path:FBSDKOIDCStatusPath queryParameters:params error:&urlError]; + host:host + path:FBSDKOIDCStatusPath + queryParameters:params + error:&urlError]; return urlError == nil ? requestURL : nil; } diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h index d9dfcb9a43..9e3bccf0b3 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationToken+Internal.h @@ -24,11 +24,13 @@ #import #endif +@class FBSDKAuthenticationTokenClaims; + NS_ASSUME_NONNULL_BEGIN @interface FBSDKAuthenticationToken (Internal) -- (NSDictionary *)claims; +- (nullable FBSDKAuthenticationTokenClaims *)claims; - (NSString *)jti; @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.h new file mode 100644 index 0000000000..b1d7cf2d5a --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.h @@ -0,0 +1,67 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKAuthenticationTokenClaims : NSObject + +/// A unique identifier for the token. +@property (nonatomic, readonly, strong) NSString *jti; + +/// Issuer Identifier for the Issuer of the response. +@property (nonatomic, readonly, strong) NSString *iss; + +/// Audience(s) that this ID Token is intended for. +@property (nonatomic, readonly, strong) NSString *aud; + +/// String value used to associate a Client session with an ID Token, and to mitigate replay attacks. +@property (nonatomic, readonly, strong) NSString *nonce; + +/// Expiration time on or after which the ID Token MUST NOT be accepted for processing. +@property (nonatomic, readonly, assign) long exp; + +/// Time at which the JWT was issued. +@property (nonatomic, readonly, assign) long iat; + +/// Subject - Identifier for the End-User at the Issuer. +@property (nonatomic, readonly, strong) NSString *sub; + +/// End-User's full name in displayable form including all name parts. +@property (nullable, nonatomic, readonly, strong) NSString *name; + +/// End-User's preferred e-mail address. +@property (nullable, nonatomic, readonly, strong) NSString *email; + +/// URL of the End-User's profile picture. +@property (nullable, nonatomic, readonly, strong) NSString *picture; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + Returns a new instance, when one can be created from the parameters given, otherwise `nil`. + @param encodedClaims Base64-encoded string of the claims. + @param nonce The expected nonce string. + */ ++ (nullable FBSDKAuthenticationTokenClaims *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m new file mode 100644 index 0000000000..fd82d1d197 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m @@ -0,0 +1,141 @@ +// 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 "FBSDKAuthenticationTokenClaims.h" + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins + +@implementation FBSDKAuthenticationTokenClaims + +- (instancetype)initWithJti:(NSString *)jti + iss:(NSString *)iss + aud:(NSString *)aud + nonce:(NSString *)nonce + exp:(long)exp + iat:(long)iat + sub:(NSString *)sub + name:(nullable NSString *)name + email:(nullable NSString *)email + picture:(nullable NSString *)picture +{ + if (self = [super init]) { + _jti = jti; + _iss = iss; + _aud = aud; + _nonce = nonce; + _exp = exp; + _iat = iat; + _sub = sub; + _name = name; + _email = email; + _picture = picture; + } + + return self; +} + ++ (nullable FBSDKAuthenticationTokenClaims *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)expectedNonce +{ + NSError *error; + NSData *claimsData = [FBSDKBase64 decodeAsData:[FBSDKBase64 base64FromBase64Url:encodedClaims]]; + + if (claimsData) { + NSDictionary *claimsDict = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; + if (!error) { + long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; + + // verify claims + NSString *jti = [FBSDKTypeUtility stringValue:claimsDict[@"jti"]]; + BOOL hasJti = jti.length > 0; + + NSString *iss = [FBSDKTypeUtility stringValue:claimsDict[@"iss"]]; + BOOL isFacebook = iss.length > 0 && [[[NSURL URLWithString:iss] host] isEqualToString:@"facebook.com"]; + + NSString *aud = [FBSDKTypeUtility stringValue:claimsDict[@"aud"]]; + BOOL audMatched = [aud isEqualToString:[FBSDKSettings appID]]; + + NSNumber *expValue = [FBSDKTypeUtility numberValue:claimsDict[@"exp"]]; + long exp = [expValue doubleValue]; + BOOL isExpired = expValue != nil && exp <= currentTime; + + NSNumber *iatValue = [FBSDKTypeUtility numberValue:claimsDict[@"iat"]]; + long iat = [iatValue doubleValue]; + BOOL issuedRecently = iatValue != nil && iat >= currentTime - MaxTimeSinceTokenIssued; + + NSString *nonce = [FBSDKTypeUtility stringValue:claimsDict[@"nonce"]]; + BOOL nonceMatched = nonce.length > 0 && [nonce isEqualToString:expectedNonce]; + + NSString *sub = [FBSDKTypeUtility stringValue:claimsDict[@"sub"]]; + BOOL userIDValid = sub.length > 0; + + NSString *name = [FBSDKTypeUtility stringValue:claimsDict[@"name"]]; + NSString *email = [FBSDKTypeUtility stringValue:claimsDict[@"email"]]; + NSString *picture = [FBSDKTypeUtility stringValue:claimsDict[@"picture"]]; + + if (hasJti && isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid) { + return [[FBSDKAuthenticationTokenClaims alloc] initWithJti:jti + iss:iss + aud:aud + nonce:nonce + exp:exp + iat:iat + sub:sub + name:name + email:email + picture:picture]; + } + } + } + + return nil; +} + +- (BOOL)isEqualToClaims:(FBSDKAuthenticationTokenClaims *)claims +{ + return [_jti isEqualToString:claims.jti] + && [_iss isEqualToString:claims.iss] + && [_aud isEqualToString:claims.aud] + && [_nonce isEqualToString:claims.nonce] + && _exp == claims.exp + && _iat == claims.iat + && [_sub isEqualToString:claims.sub] + && [_name isEqualToString:claims.name] + && [_email isEqualToString:claims.email] + && [_picture isEqualToString:claims.picture]; +} + +- (BOOL)isEqual:(id)object +{ + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[FBSDKAuthenticationTokenClaims class]]) { + return NO; + } + + return [self isEqualToClaims:(FBSDKAuthenticationTokenClaims *)object]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m index 0331157c9e..19ebd69625 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -34,10 +34,9 @@ #import +#import "FBSDKAuthenticationTokenClaims.h" #import "FBSDKSessionProviding.h" -static long const MaxTimeSinceTokenIssued = 10 * 60; // 10 mins - static NSString *const FBSDKDefaultDomain = @"facebook.com"; static NSString *const FBSDKBeginCertificate = @"-----BEGIN CERTIFICATE-----"; static NSString *const FBSDKEndCertificate = @"-----END CERTIFICATE-----"; @@ -50,7 +49,7 @@ @interface FBSDKAuthenticationToken (FactoryInitializer) - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(NSDictionary *)claims; + claims:(nullable FBSDKAuthenticationTokenClaims *)claims; @end @@ -87,7 +86,7 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString } NSString *signature; - NSDictionary *claims; + FBSDKAuthenticationTokenClaims *claims; NSDictionary *header; NSArray *segments = [tokenString componentsSeparatedByString:@"."]; @@ -100,9 +99,7 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString NSString *encodedClaims = [FBSDKTypeUtility array:segments objectAtIndex:1]; signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; - claims = [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; - - // TODO: Make header a qualified object - T81294823 + claims = [FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; header = [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; NSString *certificateKey = [FBSDKTypeUtility dictionary:header objectForKey:@"kid" @@ -127,38 +124,10 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString }]; } -+ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce -{ - NSError *error; - NSData *claimsData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory base64FromBase64Url:encodedClaims]]; - - if (claimsData) { - NSDictionary *claims = [FBSDKTypeUtility JSONObjectWithData:claimsData options:0 error:&error]; - if (!error) { - long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; - - // verify claims - BOOL isFacebook = [claims[@"iss"] isKindOfClass:[NSString class]] && [[[NSURL URLWithString:claims[@"iss"]] host] isEqualToString:@"facebook.com"]; - BOOL audMatched = [claims[@"aud"] isKindOfClass:[NSString class]] && [claims[@"aud"] isEqualToString:[FBSDKSettings appID]]; - BOOL isExpired = [claims[@"exp"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"exp"] longValue] <= currentTime; - BOOL issuedRecently = [claims[@"iat"] isKindOfClass:[NSNumber class]] && [(NSNumber *)claims[@"iat"] longValue] >= currentTime - MaxTimeSinceTokenIssued; - BOOL nonceMatched = [claims[@"nonce"] isKindOfClass:[NSString class]] && [claims[@"nonce"] isEqualToString:nonce]; - BOOL userIDValid = [claims[@"sub"] isKindOfClass:[NSString class]] && [claims[@"sub"] length] > 0; - BOOL hasJTI = [claims[@"jti"] isKindOfClass:[NSString class]] && [claims[@"jti"] length] > 0; - - if (isFacebook && audMatched && !isExpired && issuedRecently && nonceMatched && userIDValid && hasJTI) { - return claims; - } - } - } - - return nil; -} - + (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader { NSError *error; - NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory base64FromBase64Url:encodedHeader]]; + NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKBase64 base64FromBase64Url:encodedHeader]]; if (headerData) { NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; @@ -183,8 +152,7 @@ - (void)verifySignature:(NSString *)signature } #endif - NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKAuthenticationTokenFactory - base64FromBase64Url:signature]]; + NSData *signatureData = [FBSDKBase64 decodeAsData:[FBSDKBase64 base64FromBase64Url:signature]]; NSString *signedString = [NSString stringWithFormat:@"%@.%@", header, claims]; NSData *signedData = [signedString dataUsingEncoding:NSASCIIStringEncoding]; [self getPublicKeyWithCertificateKey:certificateKey @@ -286,14 +254,6 @@ - (NSURL *)_certificateEndpoint return url; } -+ (NSString *)base64FromBase64Url:(NSString *)base64Url -{ - NSString *base64 = [base64Url stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; - base64 = [base64 stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; - - return base64; -} - #pragma mark - Test methods #if DEBUG @@ -315,11 +275,6 @@ - (void)setCertificate:(NSString *)certificate _cert = certificate; } -- (NSDictionary *)claims -{ - return _claims; -} - #endif @end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 79770883b1..4c33794349 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -73,6 +73,7 @@ #import "FBSDKApplicationObserving.h" #import "FBSDKAuthenticationStatusUtility.h" #import "FBSDKAuthenticationToken+Internal.h" + #import "FBSDKAuthenticationTokenClaims.h" #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKBase64.h" #import "FBSDKButton+Subclass.h" @@ -154,6 +155,7 @@ #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKApplicationObserving.h" #import "FBSDKAuthenticationToken+Internal.h" + #import "FBSDKAuthenticationTokenClaims.h" #import "FBSDKAuthenticationTokenFactory.h" #import "FBSDKDeviceRequestsHelper.h" #import "FBSDKDynamicFrameworkLoader.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m index 52ef28e100..7a858d536a 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKAuthenticationTokenTests.m @@ -73,7 +73,7 @@ - (void)testEncoding FBSDKTestCoder *coder = [FBSDKTestCoder new]; _token = [[FBSDKAuthenticationToken alloc] initWithTokenString:expectedTokenString nonce:expectedNonce - claims:@{} + claims:nil jti:expectedJTI]; [_token encodeWithCoder:coder]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 41ad33682d..4a6913604d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -37,14 +37,18 @@ NS_ASSUME_NONNULL_BEGIN // Categories needed to expose private methods to Swift @interface FBSDKAppEventsConfigurationManager (Testing) + + (void)_processResponse:(id)response error:(nullable NSError *)error; + @end @interface FBSDKCloseIcon (Testing) + - (nullable UIImage *)imageWithSize:(CGSize)size primaryColor:(UIColor *)primaryColor secondaryColor:(UIColor *)secondaryColor scale:(CGFloat)scale; + @end NS_SWIFT_NAME(FBProfilePictureViewState) @@ -52,31 +56,40 @@ NS_SWIFT_NAME(FBProfilePictureViewState) @end @interface FBSDKProfilePictureView (Testing) + - (void)_accessTokenDidChangeNotification:(NSNotification *)notification; - (void)_profileDidChangeNotification:(NSNotification *)notification; - (void)_updateImageWithProfile; - (void)_updateImageWithAccessToken; - (void)_updateImage; - (void)_fetchAndSetImageWithURL:(NSURL *)imageURL state:(FBSDKProfilePictureViewState *)state; + @end @interface FBSDKAccessToken (Testing) + + (void)setCurrentAccessToken:(nullable FBSDKAccessToken *)token shouldDispatchNotif:(BOOL)shouldDispatchNotif; + @end @interface FBSDKProfile (Testing) + + (void)setCurrentProfile:(nullable FBSDKProfile *)profile shouldPostNotification:(BOOL)shouldPostNotification; + @end @interface FBSDKAuthenticationToken (Testing) + - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(nullable NSDictionary *)claims + claims:(nullable FBSDKAuthenticationTokenClaims *)claims jti:(NSString *)jti; + + (void)setCurrentAuthenticationToken:(nullable FBSDKAuthenticationToken *)token shouldPostNotification:(BOOL)shouldPostNotification; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift index 75255b71fd..7204ce7ce4 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Base64/FBSDKBase64Tests.swift @@ -55,4 +55,10 @@ class FBSDKBase64Tests: XCTestCase { ] runTests(testsDict) } + + func testBase64URLEncode() { + let urlString = "https://www.example.com/some-path-with-dashes-in-it/" + let encodedString = Base64.base64(fromBase64Url: urlString) + XCTAssertEqual(encodedString, "https://www.example.com/some+path+with+dashes+in+it/") + } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index a83e813573..5ba299adf7 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -39,7 +39,6 @@ @interface FBSDKAuthenticationTokenFactory (Testing) + (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; + (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; -+ (NSString *)base64FromBase64Url:(NSString *)base64Url; - (instancetype)initWithSessionProvider:(id)sessionProvider; - (void)setCertificate:(NSString *)certificate; @@ -51,13 +50,29 @@ - (BOOL)verifySignature:(NSString *)signature - (NSDictionary *)claims; @end +@interface FBSDKAuthenticationTokenClaims (Testing) + +- (instancetype)initWithJti:(NSString *)jti + iss:(NSString *)iss + aud:(NSString *)aud + nonce:(NSString *)nonce + exp:(long)exp + iat:(long)iat + sub:(NSString *)sub + name:(nullable NSString *)name + email:(nullable NSString *)email + picture:(nullable NSString *)picture; + +@end + @interface FBSDKAuthenticationTokenFactoryTests : FBSDKTestCase @end @implementation FBSDKAuthenticationTokenFactoryTests { - NSDictionary *_claims; + FBSDKAuthenticationTokenClaims *_claims; + NSDictionary *_claimsDict; NSDictionary *_header; } @@ -68,7 +83,25 @@ - (void)setUp [self stubAppID:_mockAppID]; long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; - _claims = @{ + + _claims = [[FBSDKAuthenticationTokenClaims alloc] initWithJti:_mockJTI + iss:_facebookURL + aud:_mockAppID + nonce:_mockNonce + exp:currentTime + 60 * 60 * 48 // 2 days later + iat:currentTime - 60 // 1 min ago + sub:@"1234" + name:@"Test User" + email:@"email@email.com" + picture:@"https://www.facebook.com/some_picture"]; + + _header = @{ + @"alg" : @"RS256", + @"typ" : @"JWT", + @"kid" : @"abcd1234", + }; + + _claimsDict = @{ @"iss" : _facebookURL, @"aud" : _mockAppID, @"nonce" : _mockNonce, @@ -80,11 +113,6 @@ - (void)setUp @"email" : @"email@email.com", @"picture" : @"https://www.facebook.com/some_picture", }; - - _header = @{ - @"alg" : @"RS256", - @"typ" : @"JWT" - }; } // MARK: - Creation @@ -108,10 +136,10 @@ - (void)testCreateWithInvalidFormatTokenShouldFail - (void)testDecodeValidClaimsShouldSucceed { - NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claims options:0 error:nil]; + NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claimsDict options:0 error:nil]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - NSDictionary *claims = [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; + FBSDKAuthenticationTokenClaims *claims = [FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; XCTAssertEqualObjects(claims, _claims); } @@ -120,7 +148,7 @@ - (void)testDecodeInvalidFormatClaimsShouldFail NSData *claimsData = [@"invalid_claims" dataUsingEncoding:NSUTF8StringEncoding]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - XCTAssertNil([FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); + XCTAssertNil([FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); } - (void)testDecodeInvalidClaimsShouldFail @@ -150,8 +178,6 @@ - (void)testDecodeInvalidClaimsShouldFail // invalid user ID [self assertDecodeClaimsFailWithInvalidEntry:@"sub" value:nil]; - [self assertDecodeClaimsFailWithInvalidEntry:@"sub" - value:@1234]; [self assertDecodeClaimsFailWithInvalidEntry:@"sub" value:@""]; @@ -168,17 +194,17 @@ - (void)testDecodeEmptyClaims NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:claims options:0 error:nil]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - XCTAssertNil([FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); + XCTAssertNil([FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); } - (void)testDecodeRandomClaims { for (int i = 0; i < 100; i++) { - NSDictionary *randomizedClaims = [self randomizeDictionary:_claims]; + NSDictionary *randomizedClaims = [self randomizeDictionary:_claimsDict]; NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:randomizedClaims options:0 error:nil]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - [FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; + [FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]; } } @@ -398,24 +424,9 @@ - (void)testVerifySignatureWithFuzzyData // MARK: - Utilities -- (void)testBase64FromBase64Url -{ - NSString *expectedString = @"testBase64FromBase64Url"; - NSData *data = [expectedString dataUsingEncoding:NSUTF8StringEncoding]; - NSString *base64UrlEncoded = [self base64URLEncodeData:data]; - NSString *base64Encoded = [FBSDKAuthenticationTokenFactory base64FromBase64Url:base64UrlEncoded]; - XCTAssertEqualObjects([FBSDKBase64 decodeAsString:base64Encoded], expectedString); - - // test nil - XCTAssertNil([FBSDKAuthenticationTokenFactory base64FromBase64Url:nil]); - - // test empty string - XCTAssertEqualObjects([FBSDKAuthenticationTokenFactory base64FromBase64Url:@""], @""); -} - - (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value { - NSMutableDictionary *invalidClaims = [_claims mutableCopy]; + NSMutableDictionary *invalidClaims = [_claimsDict mutableCopy]; if (value) { [FBSDKTypeUtility dictionary:invalidClaims setObject:value forKey:key]; } else { @@ -425,7 +436,7 @@ - (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:invalidClaims options:0 error:nil]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; - XCTAssertNil([FBSDKAuthenticationTokenFactory validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); + XCTAssertNil([FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); } - (NSString *)base64URLEncodeData:(NSData *)data diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift index 65900e280d..1fe1a5fa8c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/SampleAuthenticationToken.swift @@ -23,7 +23,7 @@ public class SampleAuthenticationToken: NSObject { return AuthenticationToken( tokenString: "fakeTokenString", nonce: "fakeNonce", - claims: [:], + claims: nil, jti: "fakeJTI" ) } diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h index 44568353fe..5d219be363 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h @@ -23,6 +23,7 @@ #import @class FBSDKAuthenticationToken; +@class FBSDKAuthenticationTokenClaims; @class FBSDKLoginCompletionParameters; @class FBSDKLoginManager; @class FBSDKProfile; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 4843d8587b..c76447ab42 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -35,7 +35,7 @@ @interface FBSDKAuthenticationToken (ClaimsProviding) -- (NSDictionary *)claims; +- (FBSDKAuthenticationTokenClaims *)claims; @end @@ -122,7 +122,7 @@ - (void)fetchAndSetPropertiesForParameters:(nonnull FBSDKLoginCompletionParamete FBSDKAuthenticationTokenBlock completion = ^(FBSDKAuthenticationToken *token) { if (token) { parameters.authenticationToken = token; - parameters.profile = [FBSDKLoginURLCompleter createProfileWithToken:token]; + parameters.profile = [FBSDKLoginURLCompleter profileWithClaims:token.claims]; } else { parameters.error = [FBSDKError errorWithCode:FBSDKLoginErrorInvalidIDToken message:@"Invalid ID token from login response."]; } @@ -250,31 +250,26 @@ - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)ha [connection start]; } -/// Returns a `FBSDKProfile` from an `AuthenticationToken` if it can extract the minimum necessary information -+ (FBSDKProfile *)createProfileWithToken:(FBSDKAuthenticationToken *)token ++ (nullable FBSDKProfile *)profileWithClaims:(FBSDKAuthenticationTokenClaims *)claims { - if (!token || !token.claims) { + if (claims.sub.length == 0) { return nil; } - NSDictionary *claims = token.claims; - if (![claims[@"sub"] isKindOfClass:NSString.class]) { - return nil; + NSURL *imageURL; + if (claims.picture) { + imageURL = [NSURL URLWithString:claims.picture]; } - NSString *name = [claims[@"name"] isKindOfClass:NSString.class] ? claims[@"name"] : nil; - NSString *email = [claims[@"email"] isKindOfClass:NSString.class] ? claims[@"email"] : nil; - NSURL *imageURL = [claims[@"picture"] isKindOfClass:NSString.class] ? [NSURL URLWithString:claims[@"picture"]] : nil; - - return [[FBSDKProfile alloc]initWithUserID:claims[@"sub"] - firstName:nil - middleName:nil - lastName:nil - name:name - linkURL:nil - refreshDate:nil - imageURL:imageURL - email:email]; + return [[FBSDKProfile alloc] initWithUserID:claims.sub + firstName:nil + middleName:nil + lastName:nil + name:claims.name + linkURL:nil + refreshDate:nil + imageURL:imageURL + email:claims.email]; } @end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h index b322db47da..af018a81ad 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -18,14 +18,18 @@ #import +#import "FBSDKCoreKit+Internal.h" #import "FBSDKLoginConfiguration.h" #import "FBSDKNonceUtility.h" +@class FBSDKAuthenticationTokenClaims; + NS_ASSUME_NONNULL_BEGIN // Categories needed to expose private methods to Swift @interface FBSDKLoginButton (Testing) + - (FBSDKLoginConfiguration *)loginConfiguration; - (BOOL)_isAuthenticated; - (void)_fetchAndSetContent; @@ -36,25 +40,33 @@ NS_ASSUME_NONNULL_BEGIN - (void)_profileDidChangeNotification:(NSNotification *)notification; - (nullable NSString *)userName; - (nullable NSString *)userID; + @end @interface FBSDKAccessToken (Testing) + + (void)setCurrentAccessToken:(nullable FBSDKAccessToken *)token shouldDispatchNotif:(BOOL)shouldDispatchNotif; + @end @interface FBSDKProfile (Testing) + + (void)setCurrentProfile:(nullable FBSDKProfile *)profile shouldPostNotification:(BOOL)shouldPostNotification; + @end @interface FBSDKAuthenticationToken (Testing) + - (instancetype)initWithTokenString:(NSString *)tokenString nonce:(NSString *)nonce - claims:(nullable NSDictionary *)claims + claims:(nullable FBSDKAuthenticationTokenClaims *)claims jti:(NSString *)jti; + + (void)setCurrentAuthenticationToken:(nullable FBSDKAuthenticationToken *)token shouldPostNotification:(BOOL)shouldPostNotification; + @end NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift index 0c35f180d5..81352151f2 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginButtonTests.swift @@ -35,6 +35,10 @@ class LoginButtonTests: XCTestCase { ) } + var sampleToken: AuthenticationToken { + return AuthenticationToken(tokenString: "abc", nonce: "123", claims: nil, jti: "jti") + } + override func setUp() { super.setUp() @@ -168,8 +172,7 @@ class LoginButtonTests: XCTestCase { } func testDeterminingAuthenticationWithoutAccessTokenWithAuthToken() { - let authToken = AuthenticationToken(tokenString: "abc", nonce: "123", claims: [:], jti: "jti") - AuthenticationToken.setCurrent(authToken, shouldPostNotification: false) + AuthenticationToken.setCurrent(sampleToken, shouldPostNotification: false) XCTAssertTrue( button._isAuthenticated(), From 3989e3923784038b787181b8c0a066139cd6a2c2 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 16 Dec 2020 08:54:07 -0800 Subject: [PATCH 182/227] Fix intermittent crash Summary: Occasionally seeing: 2020-12-15 13:32:32.679-0800 2020-12-15 13:32:32.679 xctest[54878:63614739] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSDate ocmock_replaced_timeIntervalSinceReferenceDate]: unrecognized selector sent to class 0x7fff86b8a4f8' This should fix that by not messing with system objects like `Date`. In retrospect this was not a good idea. Reviewed By: robtimp Differential Revision: D25574112 fbshipit-source-id: 9838a74fc3aaa560e26871100ff23eee7ee6675f --- .../Internal/Helpers/FBSDKTestCase.h | 6 ---- .../Internal/Helpers/FBSDKTestCase.m | 10 ------ .../Instrument/FBSDKCrashShieldTests.m | 32 ++++--------------- 3 files changed, 7 insertions(+), 41 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index 55bd7b4872..c5a81e5616 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -270,12 +270,6 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKSettings.isDataProcessingRestricted` and returns the provided value - (void)stubIsDataProcessingRestricted:(BOOL)isRestricted; -/// Stubs `NSDate`'s `date` method to return the shared date mock -- (void)stubDate; - -/// Stubs `NSDate`'s `timeIntervalSince1970` method and returns the provided time interval -- (void)stubTimeIntervalSince1970WithTimeInterval:(NSTimeInterval)interval; - /// Stubs `FBSDKSettings.facebookDomainPart` with the provided value - (void)stubFacebookDomainPartWith:(NSString *)domainPart; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index b0359975ed..2168a4d47a 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -587,16 +587,6 @@ - (void)stubIsDataProcessingRestricted:(BOOL)isRestricted OCMStub(ClassMethod([_settingsClassMock isDataProcessingRestricted])).andReturn(isRestricted); } -- (void)stubDate -{ - OCMStub([_nsDateClassMock date]).andReturn(_nsDateClassMock); -} - -- (void)stubTimeIntervalSince1970WithTimeInterval:(NSTimeInterval)interval -{ - OCMStub([_nsDateClassMock timeIntervalSince1970]).andReturn(interval); -} - - (void)stubFacebookDomainPartWith:(NSString *)domainPart { OCMStub(ClassMethod([_settingsClassMock facebookDomainPart])).andReturn(domainPart); diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m index 31d481abed..8ddc549422 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m @@ -208,24 +208,18 @@ - (void)testPostingCoreKitCrashLogsWithDataProcessingUnrestricted // Setup [self stubIsDataProcessingRestricted:NO]; [self stubAppID:self.appID]; - [self stubDate]; - [self stubTimeIntervalSince1970WithTimeInterval:10]; - - [self addInitializerStubsToGraphRequestMock]; - OCMExpect([self.graphRequestMock startWithCompletionHandler:nil]); + [self preventGraphRequest]; // Act [FBSDKCrashShield analyze:self.coreKitCrashLogs]; // Assert NSString *expectedPath = [NSString stringWithFormat:@"%@/instruments", self.appID]; - NSDictionary *expectedParameters = @{ - @"crash_shield" : [self encodedCoreKitFeatureDataWithTimestamp:@"10"] - }; - OCMVerifyAll( - [self.graphRequestMock initWithGraphPath:expectedPath - parameters:expectedParameters - HTTPMethod:FBSDKHTTPMethodPOST] + + OCMVerify( + (void)[self.graphRequestMock initWithGraphPath:expectedPath + parameters:OCMArg.any + HTTPMethod:FBSDKHTTPMethodPOST] ); OCMVerify([self.graphRequestMock startWithCompletionHandler:nil]); } @@ -234,10 +228,8 @@ - (void)testPostingNonCoreKitCrashLogsWithDataProcessingUnrestricted { [self stubIsDataProcessingRestricted:NO]; [self stubAppID:self.appID]; - [self stubDate]; - [self stubTimeIntervalSince1970WithTimeInterval:10]; - [self addInitializerStubsToGraphRequestMock]; + [self preventGraphRequest]; OCMReject( [self.graphRequestMock initWithGraphPath:OCMArg.any @@ -251,16 +243,6 @@ - (void)testPostingNonCoreKitCrashLogsWithDataProcessingUnrestricted // MARK: - Helpers -- (void)addInitializerStubsToGraphRequestMock -{ - OCMStub(ClassMethod([self.graphRequestMock alloc])).andReturn(self.graphRequestMock); - OCMStub( - [self.graphRequestMock initWithGraphPath:OCMArg.any - parameters:OCMArg.any - HTTPMethod:FBSDKHTTPMethodPOST] - ).andReturn(self.graphRequestMock); -} - - (NSString *)encodedCoreKitFeatureDataWithTimestamp:(NSString *)timestamp { NSData *featureData = [FBSDKTypeUtility dataWithJSONObject:@{ From d05f734698efe220b87e2adc36cdec14419eb564 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 16 Dec 2020 15:15:33 -0800 Subject: [PATCH 183/227] Get Swift LoginKitTests Running on BUCK Summary: This adds internal Swift support to LoginKit. Reviewed By: robtimp, shoumikhin Differential Revision: D25565941 fbshipit-source-id: 23d316809d3843cc08ac654892e1f2f4b48c8bdc --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 8 ++++++-- .../Internal/FBSDKReferralManager+Internal.h | 6 +++++- .../FBSDKLoginKitTests-Bridging-Header.h | 8 ++++++-- .../FBSDKLoginManagerLoggerTests.m | 9 +++++++-- .../FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 16 ++++++++++++---- .../FBSDKLoginKitTests/FBSDKReferralCodeTests.m | 6 +++++- .../FBSDKReferralManagerTests.m | 12 +++++++++--- 7 files changed, 50 insertions(+), 15 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 624d4e01b2..5b53d10e2c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -119,7 +119,6 @@ 9D03E8351A72DF5800207493 /* FBSDKLoginConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D03E8331A72DF5800207493 /* FBSDKLoginConstants.m */; }; 9D3AF4931A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D3AF4911A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.h */; }; 9D3AF4941A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D3AF4921A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.m */; }; - 9D641F841A7B69160048F563 /* FBSDKLoginManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */; }; 9D65ACA81A803FF200E375C2 /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D65ACA61A803FF200E375C2 /* FBSDKLoginButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D65ACA91A803FF200E375C2 /* FBSDKLoginButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D65ACA71A803FF200E375C2 /* FBSDKLoginButton.m */; }; 9D9DB8DF1A114E500086167B /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -164,6 +163,8 @@ F46FA65D245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; F46FA65E245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; F46FE68B2579764F000F4F53 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */; }; + F47E5CDC25895C5F008CA03E /* FBSDKLoginManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */; }; + F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */; }; F4AA32822574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; F4AA32832574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */; }; @@ -405,6 +406,7 @@ F46FA659245347570060C902 /* FBLoginButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBLoginButton.swift; sourceTree = ""; }; F46FA65C245347820060C902 /* LoginManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginManager.swift; sourceTree = ""; }; F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; + F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginManagerLoggerTests.m; sourceTree = ""; }; F4AA32812574448C005EDF04 /* LoginConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginConfiguration.swift; sourceTree = ""; }; F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKNonceUtility.h; sourceTree = ""; }; F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKNonceUtility.m; sourceTree = ""; }; @@ -664,6 +666,7 @@ 9D9DB8E81A114E500086167B /* FBSDKLoginKitTests */ = { isa = PBXGroup; children = ( + F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */, F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */, 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */, 6B6276321A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.h */, @@ -1188,9 +1191,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F47E5CDC25895C5F008CA03E /* FBSDKLoginManagerTests.m in Sources */, F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */, - 9D641F841A7B69160048F563 /* FBSDKLoginManagerTests.m in Sources */, F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, + F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h index 7d0311783d..c8d680c7d0 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKReferralManager+Internal.h @@ -20,7 +20,11 @@ #if !TARGET_OS_TV - #import "FBSDKReferralManager.h" + #ifdef BUCK + #import + #else + #import "FBSDKReferralManager.h" + #endif #ifdef FBSDKCOCOAPODS #import diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h index af018a81ad..0126b64546 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -19,8 +19,12 @@ #import #import "FBSDKCoreKit+Internal.h" -#import "FBSDKLoginConfiguration.h" -#import "FBSDKNonceUtility.h" + +#ifdef BUCK + #import +#else + #import "FBSDKNonceUtility.h" +#endif @class FBSDKAuthenticationTokenClaims; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m index e189dbcc3e..34877e2e50 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerLoggerTests.m @@ -21,8 +21,13 @@ #import -#import "FBSDKLoginManager.h" -#import "FBSDKLoginManagerLogger.h" +#ifdef BUCK + #import + #import +#else + #import "FBSDKLoginManager.h" + #import "FBSDKLoginManagerLogger.h" +#endif @interface FBSDKAppEvents (Testing) diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index b6941c4f1e..8f8802395e 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -22,10 +22,18 @@ #import -#import "FBSDKLoginConstants.h" -#import "FBSDKLoginManager.h" -#import "FBSDKLoginManager+Internal.h" -#import "FBSDKLoginManagerLoginResult.h" +#ifdef BUCK + #import + #import + #import + #import +#else + #import "FBSDKLoginConstants.h" + #import "FBSDKLoginManager.h" + #import "FBSDKLoginManager+Internal.h" + #import "FBSDKLoginManagerLoginResult.h" +#endif + #import "FBSDKLoginUtilityTests.h" static NSString *const kFakeAppID = @"7391628439"; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m index 39f5fb07a6..4c54131d6d 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralCodeTests.m @@ -18,7 +18,11 @@ #import -#import "FBSDKReferralCode.h" +#ifdef BUCK + #import +#else + #import "FBSDKReferralCode.h" +#endif static NSString *const _validReferralCode1 = @"abcd"; static NSString *const _validReferralCode2 = @"123"; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m index 10bdb77c51..d8fc214ddb 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKReferralManagerTests.m @@ -21,9 +21,15 @@ #import -#import "FBSDKLoginUtility.h" -#import "FBSDKReferralManager+Internal.h" -#import "FBSDKReferralManagerResult.h" +#ifdef BUCK + #import + #import + #import +#else + #import "FBSDKLoginUtility.h" + #import "FBSDKReferralManager+Internal.h" + #import "FBSDKReferralManagerResult.h" +#endif static NSString *const _mockAppID = @"mockAppID"; static NSString *const _mockChallenge = @"mockChallenge"; From 92c9fd2dcea0a6690dbfa66af933b98818c323b9 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 16 Dec 2020 15:35:01 -0800 Subject: [PATCH 184/227] ad fuzzy test for core kit Summary: Add tests for radomized server responses Reviewed By: joesus Differential Revision: D25545667 fbshipit-source-id: 954c1229962eb73cb004f813da554cd1cd232ccb --- .../FBSDKAuthenticationStatusUtilityTests.m | 20 ++++++ .../FBSDKAuthenticationTokenFactoryTests.m | 63 +++++++------------ .../Internal/Helpers/Fuzzer.swift | 4 ++ 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m index 4105422d90..75a837ebef 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m @@ -147,4 +147,24 @@ - (void)testHandleFailedResponse XCTAssertNotNil(FBSDKProfile.currentProfile, @"Profile should not be cleared when the request failed"); } +- (void)testHandleResponseWithFuzzyData +{ + NSURL *url = [NSURL URLWithString:@"m.facebook.com/platform/oidc/status/"]; + + for (int i = 0; i < 100; i++) { + // only strings allowed in HTTP header + NSDictionary *header = @{ + @"fb-s" : [[Fuzzer random] description], + @"some_header_key" : [[Fuzzer random] description], + }; + + NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url + statusCode:200 + HTTPVersion:nil + headerFields:header]; + + [FBSDKAuthenticationStatusUtility _handleResponse:response]; + } +} + @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index 5ba299adf7..1bd25b9d1e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -117,24 +117,22 @@ - (void)setUp // MARK: - Creation -- (void)testCreateWithInvalidFormatTokenShouldFail +- (void)testCreateWithInvalidFormatToken { - XCTestExpectation *expectation = [self expectationWithDescription:self.name]; + __block BOOL wasCalled = NO; FBSDKAuthenticationTokenBlock completion = ^(FBSDKAuthenticationToken *token) { XCTAssertNil(token); - [expectation fulfill]; + wasCalled = YES; }; [[FBSDKAuthenticationTokenFactory new] createTokenFromTokenString:@"invalid_token" nonce:@"123456789" completion:completion]; - [self waitForExpectationsWithTimeout:1 handler:^(NSError *_Nullable error) { - XCTAssertNil(error); - }]; + XCTAssertTrue(wasCalled, @"Completion handler should be called syncronously"); } // MARK: - Decoding Claims -- (void)testDecodeValidClaimsShouldSucceed +- (void)testDecodeValidClaims { NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:_claimsDict options:0 error:nil]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; @@ -143,7 +141,7 @@ - (void)testDecodeValidClaimsShouldSucceed XCTAssertEqualObjects(claims, _claims); } -- (void)testDecodeInvalidFormatClaimsShouldFail +- (void)testDecodeInvalidFormatClaims { NSData *claimsData = [@"invalid_claims" dataUsingEncoding:NSUTF8StringEncoding]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; @@ -151,7 +149,7 @@ - (void)testDecodeInvalidFormatClaimsShouldFail XCTAssertNil([FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); } -- (void)testDecodeInvalidClaimsShouldFail +- (void)testDecodeInvalidClaims { long currentTime = [[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]] longValue]; @@ -200,7 +198,7 @@ - (void)testDecodeEmptyClaims - (void)testDecodeRandomClaims { for (int i = 0; i < 100; i++) { - NSDictionary *randomizedClaims = [self randomizeDictionary:_claimsDict]; + NSDictionary *randomizedClaims = [Fuzzer randomizeWithJson:_claims]; NSData *claimsData = [FBSDKTypeUtility dataWithJSONObject:randomizedClaims options:0 error:nil]; NSString *encodedClaims = [self base64URLEncodeData:claimsData]; @@ -210,7 +208,7 @@ - (void)testDecodeRandomClaims // MARK: - Decoding Header -- (void)testDecodeValidHeaderShouldSucceed +- (void)testDecodeValidHeader { NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; NSString *encodedHeader = [self base64URLEncodeData:headerData]; @@ -219,7 +217,7 @@ - (void)testDecodeValidHeaderShouldSucceed XCTAssertEqualObjects(header, _header); } -- (void)testDecodeInvalidFormatHeaderShouldFail +- (void)testDecodeInvalidFormatHeader { NSData *headerData = [@"invalid_header" dataUsingEncoding:NSUTF8StringEncoding]; NSString *encodedHeader = [self base64URLEncodeData:headerData]; @@ -227,7 +225,7 @@ - (void)testDecodeInvalidFormatHeaderShouldFail XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); } -- (void)testDecodeInvalidHeaderShouldFail +- (void)testDecodeInvalidHeader { NSMutableDictionary *invalidHeader = [_header mutableCopy]; [FBSDKTypeUtility dictionary:invalidHeader setObject:@"wrong algorithm" forKey:@"alg"]; @@ -246,6 +244,17 @@ - (void)testDecodeEmptyHeader XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); } +- (void)testDecodeRandomHeader +{ + for (int i = 0; i < 100; i++) { + NSDictionary *randomizedHeader = [Fuzzer randomizeWithJson:_header]; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:randomizedHeader options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; + } +} + // MARK: - Verifying Signature - (void)testVerifySignatureWithoutDataWithoutResponseWithoutError @@ -406,7 +415,7 @@ - (void)testVerifySignatureWithFuzzyData FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; for (int i = 0; i < 100; i++) { - NSDictionary *randomizedCertificates = [self randomizeDictionary:self.validRawCertificateResponse]; + NSDictionary *randomizedCertificates = [Fuzzer randomizeWithJson:self.validRawCertificateResponse]; NSData *data = [FBSDKTypeUtility dataWithJSONObject:randomizedCertificates options:0 error:nil]; session.data = data; @@ -422,7 +431,7 @@ - (void)testVerifySignatureWithFuzzyData } } -// MARK: - Utilities +// MARK: - Helpers - (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value { @@ -447,30 +456,6 @@ - (NSString *)base64URLEncodeData:(NSData *)data return [base64URL stringByReplacingOccurrencesOfString:@"=" withString:@""]; } -- (NSDictionary *)randomizeDictionary:(NSDictionary *)dictionary -{ - NSArray *values = @[@YES, @NO, @1, @0, @-1, @INT32_MAX, @LONG_MAX, @MAXFLOAT, @"1", @"a", @"[ { \"something\": nonexistent } ]"]; - NSMutableDictionary *randomized = [dictionary mutableCopy]; - for (NSString *key in dictionary) { - int randOption = arc4random() % 3; - switch (randOption) { - case 0: - [randomized removeObjectForKey:key]; - break; - case 1: - [FBSDKTypeUtility dictionary:randomized setObject:[FBSDKTypeUtility array:values objectAtIndex:arc4random() % values.count] forKey:key]; - break; - case 2: - default: - break; - } - } - - return randomized; -} - -// MARK: - Helpers - - (NSDictionary *)validRawCertificateResponse { return @{ diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/Fuzzer.swift b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/Fuzzer.swift index 5a70b06c5d..68ab0b6c3a 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/Fuzzer.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/Fuzzer.swift @@ -120,6 +120,10 @@ public class Fuzzer: NSObject { if Bool.random() { json[key] = random } + + else if Bool.random() { + json.removeValue(forKey: key) + } } } From 07bc24605c9fd6613807ebc4b1313a0e29b18d29 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 16 Dec 2020 15:35:01 -0800 Subject: [PATCH 185/227] Add test for FBSDKLoginCompletion Summary: title Reviewed By: joesus Differential Revision: D25552558 fbshipit-source-id: 8fc64bfc5684195f19a4dbc392af3566f3a8f2e2 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 4 + .../FBSDKLoginCompletionTests.m | 191 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 5b53d10e2c..53f512c973 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -134,6 +134,7 @@ C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; + C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -387,6 +388,7 @@ 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; + C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginCompletionTests.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -678,6 +680,7 @@ F4647478256AEF8E00502449 /* NonceTests.swift */, 9D9DB8E91A114E500086167B /* Supporting Files */, F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */, + C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -1196,6 +1199,7 @@ F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, + C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m new file mode 100644 index 0000000000..61b5b9718e --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -0,0 +1,191 @@ +// 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 "FBSDKLoginCompletion+Internal.h" + +static NSString *const _fakeAppID = @"1234567"; +static NSString *const _fakeChallence = @"some_challenge"; + +@interface FBSDKLoginURLCompleter (Testing) + +- (FBSDKLoginCompletionParameters *)parameters; + +@end + +@interface FBSDKLoginCompletionTests : XCTestCase +{ + NSDictionary *_parameters; +} + +@end + +@implementation FBSDKLoginCompletionTests + +- (void)setUp +{ + [super setUp]; + + int secInDay = 60 * 60 * 24; + + _parameters = @{ + @"access_token" : @"some_access_token", + @"id_token" : @"some_id_token", + @"nonce" : @"some_nonce", + @"granted_scopes" : @"public_profile,openid", + @"denied_scopes" : @"email", + @"signed_request" : @"some_signed_request", + @"user_id" : @"123", + @"expires" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 60) stringValue], + @"expires_at" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 60) stringValue], + @"expires_in" : [@(secInDay * 60) stringValue], + @"data_access_expiration_time" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 90) stringValue], + @"state" : [NSString stringWithFormat:@"{\"challenge\":\"%@\"}", _fakeChallence], + @"graph_domain" : @"facebook", + @"error" : @"some_error", + @"error_message" : @"some_error_message", + }; +} + +// MARK: Creation + +- (void)testInitWithAccessTokenWithIDToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithAccessToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithIDToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"expires", @"expires_at", @"expires_in", @"data_access_expiration_time", @"graph_domain", @"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithoutAccessTokenWithoutIDTokenWithoutNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyEmptyParameters:completer.parameters]; +} + +- (void)testInitWithEmptyAccessTokenWithEmptyIDTokenWithEmptyNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"error", @"error_message"]]; + [parameters setValue:@"" forKey:@"access_token"]; + [parameters setValue:@"" forKey:@"id_token"]; + [parameters setValue:@"" forKey:@"nonce"]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyEmptyParameters:completer.parameters]; +} + +- (void)testInitWithEmptyParameters +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:@{} appID:_fakeAppID]; + + [self verifyEmptyParameters:completer.parameters]; +} + +- (void)testInitWithError +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + XCTAssertNotNil(completer.parameters.error); +} + +// MARK: Helpers + +- (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParameter:(NSDictionary *)urlParameters +{ + XCTAssertEqualObjects(parameters.accessTokenString, urlParameters[@"access_token"]); + XCTAssertEqualObjects(parameters.authenticationTokenString, urlParameters[@"id_token"]); + XCTAssertEqualObjects(parameters.appID, _fakeAppID); + XCTAssertEqualObjects(parameters.challenge, _fakeChallence); + NSSet *permissions = [NSSet setWithArray:[urlParameters[@"granted_scopes"] componentsSeparatedByString:@","]]; + XCTAssertEqualObjects(parameters.permissions, permissions); + NSSet *declinedPermissions = [NSSet setWithArray:[urlParameters[@"denied_scopes"] componentsSeparatedByString:@","]]; + XCTAssertEqualObjects(parameters.declinedPermissions, declinedPermissions); + XCTAssertEqualObjects(parameters.userID, urlParameters[@"user_id"]); + XCTAssertEqualObjects(parameters.graphDomain, urlParameters[@"graph_domain"]); + + if (urlParameters[@"expires"] || urlParameters[@"expires_at"] || urlParameters[@"expires_in"]) { + XCTAssertNotNil(parameters.expirationDate); + } + if (urlParameters[@"data_access_expiration_time"]) { + XCTAssertNotNil(parameters.dataAccessExpirationDate); + } + XCTAssertEqualObjects(parameters.nonceString, urlParameters[@"nonce"]); + XCTAssertNil(parameters.error); +} + +- (void)verifyEmptyParameters:(FBSDKLoginCompletionParameters *)parameters +{ + XCTAssertNil(parameters.accessTokenString); + XCTAssertNil(parameters.authenticationTokenString); + XCTAssertNil(parameters.appID); + XCTAssertNil(parameters.challenge); + XCTAssertNil(parameters.permissions); + XCTAssertNil(parameters.declinedPermissions); + XCTAssertNil(parameters.userID); + XCTAssertNil(parameters.graphDomain); + XCTAssertNil(parameters.expirationDate); + XCTAssertNil(parameters.dataAccessExpirationDate); + XCTAssertNil(parameters.nonceString); + XCTAssertNil(parameters.error); +} + +@end From dfd2977b8d2221dea184cfccd540138a29eacd06 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Wed, 16 Dec 2020 15:45:20 -0800 Subject: [PATCH 186/227] Stop Initializing in +load method Summary: Using the +load method to auto-initialize the SDK led to unforeseen negative consequences and developer reactions. From here on, developers are required to initialize the SDK explicitly with the `initializeSDK` method or implicitly by calling it in `applicationDidFinishLaunching`. Reviewed By: dreamolight Differential Revision: D25548365 fbshipit-source-id: 8c9a43c217310e7a086d0afc3878fba46f15a46b --- .../FBSDKCoreKit/AppEvents/FBSDKAppEvents.m | 2 - .../Internal/FBSDKAppEvents+Internal.h | 3 - .../FBSDKCoreKit/FBSDKApplicationDelegate.h | 2 - .../FBSDKCoreKit/FBSDKApplicationDelegate.m | 54 +-------- FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h | 7 -- FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m | 31 +----- .../FBSDKApplicationDelegateTests.m | 54 --------- .../Internal/AppEvents/FBSDKAppEventsTests.m | 32 ------ .../Internal/FBSDKSettingsTests.m | 105 ++---------------- .../Internal/Helpers/FBSDKTestCase.h | 3 - .../Internal/Helpers/FBSDKTestCase.m | 10 -- 11 files changed, 21 insertions(+), 282 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m index 9b6d866d0e..f580c3969c 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/FBSDKAppEvents.m @@ -213,8 +213,6 @@ FBSDKAppEventName FBSDKAppEventNameFBSessionFASLoginDialogResult = @"fb_mobile_login_fas_dialog_result"; -FBSDKAppEventName FBSDKAppEventNameImplementsApplicationDidFinishLaunching = @"fb_sdk_implements_did_finish_launching"; - FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStart = @"fb_sdk_live_streaming_start"; FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingStop = @"fb_sdk_live_streaming_stop"; FBSDKAppEventName FBSDKAppEventNameFBSDKLiveStreamingPause = @"fb_sdk_live_streaming_pause"; diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h index f2adaaddb5..8a5db6607e 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/FBSDKAppEvents+Internal.h @@ -100,9 +100,6 @@ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBDialogsWebLoginCompleted; /** Use to log the result of the App Switch OS AlertView. Only available on OS >= iOS10 */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSessionFASLoginDialogResult; -/** Use to log whether the app implements `applicationDidFinishLaunching:withOptions:` */ -FOUNDATION_EXPORT NSString *const FBSDKAppEventNameImplementsApplicationDidFinishLaunching; - /** Use to log the live streaming events from sdk */ FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKLiveStreamingStart; FOUNDATION_EXPORT NSString *const FBSDKAppEventNameFBSDKLiveStreamingStop; diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h index f09048014e..f4bde7231d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h @@ -99,8 +99,6 @@ didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions { if (g_isSDKInitialized) { @@ -110,9 +84,7 @@ + (void)initializeSDK:(NSDictionary *)launchO [[FBSDKAppEvents singleton] registerNotifications]; - NSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions]; - [FBSDKTypeUtility dictionary:modifiedLaunchOptions setObject:@YES forKey:FBSDKAutoInitLaunchArgument]; - [delegate application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:modifiedLaunchOptions]; + [delegate application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:launchOptions]; // In case of sdk autoInit enabled sdk expects one appDidBecomeActive notification after app launch and has some logic to ignore it. // if sdk autoInit disabled app won't receive appDidBecomeActive on app launch and will ignore the first one it gets instead of handling it. @@ -227,25 +199,14 @@ - (BOOL)application:(UIApplication *)application - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - if ([[FBSDKTypeUtility dictionary:launchOptions objectForKey:FBSDKAutoInitLaunchArgument ofType:NSNumber.class] boolValue]) { - // Clean the flag out of launch options - NSMutableDictionary *originalLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions]; - [originalLaunchOptions removeObjectForKey:FBSDKAutoInitLaunchArgument]; - launchOptions = [originalLaunchOptions copy]; - } else { - // Log because it was not called by autoInit - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [FBSDKAppEvents logInternalEvent:FBSDKAppEventNameImplementsApplicationDidFinishLaunching - parameters:@{} - isImplicitlyLogged:YES]; - #pragma clang diagnostic pop - } - if (_isAppLaunched) { return NO; } + if (!g_isSDKInitialized) { + [FBSDKApplicationDelegate initializeSDK:launchOptions]; + } + _isAppLaunched = YES; // Retrieve cached tokens @@ -472,10 +433,7 @@ - (void)_logSwiftRuntimeAvailability + (BOOL)isSDKInitialized { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - return [FBSDKSettings isAutoInitEnabled] || g_isSDKInitialized; - #pragma clang diagnostic pop + return g_isSDKInitialized; } // MARK: - Testability diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h index 86ee277aea..7e337c3532 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h @@ -85,13 +85,6 @@ NS_SWIFT_NAME(Settings) @property (class, nonatomic, assign) CGFloat JPEGCompressionQuality NS_SWIFT_NAME(jpegCompressionQuality); -/** - Controls sdk auto initailization. - If not explicitly set, the default is true - */ -@property (class, nonatomic, assign, getter=isAutoInitEnabled) BOOL autoInitEnabled -DEPRECATED_MSG_ATTRIBUTE("Auto-initialization will be removed in the next major version release."); - /** Controls the auto logging of basic app events, such as activateApp and deactivateApp. If not explicitly set, the default is true diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m index 2b5fea2697..886cf19afe 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m @@ -115,7 +115,6 @@ + (void)initialize FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil, NO); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil, NO); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @0.9, NO); -FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoInitEnabled, _autoInitEnabled, _setAutoInitEnabled, @1, YES); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookInstrumentEnabled, _instrumentEnabled, _setInstrumentEnabled, @1, YES); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAutoLogAppEventsEnabled, _autoLogAppEventsEnabled, _setAutoLogAppEventsEnabled, @1, YES); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookAdvertiserIDCollectionEnabled, _advertiserIDCollectionEnabled, _setAdvertiserIDCollectionEnabled, @1, YES); @@ -148,19 +147,6 @@ + (void)setJPEGCompressionQuality:(CGFloat)JPEGCompressionQuality [self _setJPEGCompressionQualityNumber:@(JPEGCompressionQuality)]; } -+ (BOOL)isAutoInitEnabled -{ - return [self _autoInitEnabled].boolValue; -} - -+ (void)setAutoInitEnabled:(BOOL)autoInitEnabled -{ - [self _setAutoInitEnabled:@(autoInitEnabled)]; - if (autoInitEnabled) { - [FBSDKApplicationDelegate initializeSDK:nil]; - } -} - + (BOOL)isInstrumentEnabled { return [self _instrumentEnabled].boolValue; @@ -435,11 +421,8 @@ + (void)_logWarnings + (void)_logIfSDKSettingsChanged { NSInteger bitmask = 0; - NSInteger bit = 0; - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - bitmask |= ([FBSDKSettings isAutoInitEnabled] ? 1 : 0) << bit++; - #pragma clang diagnostic pop + // Starting at 1 to maintain the meaning of the bits since the autoInit flag was removed. + NSInteger bit = 1; bitmask |= ([FBSDKSettings isAutoLogAppEventsEnabled] ? 1 : 0) << bit++; bitmask |= ([FBSDKSettings isAdvertiserIDCollectionEnabled] ? 1 : 0) << bit++; @@ -447,10 +430,9 @@ + (void)_logIfSDKSettingsChanged if (previousBitmask != bitmask) { [[NSUserDefaults standardUserDefaults] setInteger:bitmask forKey:FBSDKSettingsBitmask]; - NSArray *keys = @[@"FacebookAutoInitEnabled", - @"FacebookAutoLogAppEventsEnabled", + NSArray *keys = @[@"FacebookAutoLogAppEventsEnabled", @"FacebookAdvertiserIDCollectionEnabled"]; - NSArray *defaultValues = @[@YES, @YES, @YES]; + NSArray *defaultValues = @[@YES, @YES]; NSInteger initialBitmask = 0; NSInteger usageBitmask = 0; for (int i = 0; i < keys.count; i++) { @@ -576,11 +558,6 @@ + (void)resetFacebookJpegCompressionQualityCache g_FacebookJpegCompressionQuality = nil; } -+ (void)resetFacebookAutoInitEnabledCache -{ - g_FacebookAutoInitEnabled = nil; -} - + (void)resetFacebookInstrumentEnabledCache { g_FacebookInstrumentEnabled = nil; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m index d5a6696f37..4e8ed80ff8 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKApplicationDelegateTests.m @@ -299,60 +299,6 @@ - (void)testDidFinishLaunchingWithoutObservers XCTAssertFalse(notifiedObservers, "Should indicate if no observers were notified"); } -- (void)testDidFinishLaunchingCalledFromAutoInit -{ - // Should not log that the SDK implements didFinishLaunching manually - OCMReject( - ClassMethod( - [self.appEventsMock logInternalEvent:@"fb_sdk_implements_did_finish_launching" - parameters:@{} - isImplicitlyLogged:OCMOCK_VALUE(YES)] - ) - ); - - // Stub all the dependencies of initializing SDK - [self stubFBApplicationDelegateSharedInstanceWith:_delegate]; - [self stubRegisterAppForAdNetworkAttribution]; - [self stubDefaultNotificationCenterWith:_notificationCenterSpy]; - OCMStub([_partialDelegateMock applicationDidBecomeActive:UIApplication.sharedApplication]); - [self stubCheckingFeatures]; - [self stubDefaultMeasurementEventListenerWith:[FBSDKMeasurementEventListener new]]; - [self stubCachedProfileWith:nil]; - OCMStub([self.timeSpentDataClassMock setSourceApplication:OCMArg.any openURL:OCMArg.any]); - OCMStub([self.timeSpentDataClassMock registerAutoResetSourceApplication]); - OCMStub([self.internalUtilityClassMock validateFacebookReservedURLSchemes]); - - NSDictionary *launchOptions = @{}; - ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; - [_delegate addObserver:observer]; - [FBSDKApplicationDelegate initializeSDK:launchOptions]; - - XCTAssertEqualObjects(observer.capturedLaunchOptions, @{}, "Observers should not be passed the modified launch arguments."); - // Should Modify the launch arguments when didFinishLaunching is invoked from the `initializeSDK` method - OCMVerify( - [_partialDelegateMock application:UIApplication.sharedApplication - didFinishLaunchingWithOptions:@{@"_calledFromAutoInitSDK" : @YES}] - ); -} - -- (void)testDidFinishLaunchingCalledManually -{ - NSDictionary *launchOptions = @{@"foo" : @"bar"}; - ApplicationDelegateObserverFake *observer = [ApplicationDelegateObserverFake new]; - [_delegate addObserver:observer]; - [FBSDKApplicationDelegate.sharedInstance application:UIApplication.sharedApplication - didFinishLaunchingWithOptions:launchOptions]; - - XCTAssertEqualObjects(observer.capturedLaunchOptions, @{@"foo" : @"bar"}, "Observers should not be passed modified launch arguments."); - OCMVerify( - ClassMethod( - [self.appEventsMock logInternalEvent:@"fb_sdk_implements_did_finish_launching" - parameters:@{} - isImplicitlyLogged:OCMOCK_VALUE(YES)] - ) - ); -} - - (void)testAppEventsEnabled { [self stubIsAutoLogAppEventsEnabled:YES]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m index 2fd28f2108..5de660147d 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/AppEvents/FBSDKAppEventsTests.m @@ -655,38 +655,6 @@ - (void)testAppEventsKillSwitchEnabled mockGateKeeperManager = nil; } -- (void)testGraphRequestBannedWithAutoInitDisabled -{ - // test when autoInitEnabled is set to be NO - __block int activiesEndpointCalledCountDisabled = 0; - NSString *urlString = [NSString stringWithFormat:@"%@/activities", _mockAppID]; - XCTestExpectation *expectation = [self expectationWithDescription:@"No Graph Request is sent"]; - - [OHHTTPStubs stubRequestsPassingTest:^BOOL (NSURLRequest *request) { - XCTAssertNotNil(request); - if ([request.URL.absoluteString rangeOfString:urlString].location != NSNotFound) { - ++activiesEndpointCalledCountDisabled; - } - return NO; - } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { - return [OHHTTPStubsResponse responseWithData:[NSData data] - statusCode:200 - headers:nil]; - }]; - - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - [FBSDKSettings setAutoInitEnabled:NO]; - #pragma clang diagnostic pop - - [FBSDKAppEvents logPurchase:_mockPurchaseAmount currency:_mockCurrency]; - [expectation fulfill]; - [self waitForExpectationsWithTimeout:3 handler:^(NSError *error) { - XCTAssertNil(error); - }]; - XCTAssertEqual(0, activiesEndpointCalledCountDisabled, @"No Graph Request is sent"); -} - #pragma mark Tests for log event - (void)testLogEventWithValueToSum diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m index 5507ac8e5f..f66f22ff14 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKSettingsTests.m @@ -862,88 +862,6 @@ - (void)testURLSchemeSuffixInternalStorage ); } -// MARK: Auto Initialization Enabled - -- (void)testAutoInitializationEnabledFromPlist -{ - NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : @NO}]; - [self stubMainBundleWith:bundle]; - - XCTAssertFalse( - FBSDKSettings.isAutoInitEnabled, - "A developer should be able to set the value of auto initialization from the plist" - ); -} - -- (void)testAutoInitializationDefaultValue -{ - XCTAssertTrue( - FBSDKSettings.isAutoInitEnabled, - "Auto initialization should default to true when there is no plist value given" - ); -} - -- (void)testAutoInitializationInvalidPlistEntry -{ - NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : emptyString}]; - [self stubMainBundleWith:bundle]; - - XCTAssertFalse( - FBSDKSettings.isAutoInitEnabled, - "Auto initialization should default to true when there is an invalid plist value given but it does not" - ); -} - -- (void)testSettingAutoInitializationEnabled -{ - FBSDKSettings.autoInitEnabled = false; - - XCTAssertNotNil( - userDefaultsSpy.capturedValues[@"FacebookAutoInitEnabled"], - "Should persist the value of a cachable property when setting it" - ); - XCTAssertFalse( - FBSDKSettings.autoInitEnabled, - "Should use the explicitly set property" - ); -} - -- (void)testOverridingCachedAutoInitialization -{ - [self stubInitializeSDKWith:@{}]; - - FBSDKSettings.autoInitEnabled = true; - XCTAssertTrue(FBSDKSettings.isAutoInitEnabled); - - NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : @NO}]; - [self stubMainBundleWith:bundle]; - - XCTAssertTrue( - FBSDKSettings.autoInitEnabled, - "Should favor cached properties over those set in the plist" - ); -} - -- (void)testAutoInitializationInternalStorage -{ - [self stubInitializeSDKWith:@{}]; - - FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; - [self stubMainBundleWith:bundle]; - - FBSDKSettings.autoInitEnabled = @YES; - - XCTAssertTrue(FBSDKSettings.autoInitEnabled, "sanity check"); - XCTAssertNil( - userDefaultsSpy.capturedObjectRetrievalKey, - "Should not attempt to access the cache to retrieve objects that have a current value" - ); - XCTAssertNil( - bundle.capturedKeys.lastObject, - "Should not attempt to access the plist to retrieve objects that have a current value" - ); -} - // MARK: Auto Log App Events Enabled - (void)testAutoLogAppEventsEnabledFromPlist @@ -994,7 +912,6 @@ - (void)testOverridingCachedAutoLogAppEventsEnabled { [self stubInitializeSDKWith:@{}]; - FBSDKSettings.autoInitEnabled = true; XCTAssertTrue(FBSDKSettings.isAutoLogAppEventsEnabled); NSBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoLogAppEventsEnabled" : @NO}]; @@ -1237,24 +1154,24 @@ - (void)testCachedFacebookCodelessDebugLogEnabledInternalStorage - (void)testInitialAccessForCachablePropertyWithNonEmptyCache { // Using false because it is not the default value for `isAutoInitializationEnabled` - userDefaultsSpy.capturedValues = @{ @"FacebookAutoInitEnabled" : @NO }; + userDefaultsSpy.capturedValues = @{ @"FacebookAutoLogAppEventsEnabled" : @NO }; [self stubUserDefaultsWith:userDefaultsSpy]; FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{}]; [self stubMainBundleWith:bundle]; XCTAssertFalse( - FBSDKSettings.isAutoInitEnabled, + FBSDKSettings.isAutoLogAppEventsEnabled, "Should retrieve an initial value for a cachable property when there is a non-empty cache" ); XCTAssertEqualObjects( userDefaultsSpy.capturedObjectRetrievalKey, - @"FacebookAutoInitEnabled", + @"FacebookAutoLogAppEventsEnabled", "Should attempt to access the cache to retrieve the initial value for a cachable property" ); XCTAssertFalse( - [bundle.capturedKeys containsObject:@"FacebookAutoInitEnabled"], + [bundle.capturedKeys containsObject:@"FacebookAutoLogAppEventsEnabled"], "Should not attempt to access the plist for cachable properties that have a value in the cache" ); } @@ -1262,22 +1179,22 @@ - (void)testInitialAccessForCachablePropertyWithNonEmptyCache - (void)testInitialAccessForCachablePropertyWithEmptyCacheNonEmptyPlist { // Using false because it is not the default value for `isAutoInitializationEnabled` - FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoInitEnabled" : @NO}]; + FakeBundle *bundle = [FakeBundle bundleWithDictionary:@{@"FacebookAutoLogAppEventsEnabled" : @NO}]; [self stubMainBundleWith:bundle]; XCTAssertFalse( - FBSDKSettings.isAutoInitEnabled, + FBSDKSettings.isAutoLogAppEventsEnabled, "Should retrieve an initial value from the property list" ); XCTAssertEqualObjects( userDefaultsSpy.capturedObjectRetrievalKey, - @"FacebookAutoInitEnabled", + @"FacebookAutoLogAppEventsEnabled", "Should attempt to access the cache to retrieve the initial value for a cachable property" ); XCTAssertEqualObjects( bundle.capturedKeys.lastObject, - @"FacebookAutoInitEnabled", + @"FacebookAutoLogAppEventsEnabled", "Should attempt to access the plist for cachable properties that have no value in the cache" ); } @@ -1288,18 +1205,18 @@ - (void)testInitialAccessForCachablePropertyWithEmptyCacheEmptyPlistAndDefaultVa [self stubMainBundleWith:bundle]; XCTAssertTrue( - FBSDKSettings.isAutoInitEnabled, + FBSDKSettings.isAutoLogAppEventsEnabled, "Should use the default value for a property when there are no values in the cache or plist" ); XCTAssertEqualObjects( userDefaultsSpy.capturedObjectRetrievalKey, - @"FacebookAutoInitEnabled", + @"FacebookAutoLogAppEventsEnabled", "Should attempt to access the cache to retrieve the initial value for a cachable property" ); XCTAssertEqualObjects( bundle.capturedKeys.lastObject, - @"FacebookAutoInitEnabled", + @"FacebookAutoLogAppEventsEnabled", "Should attempt to access the plist for cachable properties that have no value in the cache" ); } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h index c5a81e5616..24796085b5 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.h @@ -164,9 +164,6 @@ Also, to get a better understanding of mocking, please read the documentation at /// Stubs `FBSDKSettings.isSDKInitialized` and return the provided value - (void)stubIsSDKInitialized:(BOOL)initialized; -/// Stubs `FBSDKSettings.isAutoInitEnabled` and return the provided value -- (void)stubIsAutoInitEnabled:(BOOL)isEnabled; - /// Stubs `FBSDKSettings.isAutoLogAppEventsEnabled` and return the provided value - (void)stubIsAutoLogAppEventsEnabled:(BOOL)isEnabled; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m index 2168a4d47a..bc58108794 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Helpers/FBSDKTestCase.m @@ -58,7 +58,6 @@ + (void)resetFacebookClientTokenCache; + (void)resetFacebookDisplayNameCache; + (void)resetFacebookDomainPartCache; + (void)resetFacebookJpegCompressionQualityCache; -+ (void)resetFacebookAutoInitEnabledCache; + (void)resetFacebookInstrumentEnabledCache; + (void)resetFacebookAutoLogAppEventsEnabledCache; + (void)resetFacebookAdvertiserIDCollectionEnabledCache; @@ -457,14 +456,6 @@ - (void)stubTokenCacheWith:(FakeTokenCache *)cache OCMStub(ClassMethod([_settingsClassMock tokenCache])).andReturn(cache); } -- (void)stubIsAutoInitEnabled:(BOOL)isEnabled -{ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - OCMStub(ClassMethod([_settingsClassMock isAutoInitEnabled])).andReturn(isEnabled); - #pragma clang diagnostic pop -} - - (void)stubIsAutoLogAppEventsEnabled:(BOOL)isEnabled { OCMStub(ClassMethod([_settingsClassMock isAutoLogAppEventsEnabled])).andReturn(isEnabled); @@ -643,7 +634,6 @@ - (void)resetCachedSettings [FBSDKSettings resetFacebookDisplayNameCache]; [FBSDKSettings resetFacebookDomainPartCache]; [FBSDKSettings resetFacebookJpegCompressionQualityCache]; - [FBSDKSettings resetFacebookAutoInitEnabledCache]; [FBSDKSettings resetFacebookInstrumentEnabledCache]; [FBSDKSettings resetFacebookAutoLogAppEventsEnabledCache]; [FBSDKSettings resetFacebookAdvertiserIDCollectionEnabledCache]; From 34926878a4bc3e575ae9509ec65db8ed75e13af3 Mon Sep 17 00:00:00 2001 From: Dmytro Kasianchuk Date: Wed, 16 Dec 2020 17:33:48 -0800 Subject: [PATCH 187/227] Revert D25552558: Add test for FBSDKLoginCompletion Differential Revision: D25552558 (https://github.com/facebook/facebook-ios-sdk/commit/07bc24605c9fd6613807ebc4b1313a0e29b18d29) Original commit changeset: 8fc64bfc5684 fbshipit-source-id: 06374b39c3ff7213768f0425b824c53271d325d2 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 4 - .../FBSDKLoginCompletionTests.m | 191 ------------------ 2 files changed, 195 deletions(-) delete mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 53f512c973..5b53d10e2c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -134,7 +134,6 @@ C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; - C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -388,7 +387,6 @@ 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; - C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginCompletionTests.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -680,7 +678,6 @@ F4647478256AEF8E00502449 /* NonceTests.swift */, 9D9DB8E91A114E500086167B /* Supporting Files */, F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */, - C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -1199,7 +1196,6 @@ F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, - C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m deleted file mode 100644 index 61b5b9718e..0000000000 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ /dev/null @@ -1,191 +0,0 @@ -// 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 "FBSDKLoginCompletion+Internal.h" - -static NSString *const _fakeAppID = @"1234567"; -static NSString *const _fakeChallence = @"some_challenge"; - -@interface FBSDKLoginURLCompleter (Testing) - -- (FBSDKLoginCompletionParameters *)parameters; - -@end - -@interface FBSDKLoginCompletionTests : XCTestCase -{ - NSDictionary *_parameters; -} - -@end - -@implementation FBSDKLoginCompletionTests - -- (void)setUp -{ - [super setUp]; - - int secInDay = 60 * 60 * 24; - - _parameters = @{ - @"access_token" : @"some_access_token", - @"id_token" : @"some_id_token", - @"nonce" : @"some_nonce", - @"granted_scopes" : @"public_profile,openid", - @"denied_scopes" : @"email", - @"signed_request" : @"some_signed_request", - @"user_id" : @"123", - @"expires" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 60) stringValue], - @"expires_at" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 60) stringValue], - @"expires_in" : [@(secInDay * 60) stringValue], - @"data_access_expiration_time" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 90) stringValue], - @"state" : [NSString stringWithFormat:@"{\"challenge\":\"%@\"}", _fakeChallence], - @"graph_domain" : @"facebook", - @"error" : @"some_error", - @"error_message" : @"some_error_message", - }; -} - -// MARK: Creation - -- (void)testInitWithAccessTokenWithIDToken -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"nonce", @"error", @"error_message"]]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - [self verifyParameters:completer.parameters urlParameter:parameters]; -} - -- (void)testInitWithAccessToken -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"id_token", @"nonce", @"error", @"error_message"]]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - [self verifyParameters:completer.parameters urlParameter:parameters]; -} - -- (void)testInitWithNonce -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"error", @"error_message"]]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - [self verifyParameters:completer.parameters urlParameter:parameters]; -} - -- (void)testInitWithIDToken -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token", @"expires", @"expires_at", @"expires_in", @"data_access_expiration_time", @"graph_domain", @"nonce", @"error", @"error_message"]]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - [self verifyParameters:completer.parameters urlParameter:parameters]; -} - -- (void)testInitWithoutAccessTokenWithoutIDTokenWithoutNonce -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce", @"error", @"error_message"]]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - [self verifyEmptyParameters:completer.parameters]; -} - -- (void)testInitWithEmptyAccessTokenWithEmptyIDTokenWithEmptyNonce -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"error", @"error_message"]]; - [parameters setValue:@"" forKey:@"access_token"]; - [parameters setValue:@"" forKey:@"id_token"]; - [parameters setValue:@"" forKey:@"nonce"]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - [self verifyEmptyParameters:completer.parameters]; -} - -- (void)testInitWithEmptyParameters -{ - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:@{} appID:_fakeAppID]; - - [self verifyEmptyParameters:completer.parameters]; -} - -- (void)testInitWithError -{ - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce"]]; - - FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; - - XCTAssertNotNil(completer.parameters.error); -} - -// MARK: Helpers - -- (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParameter:(NSDictionary *)urlParameters -{ - XCTAssertEqualObjects(parameters.accessTokenString, urlParameters[@"access_token"]); - XCTAssertEqualObjects(parameters.authenticationTokenString, urlParameters[@"id_token"]); - XCTAssertEqualObjects(parameters.appID, _fakeAppID); - XCTAssertEqualObjects(parameters.challenge, _fakeChallence); - NSSet *permissions = [NSSet setWithArray:[urlParameters[@"granted_scopes"] componentsSeparatedByString:@","]]; - XCTAssertEqualObjects(parameters.permissions, permissions); - NSSet *declinedPermissions = [NSSet setWithArray:[urlParameters[@"denied_scopes"] componentsSeparatedByString:@","]]; - XCTAssertEqualObjects(parameters.declinedPermissions, declinedPermissions); - XCTAssertEqualObjects(parameters.userID, urlParameters[@"user_id"]); - XCTAssertEqualObjects(parameters.graphDomain, urlParameters[@"graph_domain"]); - - if (urlParameters[@"expires"] || urlParameters[@"expires_at"] || urlParameters[@"expires_in"]) { - XCTAssertNotNil(parameters.expirationDate); - } - if (urlParameters[@"data_access_expiration_time"]) { - XCTAssertNotNil(parameters.dataAccessExpirationDate); - } - XCTAssertEqualObjects(parameters.nonceString, urlParameters[@"nonce"]); - XCTAssertNil(parameters.error); -} - -- (void)verifyEmptyParameters:(FBSDKLoginCompletionParameters *)parameters -{ - XCTAssertNil(parameters.accessTokenString); - XCTAssertNil(parameters.authenticationTokenString); - XCTAssertNil(parameters.appID); - XCTAssertNil(parameters.challenge); - XCTAssertNil(parameters.permissions); - XCTAssertNil(parameters.declinedPermissions); - XCTAssertNil(parameters.userID); - XCTAssertNil(parameters.graphDomain); - XCTAssertNil(parameters.expirationDate); - XCTAssertNil(parameters.dataAccessExpirationDate); - XCTAssertNil(parameters.nonceString); - XCTAssertNil(parameters.error); -} - -@end From c03a8251886161860908abacdc07ac208646092a Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 17 Dec 2020 08:09:20 -0800 Subject: [PATCH 188/227] Provide configuration to error recovery Summary: All login requires a nonce. This fixes that for error recovery. Followup changes will make it impossible to call login without a configuration (since this will provide the nonce). Reviewed By: ppansy Differential Revision: D25598958 fbshipit-source-id: cebc465dbfdcac6e420aeeec06325295ad84083a --- .../FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m index c48fd7a0ad..2f7f943457 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m @@ -39,7 +39,8 @@ - (void)attemptRecoveryFromError:(NSError *)error NSSet *currentPermissions = [FBSDKAccessToken currentAccessToken].permissions; if (recoveryOptionIndex == 0 && currentPermissions.count > 0) { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; - [login logInWithPermissions:currentPermissions handler:^(FBSDKLoginManagerLoginResult *result, NSError *loginError) { + FBSDKLoginConfiguration *configuration = [[FBSDKLoginConfiguration alloc] initWithBetaLoginExperience:FBSDKBetaLoginExperienceEnabled]; + [login logInWithPermissions:currentPermissions fromViewController:nil handler:^(FBSDKLoginManagerLoginResult *result, NSError *loginError) { // we can only consider a recovery successful if there are no declines // (note this could still set an updated currentAccessToken). handler(!loginError && !result.isCancelled && result.declinedPermissions.count == 0); From 2f6c12880af6eff6b7bfc35904d249ba4f365e28 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 17 Dec 2020 10:01:49 -0800 Subject: [PATCH 189/227] Fix the build Summary: Moving too fast. Yolo changes were too yolo. Reviewed By: Mxiim Differential Revision: D25616691 fbshipit-source-id: 839d72d0d68be2ed29228e06dc3e8a73c08c6d8e --- .../FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m index 2f7f943457..f884b4b973 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m @@ -39,8 +39,7 @@ - (void)attemptRecoveryFromError:(NSError *)error NSSet *currentPermissions = [FBSDKAccessToken currentAccessToken].permissions; if (recoveryOptionIndex == 0 && currentPermissions.count > 0) { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; - FBSDKLoginConfiguration *configuration = [[FBSDKLoginConfiguration alloc] initWithBetaLoginExperience:FBSDKBetaLoginExperienceEnabled]; - [login logInWithPermissions:currentPermissions fromViewController:nil handler:^(FBSDKLoginManagerLoginResult *result, NSError *loginError) { + [login logInWithPermissions:currentPermissions.allObjects fromViewController:nil handler:^(FBSDKLoginManagerLoginResult *result, NSError *loginError) { // we can only consider a recovery successful if there are no declines // (note this could still set an updated currentAccessToken). handler(!loginError && !result.isCancelled && result.declinedPermissions.count == 0); From 69eb6f3d4a0941de6dadc388beea7792cff54e56 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Thu, 17 Dec 2020 10:49:23 -0800 Subject: [PATCH 190/227] Add test for FBSDKLoginCompletion Summary: Redo D25552558 (https://github.com/facebook/facebook-ios-sdk/commit/07bc24605c9fd6613807ebc4b1313a0e29b18d29). That diff was breaking unit tests because Buck file was changed for LoginKit. Fixing import so that it can build with buck Reviewed By: joesus Differential Revision: D25605877 fbshipit-source-id: 44b334978cca1b016df0687bdb33b34708aeed59 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 4 + .../FBSDKLoginCompletionTests.m | 195 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 5b53d10e2c..53f512c973 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -134,6 +134,7 @@ C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; + C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -387,6 +388,7 @@ 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; + C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginCompletionTests.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -678,6 +680,7 @@ F4647478256AEF8E00502449 /* NonceTests.swift */, 9D9DB8E91A114E500086167B /* Supporting Files */, F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */, + C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -1196,6 +1199,7 @@ F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, + C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m new file mode 100644 index 0000000000..4d0fc5ff7f --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -0,0 +1,195 @@ +// 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 + +#ifdef BUCK + #import +#else + #import "FBSDKLoginCompletion+Internal.h" +#endif + +static NSString *const _fakeAppID = @"1234567"; +static NSString *const _fakeChallence = @"some_challenge"; + +@interface FBSDKLoginURLCompleter (Testing) + +- (FBSDKLoginCompletionParameters *)parameters; + +@end + +@interface FBSDKLoginCompletionTests : XCTestCase +{ + NSDictionary *_parameters; +} + +@end + +@implementation FBSDKLoginCompletionTests + +- (void)setUp +{ + [super setUp]; + + int secInDay = 60 * 60 * 24; + + _parameters = @{ + @"access_token" : @"some_access_token", + @"id_token" : @"some_id_token", + @"nonce" : @"some_nonce", + @"granted_scopes" : @"public_profile,openid", + @"denied_scopes" : @"email", + @"signed_request" : @"some_signed_request", + @"user_id" : @"123", + @"expires" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 60) stringValue], + @"expires_at" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 60) stringValue], + @"expires_in" : [@(secInDay * 60) stringValue], + @"data_access_expiration_time" : [@(NSDate.date.timeIntervalSince1970 + secInDay * 90) stringValue], + @"state" : [NSString stringWithFormat:@"{\"challenge\":\"%@\"}", _fakeChallence], + @"graph_domain" : @"facebook", + @"error" : @"some_error", + @"error_message" : @"some_error_message", + }; +} + +// MARK: Creation + +- (void)testInitWithAccessTokenWithIDToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithAccessToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithIDToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"expires", @"expires_at", @"expires_in", @"data_access_expiration_time", @"graph_domain", @"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyParameters:completer.parameters urlParameter:parameters]; +} + +- (void)testInitWithoutAccessTokenWithoutIDTokenWithoutNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce", @"error", @"error_message"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyEmptyParameters:completer.parameters]; +} + +- (void)testInitWithEmptyAccessTokenWithEmptyIDTokenWithEmptyNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"error", @"error_message"]]; + [parameters setValue:@"" forKey:@"access_token"]; + [parameters setValue:@"" forKey:@"id_token"]; + [parameters setValue:@"" forKey:@"nonce"]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + [self verifyEmptyParameters:completer.parameters]; +} + +- (void)testInitWithEmptyParameters +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:@{} appID:_fakeAppID]; + + [self verifyEmptyParameters:completer.parameters]; +} + +- (void)testInitWithError +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + XCTAssertNotNil(completer.parameters.error); +} + +// MARK: Helpers + +- (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParameter:(NSDictionary *)urlParameters +{ + XCTAssertEqualObjects(parameters.accessTokenString, urlParameters[@"access_token"]); + XCTAssertEqualObjects(parameters.authenticationTokenString, urlParameters[@"id_token"]); + XCTAssertEqualObjects(parameters.appID, _fakeAppID); + XCTAssertEqualObjects(parameters.challenge, _fakeChallence); + NSSet *permissions = [NSSet setWithArray:[urlParameters[@"granted_scopes"] componentsSeparatedByString:@","]]; + XCTAssertEqualObjects(parameters.permissions, permissions); + NSSet *declinedPermissions = [NSSet setWithArray:[urlParameters[@"denied_scopes"] componentsSeparatedByString:@","]]; + XCTAssertEqualObjects(parameters.declinedPermissions, declinedPermissions); + XCTAssertEqualObjects(parameters.userID, urlParameters[@"user_id"]); + XCTAssertEqualObjects(parameters.graphDomain, urlParameters[@"graph_domain"]); + + if (urlParameters[@"expires"] || urlParameters[@"expires_at"] || urlParameters[@"expires_in"]) { + XCTAssertNotNil(parameters.expirationDate); + } + if (urlParameters[@"data_access_expiration_time"]) { + XCTAssertNotNil(parameters.dataAccessExpirationDate); + } + XCTAssertEqualObjects(parameters.nonceString, urlParameters[@"nonce"]); + XCTAssertNil(parameters.error); +} + +- (void)verifyEmptyParameters:(FBSDKLoginCompletionParameters *)parameters +{ + XCTAssertNil(parameters.accessTokenString); + XCTAssertNil(parameters.authenticationTokenString); + XCTAssertNil(parameters.appID); + XCTAssertNil(parameters.challenge); + XCTAssertNil(parameters.permissions); + XCTAssertNil(parameters.declinedPermissions); + XCTAssertNil(parameters.userID); + XCTAssertNil(parameters.graphDomain); + XCTAssertNil(parameters.expirationDate); + XCTAssertNil(parameters.dataAccessExpirationDate); + XCTAssertNil(parameters.nonceString); + XCTAssertNil(parameters.error); +} + +@end From 0821b77254c9c4ee11f3647e20ee03667f7a88d1 Mon Sep 17 00:00:00 2001 From: Xin Wu Date: Thu, 17 Dec 2020 10:59:27 -0800 Subject: [PATCH 191/227] disable AdTrackingKit linter for IDFA and AdTracking Usage Summary: Since iOS SDK doesn't use `FBAdTrackingKit`, this diff disabled IDFA and AdTracking Usage linter. Clang-tidy for objc and fastChecks for Swift. Reviewed By: joesus Differential Revision: D25602633 fbshipit-source-id: 22a9d91f082b634dd8714d3161a3f2346e73a8c4 --- .fast_checks | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .fast_checks diff --git a/.fast_checks b/.fast_checks new file mode 100644 index 0000000000..67e317cec9 --- /dev/null +++ b/.fast_checks @@ -0,0 +1,4 @@ +InheritParentConfig: true +Checks: ' +-idfa-usage +' From 5fb073096cb79f41622f4dbf9dfa75a373a27054 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 17 Dec 2020 11:21:56 -0800 Subject: [PATCH 192/227] Documentation Improvements Summary: Adds some clarity around the public methods in `FBSDKLoginManager` Reviewed By: jingping2015 Differential Revision: D25617205 fbshipit-source-id: f9bb76b40d6854f85bc8f2ad988f10b5870dad7d --- .../FBSDKLoginKit/FBSDKLoginManager.h | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index 82f04d5d0d..9e73b49300 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -132,6 +132,7 @@ NS_SWIFT_NAME(LoginManager) /** Logs the user in or authorizes additional permissions. + @param permissions the optional array of permissions. Note this is converted to NSSet and is only an NSArray for the convenience of literal syntax. @param fromViewController the view controller to present from. If nil, the topmost view controller will be @@ -141,12 +142,13 @@ NS_SWIFT_NAME(LoginManager) Use this method when asking for read permissions. You should only ask for permissions when they are needed and explain the value to the user. You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. - - This method will present UI the user. You typically should check if `[FBSDKAccessToken currentAccessToken]` + You typically should check if `[FBSDKAccessToken currentAccessToken]` already contains the permissions you need before asking to reduce unnecessary app switching. For example, you could make that check at viewDidLoad. - You can only do one login call at a time. Calling a login method before the completion handler is called - on a previous login will return an error. + + @warning You can only perform one login call at a time. Calling a login method before the completion handler is called + on a previous login attempt will result in an error. + @warning This method will present a UI to the user and thus should be called on the main thread. */ - (void)logInWithPermissions:(NSArray *)permissions fromViewController:(nullable UIViewController *)fromViewController @@ -163,13 +165,12 @@ NS_SWIFT_NAME(logIn(permissions:from:handler:)); Use this method when asking for permissions. You should only ask for permissions when they are needed and the value should be explained to the user. You can inspect the result's `declinedPermissions` to also provide more information to the user if they decline permissions. + To reduce unnecessary app switching, you should typically check if `FBSDKAccessToken.currentAccessToken` + already contains the permissions you need. If it does, you probably do not need to call this method. - This method will present a UI to the user. To reduce unnecessary app switching, you should typically check if - `FBSDKAccessToken.currentAccessToken` already contains the permissions you need. If it does, you probably - do not need to call this method. - - You can only perform one login call at a time. Calling a login method before the completion handler is called - on a previous login will result in an error. + @warning You can only perform one login call at a time. Calling a login method before the completion handler is called + on a previous login attempt will result in an error. + @warning This method will present a UI to the user and thus should be called on the main thread. */ - (void)logInFromViewController:(nullable UIViewController *)viewController configuration:(FBSDKLoginConfiguration *)configuration @@ -181,7 +182,10 @@ NS_REFINED_FOR_SWIFT; @param url the deep link url @param handler the callback. - This method should be called with the url from the openURL method. +This method will present a UI to the user and thus should be called on the main thread. +This method should be called with the url from the openURL method. + + @warning This method will present a UI to the user and thus should be called on the main thread. */ - (void)logInWithURL:(NSURL *)url handler:(nullable FBSDKLoginManagerLoginResultBlock)handler @@ -189,11 +193,9 @@ NS_SWIFT_NAME(logIn(url:handler:)); /** Requests user's permission to reathorize application's data access, after it has expired due to inactivity. -@param fromViewController the view controller to present from. If nil, the topmost view controller will be -automatically determined as best as possible. -@param handler the callback. - -@warning This method will reauthorize using a `LoginConfiguration` with `FBSDKBetaLoginExperience` set to enabled. + @param fromViewController the view controller to present from. If nil, the topmost view controller will be + automatically determined as best as possible. + @param handler the callback. Use this method when you need to reathorize your app's access to user data via Graph API, after such an access has expired. You should provide as much context to the user as possible as to why you need to reauthorize the access, the scope of @@ -201,6 +203,7 @@ access being reathorized, and what added value your app provides when the access You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. This method will present UI the user. You typically should call this if `[FBSDKAccessToken isDataAccessExpired]` returns true. + @warning This method will reauthorize using a `LoginConfiguration` with `FBSDKBetaLoginExperience` set to enabled. */ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FBSDKLoginManagerLoginResultBlock)handler @@ -209,7 +212,9 @@ NS_SWIFT_NAME(reauthorizeDataAccess(from:handler:)); /** Logs the user out - This calls [FBSDKAccessToken setCurrentAccessToken:nil] and [FBSDKProfile setCurrentProfile:nil]. + This nils out the singleton instances of `FBSDKAccessToken` `FBSDKAuthenticationToken` and `FBSDKProfle`. + + @note This is only a client side logout. It will not log the user out of their Facebook account. */ - (void)logOut; From 702144f39982ebba422340e52dcfd7be809cb5e3 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 17 Dec 2020 15:19:01 -0800 Subject: [PATCH 193/227] Rename BetaLoginExperience Summary: Renaming beta login experience to login tracking. The developer site page referenced by the code documentation is currently inactive but will be live by the v9 release date. Reviewed By: ppansy Differential Revision: D25616373 fbshipit-source-id: 6151a90ef10a07bfe710059f17b14ded3f42af01 --- .../FBSDKLoginKit/FBSDKLoginButton.h | 4 +-- .../FBSDKLoginKit/FBSDKLoginButton.m | 8 ++--- .../FBSDKLoginKit/FBSDKLoginConfiguration.h | 35 ++++++++++--------- .../FBSDKLoginKit/FBSDKLoginConfiguration.m | 24 ++++++------- .../FBSDKLoginKit/FBSDKLoginManager.h | 4 ++- .../FBSDKLoginKit/FBSDKLoginManager.m | 4 +-- .../Swift/LoginConfiguration.swift | 8 ++--- .../FBSDKLoginManagerTests.m | 10 +++--- .../LoginConfigurationTests.swift | 28 +++++++-------- 9 files changed, 64 insertions(+), 61 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h index db0fb16331..4be58012a1 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h @@ -99,9 +99,9 @@ NS_SWIFT_NAME(FBLoginButton) */ @property (assign, nonatomic) FBSDKTooltipColorStyle tooltipColorStyle; /** - Gets or sets the desired beta login experience to use for login attempts. Defaults to `.enabled` + Gets or sets the desired tracking preference to use for login attempts. Defaults to `.enabled` */ -@property (assign, nonatomic) FBSDKBetaLoginExperience betaLoginExperience; +@property (assign, nonatomic) FBSDKLoginTracking loginTracking; /** Gets or sets an optional nonce to use for login attempts. A valid nonce must be a non-empty string without whitespace. An invalid nonce will not be set. Instead, default unique nonces will be used for login attempts. diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m index 375f133b49..d66d1c2b78 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m @@ -67,9 +67,9 @@ - (void)setDefaultAudience:(FBSDKDefaultAudience)defaultAudience _loginManager.defaultAudience = defaultAudience; } -- (void)setBetaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +- (void)setLoginTracking:(FBSDKLoginTracking)loginTracking { - _betaLoginExperience = betaLoginExperience; + _loginTracking = loginTracking; [self _updateNotificationObservers]; } @@ -329,11 +329,11 @@ - (FBSDKLoginConfiguration *)loginConfiguration { if (self.nonce) { return [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions - betaLoginExperience:self.betaLoginExperience + tracking:self.loginTracking nonce:self.nonce]; } else { return [[FBSDKLoginConfiguration alloc] initWithPermissions:self.permissions - betaLoginExperience:self.betaLoginExperience]; + tracking:self.loginTracking]; } } diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h index 4db5f9daf2..9f905d2970 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h @@ -20,14 +20,15 @@ NS_ASSUME_NONNULL_BEGIN -/// The login experience style to use for a login attempt -typedef NS_ENUM(NSUInteger, FBSDKBetaLoginExperience) +/// The login tracking preference to use for a login attempt. For more information on the differences between +/// `enabled` and `limited` see: https://developers.facebook.com/docs/facebook-login/ios/limited-login/ +typedef NS_ENUM(NSUInteger, FBSDKLoginTracking) { - FBSDKBetaLoginExperienceEnabled, - FBSDKBetaLoginExperienceRestricted, -} NS_SWIFT_NAME(BetaLoginExperience); + FBSDKLoginTrackingEnabled, + FBSDKLoginTrackingLimited, +} NS_SWIFT_NAME(LoginTracking); -/// A configuration to use for modifying the default behavior of a login attempt. +/// A configuration to use for modifying the behavior of a login attempt. NS_SWIFT_NAME(LoginConfiguration) @interface FBSDKLoginConfiguration : NSObject @@ -35,8 +36,8 @@ NS_SWIFT_NAME(LoginConfiguration) /// A unique nonce will be used if none is provided to the initializer. @property (nonatomic, readonly, copy) NSString *nonce; -/// The beta login experience preference. Defaults to `.enabled`. -@property (nonatomic, readonly) FBSDKBetaLoginExperience betaLoginExperience; +/// The tracking preference. Defaults to `.enabled`. +@property (nonatomic, readonly) FBSDKLoginTracking tracking; /// The requested permissions for the login attempt. Defaults to an empty set. @property (nonatomic, readonly, copy) NSSet *requestedPermissions; @@ -47,14 +48,14 @@ NS_SWIFT_NAME(LoginConfiguration) /** Attempts to initialize a new configuration with the expected parameters. - @param permissions the requested permissions for the login attempt. Permissions must be an array of strings that do not contain whitespace. - The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. - @param betaLoginExperience determines whether the login attempt should use the beta experience. + @param permissions the requested permissions for a login attempt. Permissions must be an array of strings that do not contain whitespace. + The only permissions allowed when the `loginTracking` is `.limited` are 'email' and 'public_profile'. + @param tracking the tracking preference to use for a login attempt. @param nonce an optional nonce to use for the login attempt. A valid nonce must be a non-empty string without whitespace. Creation of the configuration will fail if the nonce is invalid. */ - (nullable instancetype)initWithPermissions:(NSArray *)permissions - betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience + tracking:(FBSDKLoginTracking)tracking nonce:(NSString *)nonce NS_REFINED_FOR_SWIFT; @@ -62,19 +63,19 @@ NS_REFINED_FOR_SWIFT; Attempts to initialize a new configuration with the expected parameters. @param permissions the requested permissions for the login attempt. Permissions must be an array of strings that do not contain whitespace. - The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. - @param betaLoginExperience determines whether the login attempt should use the beta experience. + The only permissions allowed when the `loginTracking` is `.limited` are 'email' and 'public_profile'. + @param tracking the tracking preference to use for a login attempt. */ - (nullable instancetype)initWithPermissions:(NSArray *)permissions - betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience + tracking:(FBSDKLoginTracking)tracking NS_REFINED_FOR_SWIFT; /** Attempts to initialize a new configuration with the expected parameters. - @param betaLoginExperience determines whether the login attempt should use the beta experience. + @param tracking the login tracking preference to use for a login attempt. */ -- (nullable instancetype)initWithBetaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +- (nullable instancetype)initWithTracking:(FBSDKLoginTracking)tracking NS_REFINED_FOR_SWIFT; @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m index 52d6cfe57a..b995846205 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m @@ -32,22 +32,22 @@ @implementation FBSDKLoginConfiguration -- (nullable instancetype)initWithBetaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience +- (nullable instancetype)initWithTracking:(FBSDKLoginTracking)tracking { return [[FBSDKLoginConfiguration alloc] initWithPermissions:@[] - betaLoginExperience:betaLoginExperience]; + tracking:tracking]; } - (nullable instancetype)initWithPermissions:(NSArray *)permissions - betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience + tracking:(FBSDKLoginTracking)tracking { return [[FBSDKLoginConfiguration alloc] initWithPermissions:permissions - betaLoginExperience:betaLoginExperience + tracking:tracking nonce:NSUUID.UUID.UUIDString]; } - (nullable instancetype)initWithPermissions:(NSArray *)permissions - betaLoginExperience:(FBSDKBetaLoginExperience)betaLoginExperience + tracking:(FBSDKLoginTracking)tracking nonce:(NSString *)nonce { if (![FBSDKNonceUtility isValidNonce:nonce]) { @@ -58,16 +58,16 @@ - (nullable instancetype)initWithPermissions:(NSArray *)permissions NSSet *permissionsSet = [NSSet setWithArray:permissions]; BOOL arePermissionsValid = [FBSDKLoginConfiguration _arePermissionsValid:permissionsSet - forBetaLoginExperienceStatus:betaLoginExperience]; + forTrackingPreference:tracking]; if (!arePermissionsValid) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors - formatString:@"Invalid combination of permissions and beta experience preference provided to login configuration. The only permissions allowed when the `betaLoginExperince` is `.restricted` are 'email' and 'public_profile'. Returning nil."]; + formatString:@"Invalid combination of permissions and tracking preference provided to login configuration. The only permissions allowed when `tracking` is `.limited` are 'email' and 'public_profile'. Returning nil."]; return nil; } if ((self = [super init])) { _requestedPermissions = permissionsSet; - _betaLoginExperience = betaLoginExperience; + _tracking = tracking; _nonce = nonce; } @@ -78,17 +78,17 @@ - (instancetype)init { if ((self = [super init])) { _requestedPermissions = [NSSet set]; - _betaLoginExperience = FBSDKBetaLoginExperienceEnabled; + _tracking = FBSDKLoginTrackingEnabled; _nonce = NSUUID.UUID.UUIDString; } return self; } -+ (BOOL) _arePermissionsValid:(NSSet *)permissions - forBetaLoginExperienceStatus:(FBSDKBetaLoginExperience)betaLoginExperience ++ (BOOL)_arePermissionsValid:(NSSet *)permissions + forTrackingPreference:(FBSDKLoginTracking)tracking { - if (betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { + if (tracking == FBSDKLoginTrackingLimited) { NSSet *validPermissions = [NSSet setWithArray:@[@"email", @"public_profile"]]; NSSet *combined = [permissions setByAddingObjectsFromSet:validPermissions]; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index 9e73b49300..1c0963ed5c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -194,9 +194,11 @@ NS_SWIFT_NAME(logIn(url:handler:)); /** Requests user's permission to reathorize application's data access, after it has expired due to inactivity. @param fromViewController the view controller to present from. If nil, the topmost view controller will be - automatically determined as best as possible. + automatically determined as best as possible. @param handler the callback. + @warning This method will reauthorize using a `LoginConfiguration` with `FBSDKLoginTracking` set to `.enabled`. + Use this method when you need to reathorize your app's access to user data via Graph API, after such an access has expired. You should provide as much context to the user as possible as to why you need to reauthorize the access, the scope of access being reathorized, and what added value your app provides when the access is reathorized. diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 9956d8dac8..fa801b7af2 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -111,7 +111,7 @@ - (void)logInWithPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerLoginResultBlock)handler { FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:permissions - betaLoginExperience:FBSDKBetaLoginExperienceEnabled]; + tracking:FBSDKLoginTrackingEnabled]; [self logInFromViewController:viewController configuration:config completion:handler]; @@ -414,7 +414,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co [self storeExpectedChallenge:expectedChallenge]; NSString *responseType; - if (configuration.betaLoginExperience == FBSDKBetaLoginExperienceRestricted) { + if (configuration.tracking == FBSDKLoginTrackingLimited) { responseType = @"id_token"; [FBSDKTypeUtility dictionary:loginParams setObject:@"sentinel_test_value" forKey:@"tp"]; } else { diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift index e7e0c52b6c..292fd05d29 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginConfiguration.swift @@ -24,21 +24,21 @@ public extension LoginConfiguration { Attempts to allocate and initialize a new configuration with the expected parameters. - parameter permissions: The requested permissions for the login attempt. - The only permissions allowed when the `betaLoginExperience` is `.restricted` are 'email' and 'public_profile'. + The only permissions allowed when `tracking` is `.limited` are 'email' and 'public_profile'. Defaults to an empty `Permission` array. - - parameter beta: Determines whether the login attempt should use the beta experience. Defaults to `.enabled` + - parameter tracking: The tracking preference to use for a login attempt. Defaults to `.enabled` - parameter nonce: An optional nonce to use for the login attempt. A valid nonce must be an alphanumeric string without whitespace. Creation of the configuration will fail if the nonce is invalid. Defaults to a `UUID` string. */ convenience init?( permissions: Set = [], - betaLoginExperience: BetaLoginExperience = .enabled, + tracking: LoginTracking = .enabled, nonce: String = UUID().uuidString ) { self.init( __permissions: permissions.map { $0.name }, - betaLoginExperience: betaLoginExperience, + tracking: tracking, nonce: nonce ) } diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 8f8802395e..4417275327 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -499,7 +499,7 @@ - (void)testCallingLoginWithNilConfigurationShouldFail }; FBSDKLoginConfiguration *invalidConfig = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[] - betaLoginExperience:FBSDKBetaLoginExperienceRestricted + tracking:FBSDKLoginTrackingLimited nonce:@" "]; XCTAssertNil(invalidConfig); @@ -507,11 +507,11 @@ - (void)testCallingLoginWithNilConfigurationShouldFail XCTAssertTrue(resultBlockInvoked, "Should invoke completion synchronously"); } -- (void)testBetaLoginExperienceEnabledLoginParams +- (void)testLoginTrackingEnabledLoginParams { FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"] - betaLoginExperience:FBSDKBetaLoginExperienceEnabled]; + tracking:FBSDKLoginTrackingEnabled]; NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:config serverConfiguration:nil]; [self validateCommonLoginParameters:params]; @@ -521,11 +521,11 @@ - (void)testBetaLoginExperienceEnabledLoginParams XCTAssertNil(params[@"tp"]); } -- (void)testBetaLoginExperienceRestrictedLoginParams +- (void)testLoginTrackingLimitedLoginParams { FBSDKLoginConfiguration *config = [[FBSDKLoginConfiguration alloc] initWithPermissions:@[@"public_profile", @"email"] - betaLoginExperience:FBSDKBetaLoginExperienceRestricted + tracking:FBSDKLoginTrackingLimited nonce:@"some_nonce"]; NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:config serverConfiguration:nil]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift index ea970c0dfc..b5817766d7 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift @@ -31,9 +31,9 @@ class LoginConfigurationTests: XCTestCase { "A config should be created with default requested permissions" ) XCTAssertEqual( - config.betaLoginExperience, + config.tracking, .enabled, - "Beta login experience should default to enabled when unspecified" + "Tracking should default to enabled when unspecified" ) XCTAssertNotNil( config.nonce, @@ -58,17 +58,17 @@ class LoginConfigurationTests: XCTestCase { ) } - func testCreatingWithBetaLoginExperience() { + func testCreatingWithTracking() { let preferences = [ - BetaLoginExperience.enabled, - .restricted + LoginTracking.enabled, + .limited ] preferences.forEach { preference in - let config = LoginConfiguration(betaLoginExperience: preference) + let config = LoginConfiguration(tracking: preference) XCTAssertEqual( - config?.betaLoginExperience, + config?.tracking, preference, - "Should create a configuration with the provided beta login experience preference" + "Should create a configuration with the provided tracking preference" ) } } @@ -80,30 +80,30 @@ class LoginConfigurationTests: XCTestCase { XCTAssertEqual( config?.requestedPermissions, Set(permissions.map { $0.name }), - "Should create a configuration with the provided beta login experience preference" + "Should create a configuration with the provided tracking preference" ) } - func testCreatingWithPermissionsForRestrictedBetaLoginExperience() { + func testCreatingWithPermissionsForLimitedTracking() { let allowedPermissions = Set([Permission.email]) let disallowedPermissions = Set([Permission.userBirthday, .userPosts]) var configuration = LoginConfiguration( permissions: disallowedPermissions, - betaLoginExperience: .restricted + tracking: .limited ) XCTAssertNil( configuration, - "Should not create a configuration with permissions that are disallowed based on the beta login experience preference" // swiftlint:disable:this line_length + "Should not create a configuration with permissions that are disallowed based on the tracking preference" // swiftlint:disable:this line_length ) configuration = LoginConfiguration( permissions: allowedPermissions, - betaLoginExperience: .restricted + tracking: .limited ) XCTAssertNotNil( configuration, - "Should create a configuration with permissions that are allowed based on the beta login experience preference" // swiftlint:disable:this line_length + "Should create a configuration with permissions that are allowed based on the tracking preference" // swiftlint:disable:this line_length ) } } From 285c81b0ee5c621967d382deead80358fb9f7377 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 17 Dec 2020 16:58:07 -0800 Subject: [PATCH 194/227] Add no-nonce check Summary: Ensure that parameters do not include a nonce when ID token is also present. Return an error in those cases. Reviewed By: joesus Differential Revision: D25625287 fbshipit-source-id: ed9787b782a4526e788dc75df226322309506100 --- .../Internal/FBSDKLoginCompletion.h | 31 ++++++++++--------- .../Internal/FBSDKLoginCompletion.m | 13 ++++---- .../FBSDKLoginCompletionTests.m | 10 ++++++ 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h index 5d219be363..8e4e234de9 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h @@ -47,28 +47,29 @@ NS_SWIFT_NAME(LoginCompletionParameters) - (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithError:(NSError *)error; -@property (nonatomic, readonly) FBSDKAuthenticationToken *authenticationToken; -@property (nonatomic, readonly) FBSDKProfile *profile; +@property (nullable, nonatomic, readonly) FBSDKAuthenticationToken *authenticationToken; +@property (nullable, nonatomic, readonly) FBSDKProfile *profile; -@property (nonatomic, copy, readonly) NSString *accessTokenString; -@property (nonatomic, copy, readonly) NSString *nonceString; -@property (nonatomic, copy, readonly) NSString *authenticationTokenString; +@property (nullable, nonatomic, copy, readonly) NSString *accessTokenString; +@property (nullable, nonatomic, copy, readonly) NSString *nonceString; +@property (nullable, nonatomic, copy, readonly) NSString *authenticationTokenString; -@property (nonatomic, copy, readonly) NSSet *permissions; -@property (nonatomic, copy, readonly) NSSet *declinedPermissions; -@property (nonatomic, copy, readonly) NSSet *expiredPermissions; +@property (nullable, nonatomic, copy, readonly) NSSet *permissions; +@property (nullable, nonatomic, copy, readonly) NSSet *declinedPermissions; +@property (nullable, nonatomic, copy, readonly) NSSet *expiredPermissions; -@property (nonatomic, copy, readonly) NSString *appID; -@property (nonatomic, copy, readonly) NSString *userID; +@property (nullable, nonatomic, copy, readonly) NSString *appID; +@property (nullable, nonatomic, copy, readonly) NSString *userID; -@property (nonatomic, copy, readonly) NSError *error; +@property (nullable, nonatomic, copy, readonly) NSError *error; -@property (nonatomic, copy, readonly) NSDate *expirationDate; -@property (nonatomic, copy, readonly) NSDate *dataAccessExpirationDate; +@property (nullable, nonatomic, copy, readonly) NSDate *expirationDate; +@property (nullable, nonatomic, copy, readonly) NSDate *dataAccessExpirationDate; -@property (nonatomic, copy, readonly) NSString *challenge; +@property (nullable, nonatomic, copy, readonly) NSString *challenge; + +@property (nullable, nonatomic, copy, readonly) NSString *graphDomain; -@property (nonatomic, copy, readonly) NSString *graphDomain; @end NS_SWIFT_NAME(LoginCompleting) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index c76447ab42..a7ad0d19ee 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -71,16 +71,15 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; - BOOL hasNonEmptyNonceString = [parameters[@"nonce"] length] > 0; - BOOL hasNonEmptyIdTokenString = [parameters[@"id_token"] length] > 0; + BOOL hasNonEmptyNonceString = ((NSString *)[FBSDKTypeUtility dictionary:parameters objectForKey:@"nonce" ofType:NSString.class]).length > 0; + BOOL hasNonEmptyIdTokenString = ((NSString *)[FBSDKTypeUtility dictionary:parameters objectForKey:@"id_token" ofType:NSString.class]).length > 0; + BOOL hasNonEmptyAccessTokenString = ((NSString *)[FBSDKTypeUtility dictionary:parameters objectForKey:@"access_token" ofType:NSString.class]).length > 0; - // TODO: T81282385 - Error if nonce and ID Token // Nonce and id token are mutually exclusive parameters - // BOOL isInvalid = (hasNonEmptyNonceString && hasNonEmptyIdTokenString); + BOOL hasBothNonceAndIdToken = hasNonEmptyNonceString && hasNonEmptyIdTokenString; + BOOL hasEitherNonceOrIdToken = hasNonEmptyNonceString || hasNonEmptyIdTokenString; - if ([parameters[@"access_token"] length] > 0 - || hasNonEmptyNonceString - || hasNonEmptyIdTokenString) { + if (hasNonEmptyAccessTokenString || (hasEitherNonceOrIdToken && !hasBothNonceAndIdToken)) { [self setParametersWithDictionary:parameters appID:appID]; } else { [self setErrorWithDictionary:parameters]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m index 4d0fc5ff7f..1272c0e22b 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -141,6 +141,16 @@ - (void)testInitWithEmptyParameters [self verifyEmptyParameters:completer.parameters]; } +- (void)testInitWithBothIdTokenAndNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token"]]; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + + XCTAssertNotNil(completer.parameters.error); +} + - (void)testInitWithError { NSMutableDictionary *parameters = _parameters.mutableCopy; From d7be85cd27212336533b0e25da51580d76bb737f Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Thu, 17 Dec 2020 16:59:13 -0800 Subject: [PATCH 195/227] Reset State when Missing Login Configuration Summary: We currently change the login state when validating. This is not great and we need to refactor so it doesn't do that. In the meantime this fixes the bug without introducing more complexity to the validation method. Reviewed By: ppansy Differential Revision: D25626071 fbshipit-source-id: fd42ec6b590e3d09c3b4c9db5899dfd185eaf10f --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index fa801b7af2..3238508dbf 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -96,7 +96,9 @@ - (void)logInFromViewController:(UIViewController *)viewController [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:failureMessage]; NSError *error = [FBSDKError errorWithCode:FBSDKErrorInvalidArgument message:failureMessage]; - completion(nil, error); + + _handler = [completion copy]; + [self invokeHandler:nil error:error]; return; } From a5f4ae10975ccf17c2206ee7d807c46cb63d9168 Mon Sep 17 00:00:00 2001 From: Rob Hudson Date: Thu, 17 Dec 2020 17:15:23 -0800 Subject: [PATCH 196/227] Add FBSDKAuthenticationTokenHeader object Summary: Refactor authentication token header from NSDictionary to a new class (FBSDKAuthenticationTokenHeader). Reviewed By: joesus Differential Revision: D25627398 fbshipit-source-id: e73e87b45bbdade1988be6dfe10ebdd16eb012c0 --- .../FBSDKCoreKit.xcodeproj/project.pbxproj | 16 +++- .../FBSDKAuthenticationTokenFactory.m | 29 +------ .../Internal/FBSDKAuthenticationTokenHeader.h | 42 ++++++++++ .../Internal/FBSDKAuthenticationTokenHeader.m | 80 +++++++++++++++++++ .../Internal/FBSDKCoreKit+Internal.h | 2 + .../FBSDKAuthenticationTokenFactoryTests.m | 45 +++++++---- 6 files changed, 170 insertions(+), 44 deletions(-) create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.h create mode 100644 FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m diff --git a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj index 8d5b5f9664..ee0a1f263d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj +++ b/FBSDKCoreKit/FBSDKCoreKit.xcodeproj/project.pbxproj @@ -184,6 +184,10 @@ 5DBC72D22373793400A9D859 /* FBSDKModelManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBC72D02373792A00A9D859 /* FBSDKModelManager.h */; }; 5DBC72D82373795600A9D859 /* FBSDKModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */; }; 5DBC72D92373795600A9D859 /* FBSDKModelManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */; }; + 5E3AFFE7258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E3AFFE5258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h */; }; + 5E3AFFE8258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E3AFFE5258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h */; }; + 5E3AFFE9258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3AFFE6258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m */; }; + 5E3AFFEA258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E3AFFE6258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m */; }; 5E47555D2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */; }; 5E47555E2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */; }; 5EF17EE52582DE3300FAA5D2 /* FBSDKAuthenticationTokenClaims.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */; }; @@ -1307,6 +1311,8 @@ 5DBB0446227FEF700009E0A6 /* FBSDKBasicUtilityTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKBasicUtilityTests.m; sourceTree = ""; }; 5DBC72D02373792A00A9D859 /* FBSDKModelManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKModelManager.h; sourceTree = ""; }; 5DBC72D72373795600A9D859 /* FBSDKModelManager.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = FBSDKModelManager.mm; sourceTree = ""; }; + 5E3AFFE5258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationTokenHeader.h; sourceTree = ""; }; + 5E3AFFE6258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenHeader.m; sourceTree = ""; }; 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAuthenticationTokenClaims.h; sourceTree = ""; }; 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKAuthenticationTokenClaims.m; sourceTree = ""; }; 5F7063FA1AF733F300E42ED7 /* FBSDKAppEventsDeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKAppEventsDeviceInfo.h; sourceTree = ""; }; @@ -2034,11 +2040,13 @@ 52963A9E215993C100C7B252 /* FBSDKAppLink_Internal.h */, 52963A9B215993C100C7B252 /* FBSDKAppLinkReturnToRefererView_Internal.h */, 894C0ACD1A6F0D3F009137EF /* FBSDKApplicationDelegate+Internal.h */, + C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */, + C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */, 5E47555B2580577B00C98E30 /* FBSDKAuthenticationTokenClaims.h */, 5E47555C2580577C00C98E30 /* FBSDKAuthenticationTokenClaims.m */, + 5E3AFFE5258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h */, + 5E3AFFE6258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m */, C6A308BA257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.h */, - C6C5CBCB2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.h */, - C6C5CBCA2581871B00AA3BB3 /* FBSDKAuthenticationStatusUtility.m */, C6A308BB257AD1FF003C52FD /* FBSDKAuthenticationTokenFactory.m */, C5188DF8222F388400F4D8BC /* FBSDKApplicationObserving.h */, 89D05AA71AA1134000609300 /* FBSDKAudioResourceLoader.h */, @@ -3011,6 +3019,7 @@ 81B71D601D19C87400933E93 /* FBSDKMutableCopying.h in Headers */, F42004902416C30300AD7006 /* FBSDKMonitor.h in Headers */, 81B71D611D19C87400933E93 /* FBSDKErrorRecoveryAttempter.h in Headers */, + 5E3AFFE8258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h in Headers */, 81B71D621D19C87400933E93 /* FBSDKPaymentObserver.h in Headers */, E4416C1323F61911009CCBFA /* FBSDKModelParser.h in Headers */, F40F6562241A99E000B10EAA /* FBSDKMethodUsageMonitorEntry.h in Headers */, @@ -3175,6 +3184,7 @@ 52963A90215992F400C7B252 /* FBSDKAppLinkTarget.h in Headers */, C5696F83209BBC35009C931F /* FBSDKViewHierarchy.h in Headers */, C5EAFA5E255283C100458DF5 /* FBSDKUserDataStore+Internal.h in Headers */, + 5E3AFFE7258C191200BE46AB /* FBSDKAuthenticationTokenHeader.h in Headers */, 9DA81AF61AA4EF3300B9FE0B /* FBSDKProfile.h in Headers */, 5DBC72D12373793300A9D859 /* FBSDKModelManager.h in Headers */, C4FC99D9202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.h in Headers */, @@ -3965,6 +3975,7 @@ 81B71D041D19C87400933E93 /* FBSDKGraphRequest.m in Sources */, F9CBE51424E090590097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, 81B71D051D19C87400933E93 /* FBSDKContainerViewController.m in Sources */, + 5E3AFFEA258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m in Sources */, 81B71D061D19C87400933E93 /* FBSDKTokenCache.m in Sources */, 81B71D071D19C87400933E93 /* FBSDKCrypto.m in Sources */, F4FE998024D906BA008879A4 /* FBSDKJSONValue.m in Sources */, @@ -4098,6 +4109,7 @@ 9DC658961A6EE5C500B85AAF /* FBSDKGraphRequest.m in Sources */, F9CBE51224E085CD0097B442 /* FBSDKSKAdNetworkReporter.m in Sources */, 9D195CC91B9FE2E000BD6BEC /* FBSDKContainerViewController.m in Sources */, + 5E3AFFE9258C191200BE46AB /* FBSDKAuthenticationTokenHeader.m in Sources */, C4FC99DA202CD5590038C5ED /* FBSDKHybridAppEventsScriptMessageHandler.m in Sources */, 9D32A8461A699459000A936D /* FBSDKTokenCache.m in Sources */, F4FE997F24D906BA008879A4 /* FBSDKJSONValue.m in Sources */, diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m index 19ebd69625..ebc34f0ac5 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -56,9 +56,6 @@ - (instancetype)initWithTokenString:(NSString *)tokenString @implementation FBSDKAuthenticationTokenFactory { NSString *_cert; - NSDictionary *_claims; - NSDictionary *_header; - NSString *_signature; id _sessionProvider; } @@ -87,7 +84,7 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString NSString *signature; FBSDKAuthenticationTokenClaims *claims; - NSDictionary *header; + FBSDKAuthenticationTokenHeader *header; NSArray *segments = [tokenString componentsSeparatedByString:@"."]; if (segments.count != 3) { @@ -100,12 +97,9 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString signature = [FBSDKTypeUtility array:segments objectAtIndex:2]; claims = [FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:nonce]; - header = [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; - NSString *certificateKey = [FBSDKTypeUtility dictionary:header - objectForKey:@"kid" - ofType:NSString.class]; + header = [FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]; - if (!claims || !header || !certificateKey) { + if (!claims || !header) { completion(nil); return; } @@ -113,7 +107,7 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString [self verifySignature:signature header:encodedHeader claims:encodedClaims - certificateKey:certificateKey + certificateKey:header.kid completion:^(BOOL success) { if (success) { FBSDKAuthenticationToken *token = [[FBSDKAuthenticationToken alloc] initWithTokenString:tokenString nonce:nonce claims:claims]; @@ -124,21 +118,6 @@ - (void)createTokenFromTokenString:(NSString *_Nonnull)tokenString }]; } -+ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader -{ - NSError *error; - NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKBase64 base64FromBase64Url:encodedHeader]]; - - if (headerData) { - NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; - if (!error && [header[@"alg"] isKindOfClass:[NSString class]] && [header[@"alg"] isEqualToString:@"RS256"]) { - return header; - } - } - - return nil; -} - - (void)verifySignature:(NSString *)signature header:(NSString *)header claims:(NSString *)claims diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.h new file mode 100644 index 0000000000..6dea5a95c7 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.h @@ -0,0 +1,42 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface FBSDKAuthenticationTokenHeader : NSObject + +/// Value that represents the algorithm that was used to sign the JWT. +@property (nonatomic, readonly, strong) NSString *alg; + +/// The type of the JWT. +@property (nonatomic, readonly, strong) NSString *typ; + +/// Key identifier used in identifying the key to be used to verify the signature. +@property (nonatomic, readonly, strong) NSString *kid; + +/** + Returns a new instance, when one can be created from the parameters given, otherwise `nil`. + @param encodedHeader Base64-encoded string of the header. + */ ++ (nullable FBSDKAuthenticationTokenHeader *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m new file mode 100644 index 0000000000..c819e5d293 --- /dev/null +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m @@ -0,0 +1,80 @@ +// 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 "FBSDKAuthenticationTokenHeader.h" + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +@implementation FBSDKAuthenticationTokenHeader + +- (instancetype)initWithAlg:(NSString *)alg + typ:(NSString *)typ + kid:(NSString *)kid +{ + if (self = [super init]) { + _alg = alg; + _typ = typ; + _kid = kid; + } + + return self; +} + ++ (nullable FBSDKAuthenticationTokenHeader *)validatedHeaderWithEncodedString:(NSString *)encodedHeader +{ + NSError *error; + NSData *headerData = [FBSDKBase64 decodeAsData:[FBSDKBase64 base64FromBase64Url:encodedHeader]]; + + if (headerData) { + NSDictionary *header = [FBSDKTypeUtility JSONObjectWithData:headerData options:0 error:&error]; + NSString *alg = [FBSDKTypeUtility dictionary:header objectForKey:@"alg" ofType:NSString.class]; + NSString *typ = [FBSDKTypeUtility dictionary:header objectForKey:@"typ" ofType:NSString.class]; + NSString *kid = [FBSDKTypeUtility dictionary:header objectForKey:@"kid" ofType:NSString.class]; + if (!error && alg.length > 0 && [alg isEqualToString:@"RS256"] && kid.length > 0) { + return [[FBSDKAuthenticationTokenHeader alloc] initWithAlg:alg typ:typ kid:kid]; + } + } + + return nil; +} + +- (BOOL)isEqualToHeader:(FBSDKAuthenticationTokenHeader *)header +{ + return [_alg isEqualToString:header.alg] + && [_typ isEqualToString:header.typ] + && [_kid isEqualToString:header.kid]; +} + +- (BOOL)isEqual:(id)object +{ + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[FBSDKAuthenticationTokenHeader class]]) { + return NO; + } + + return [self isEqualToHeader:(FBSDKAuthenticationTokenHeader *)object]; +} + +@end diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h index 4c33794349..d27b82aba1 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h @@ -75,6 +75,7 @@ #import "FBSDKAuthenticationToken+Internal.h" #import "FBSDKAuthenticationTokenClaims.h" #import "FBSDKAuthenticationTokenFactory.h" + #import "FBSDKAuthenticationTokenHeader.h" #import "FBSDKBase64.h" #import "FBSDKButton+Subclass.h" #import "FBSDKDeviceRequestsHelper.h" @@ -157,6 +158,7 @@ #import "FBSDKAuthenticationToken+Internal.h" #import "FBSDKAuthenticationTokenClaims.h" #import "FBSDKAuthenticationTokenFactory.h" + #import "FBSDKAuthenticationTokenHeader.h" #import "FBSDKDeviceRequestsHelper.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKError.h" diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index 1bd25b9d1e..a41ff8e96e 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -37,8 +37,6 @@ typedef void (^FBSDKVerifySignatureCompletionBlock)(BOOL success); @interface FBSDKAuthenticationTokenFactory (Testing) -+ (NSDictionary *)validatedClaimsWithEncodedString:(NSString *)encodedClaims nonce:(NSString *)nonce; -+ (NSDictionary *)validatedHeaderWithEncodedString:(NSString *)encodedHeader; - (instancetype)initWithSessionProvider:(id)sessionProvider; - (void)setCertificate:(NSString *)certificate; @@ -65,6 +63,14 @@ - (instancetype)initWithJti:(NSString *)jti @end +@interface FBSDKAuthenticationTokenHeader (Testing) + +- (instancetype)initWithAlg:(NSString *)alg + typ:(NSString *)typ + kid:(NSString *)kid; + +@end + @interface FBSDKAuthenticationTokenFactoryTests : FBSDKTestCase @end @@ -73,7 +79,8 @@ @implementation FBSDKAuthenticationTokenFactoryTests { FBSDKAuthenticationTokenClaims *_claims; NSDictionary *_claimsDict; - NSDictionary *_header; + FBSDKAuthenticationTokenHeader *_header; + NSDictionary *_headerDict; } - (void)setUp @@ -95,12 +102,6 @@ - (void)setUp email:@"email@email.com" picture:@"https://www.facebook.com/some_picture"]; - _header = @{ - @"alg" : @"RS256", - @"typ" : @"JWT", - @"kid" : @"abcd1234", - }; - _claimsDict = @{ @"iss" : _facebookURL, @"aud" : _mockAppID, @@ -113,6 +114,16 @@ - (void)setUp @"email" : @"email@email.com", @"picture" : @"https://www.facebook.com/some_picture", }; + + _header = [[FBSDKAuthenticationTokenHeader alloc] initWithAlg:@"RS256" + typ:@"JWT" + kid:@"abcd1234"]; + + _headerDict = @{ + @"alg" : @"RS256", + @"typ" : @"JWT", + @"kid" : @"abcd1234", + }; } // MARK: - Creation @@ -210,10 +221,10 @@ - (void)testDecodeRandomClaims - (void)testDecodeValidHeader { - NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_header options:0 error:nil]; + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:_headerDict options:0 error:nil]; NSString *encodedHeader = [self base64URLEncodeData:headerData]; - NSDictionary *header = [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; + FBSDKAuthenticationTokenHeader *header = [FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]; XCTAssertEqualObjects(header, _header); } @@ -222,17 +233,17 @@ - (void)testDecodeInvalidFormatHeader NSData *headerData = [@"invalid_header" dataUsingEncoding:NSUTF8StringEncoding]; NSString *encodedHeader = [self base64URLEncodeData:headerData]; - XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); + XCTAssertNil([FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]); } - (void)testDecodeInvalidHeader { - NSMutableDictionary *invalidHeader = [_header mutableCopy]; + NSMutableDictionary *invalidHeader = [_headerDict mutableCopy]; [FBSDKTypeUtility dictionary:invalidHeader setObject:@"wrong algorithm" forKey:@"alg"]; NSData *invalidHeaderData = [FBSDKTypeUtility dataWithJSONObject:invalidHeader options:0 error:nil]; NSString *encodedHeader = [self base64URLEncodeData:invalidHeaderData]; - XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); + XCTAssertNil([FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]); } - (void)testDecodeEmptyHeader @@ -241,17 +252,17 @@ - (void)testDecodeEmptyHeader NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:header options:0 error:nil]; NSString *encodedHeader = [self base64URLEncodeData:headerData]; - XCTAssertNil([FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]); + XCTAssertNil([FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]); } - (void)testDecodeRandomHeader { for (int i = 0; i < 100; i++) { - NSDictionary *randomizedHeader = [Fuzzer randomizeWithJson:_header]; + NSDictionary *randomizedHeader = [Fuzzer randomizeWithJson:_headerDict]; NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:randomizedHeader options:0 error:nil]; NSString *encodedHeader = [self base64URLEncodeData:headerData]; - [FBSDKAuthenticationTokenFactory validatedHeaderWithEncodedString:encodedHeader]; + [FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]; } } From df8ff48b02b9e8b9fb5dcbcae75c7d62bbb4cd6a Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Thu, 17 Dec 2020 18:12:45 -0800 Subject: [PATCH 197/227] Add FBSDKLoginCompletion fuzzy test Summary: title Reviewed By: joesus Differential Revision: D25554295 fbshipit-source-id: 6531785c2de3f9f4bccbd9e05933a2156201ff94 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 4 + .../Internal/FBSDKLoginCompletion.m | 96 +++++++++---- .../FBSDKLoginKit/Internal/FBSDKLoginError.m | 8 +- .../FBSDKLoginCompletionTests.m | 9 ++ FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift | 132 ++++++++++++++++++ 5 files changed, 215 insertions(+), 34 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 53f512c973..6fda41c1d5 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -135,6 +135,7 @@ C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */; }; + C67DC42D258851C3004D7E43 /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C67DC42C258851C3004D7E43 /* Fuzzer.swift */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -389,6 +390,7 @@ 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginCompletionTests.m; sourceTree = ""; }; + C67DC42C258851C3004D7E43 /* Fuzzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -681,6 +683,7 @@ 9D9DB8E91A114E500086167B /* Supporting Files */, F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */, C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */, + C67DC42C258851C3004D7E43 /* Fuzzer.swift */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -1196,6 +1199,7 @@ files = ( F47E5CDC25895C5F008CA03E /* FBSDKLoginManagerTests.m in Sources */, F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */, + C67DC42D258851C3004D7E43 /* Fuzzer.swift in Sources */, F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index a7ad0d19ee..1d8f427fdb 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -132,23 +132,23 @@ - (void)fetchAndSetPropertiesForParameters:(nonnull FBSDKLoginCompletionParamete - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString *)appID { - NSString *grantedPermissionsString = parameters[@"granted_scopes"]; - NSString *declinedPermissionsString = parameters[@"denied_scopes"]; + NSString *grantedPermissionsString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"granted_scopes" ofType:NSString.class]; + NSString *declinedPermissionsString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"denied_scopes" ofType:NSString.class]; + NSString *signedRequest = [FBSDKTypeUtility dictionary:parameters objectForKey:@"signed_request" ofType:NSString.class]; + NSString *userID = [FBSDKTypeUtility dictionary:parameters objectForKey:@"user_id" ofType:NSString.class]; + NSString *domain = [FBSDKTypeUtility dictionary:parameters objectForKey:@"graph_domain" ofType:NSString.class]; - NSString *signedRequest = parameters[@"signed_request"]; - NSString *userID = parameters[@"user_id"]; - - _parameters.accessTokenString = parameters[@"access_token"]; - _parameters.nonceString = parameters[@"nonce"]; - _parameters.authenticationTokenString = parameters[@"id_token"]; + _parameters.accessTokenString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"access_token" ofType:NSString.class]; + _parameters.nonceString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"nonce" ofType:NSString.class]; + _parameters.authenticationTokenString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"id_token" ofType:NSString.class]; // check the string length so that we assign an empty set rather than a set with an empty string _parameters.permissions = (grantedPermissionsString.length > 0) ? [NSSet setWithArray:[grantedPermissionsString componentsSeparatedByString:@","]] - : [NSSet set]; + : NSSet.set; _parameters.declinedPermissions = (declinedPermissionsString.length > 0) ? [NSSet setWithArray:[declinedPermissionsString componentsSeparatedByString:@","]] - : [NSSet set]; + : NSSet.set; _parameters.expiredPermissions = [NSSet set]; @@ -160,32 +160,18 @@ - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString * _parameters.userID = userID; } - NSString *expirationDateString = parameters[@"expires"] ?: parameters[@"expires_at"]; - NSDate *expirationDate = [NSDate distantFuture]; - if (expirationDateString && expirationDateString.doubleValue > 0) { - expirationDate = [NSDate dateWithTimeIntervalSince1970:expirationDateString.doubleValue]; - } else if (parameters[@"expires_in"] && [parameters[@"expires_in"] integerValue] > 0) { - expirationDate = [NSDate dateWithTimeIntervalSinceNow:[parameters[@"expires_in"] integerValue]]; - } - _parameters.expirationDate = expirationDate; - - NSDate *dataAccessExpirationDate = [NSDate distantFuture]; - if (parameters[@"data_access_expiration_time"] && [parameters[@"data_access_expiration_time"] integerValue] > 0) { - dataAccessExpirationDate = [NSDate dateWithTimeIntervalSince1970:[parameters[@"data_access_expiration_time"] integerValue]]; + if (domain.length > 0) { + _parameters.graphDomain = domain; } - _parameters.dataAccessExpirationDate = dataAccessExpirationDate; - NSError *error = nil; - NSDictionary *state = [FBSDKBasicUtility objectForJSONString:parameters[@"state"] error:&error]; - _parameters.challenge = [FBSDKUtility URLDecode:state[@"challenge"]]; - - NSString *domain = parameters[@"graph_domain"]; - _parameters.graphDomain = [domain copy]; + _parameters.expirationDate = [FBSDKLoginURLCompleter expirationDateFromParameters:parameters]; + _parameters.dataAccessExpirationDate = [FBSDKLoginURLCompleter dataAccessExpirationDateFromParameters:parameters]; + _parameters.challenge = [FBSDKLoginURLCompleter challengeFromParameters:parameters]; } - (void)setErrorWithDictionary:(NSDictionary *)parameters { - NSString *legacyErrorReason = parameters[@"error"]; + NSString *legacyErrorReason = [FBSDKTypeUtility dictionary:parameters objectForKey:@"error" ofType:NSString.class]; if ([legacyErrorReason isEqualToString:@"service_disabled_use_browser"] || [legacyErrorReason isEqualToString:@"service_disabled"]) { @@ -271,6 +257,56 @@ + (nullable FBSDKProfile *)profileWithClaims:(FBSDKAuthenticationTokenClaims *)c email:claims.email]; } ++ (NSDate *)expirationDateFromParameters:(NSDictionary *)parameters +{ + NSString *expiresString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"expires" ofType:NSString.class]; + NSString *expiresAtString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"expires_at" ofType:NSString.class]; + NSString *expiresInString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"expires_in" ofType:NSString.class]; + NSString *expirationDateString = expiresString ?: expiresAtString; + + if (expirationDateString.doubleValue > 0) { + return [NSDate dateWithTimeIntervalSince1970:expirationDateString.doubleValue]; + } else if (expiresInString.integerValue > 0) { + return [NSDate dateWithTimeIntervalSinceNow:expiresInString.integerValue]; + } else { + return NSDate.distantFuture; + } +} + ++ (NSDate *)dataAccessExpirationDateFromParameters:(NSDictionary *)parameters +{ + NSString *dataAccessExpirationDateString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"data_access_expiration_time" ofType:NSString.class]; + if (dataAccessExpirationDateString.integerValue > 0) { + return [NSDate dateWithTimeIntervalSince1970:dataAccessExpirationDateString.integerValue]; + } else { + return NSDate.distantFuture; + } +} + ++ (NSString *)challengeFromParameters:(NSDictionary *)parameters +{ + NSString *stateString = [FBSDKTypeUtility dictionary:parameters objectForKey:@"state" ofType:NSString.class]; + if (stateString.length > 0) { + NSError *error = nil; + NSDictionary *state = [FBSDKBasicUtility objectForJSONString:stateString error:&error]; + + if (!error) { + NSString *challenge = [FBSDKTypeUtility dictionary:state objectForKey:@"challenge" ofType:NSString.class]; + if (challenge.length > 0) { + return [FBSDKUtility URLDecode:state[@"challenge"]]; + } + } + } + return nil; +} + +// MARK: Test Helpers + +- (FBSDKLoginCompletionParameters *)parameters +{ + return _parameters; +} + @end #endif diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m index 21588573f8..8d4ee00c0c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m @@ -149,14 +149,14 @@ + (NSError *)fbErrorFromReturnURLParameters:(NSDictionary *)parameters NSError *error = nil; NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; - [FBSDKTypeUtility dictionary:userInfo setObject:parameters[@"error_message"] forKey:FBSDKErrorDeveloperMessageKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:[FBSDKTypeUtility dictionary:parameters objectForKey:@"error_message" ofType:NSString.class] forKey:FBSDKErrorDeveloperMessageKey]; if (userInfo.count > 0) { - [FBSDKTypeUtility dictionary:userInfo setObject:parameters[@"error"] forKey:FBSDKErrorDeveloperMessageKey]; - [FBSDKTypeUtility dictionary:userInfo setObject:parameters[@"error_code"] forKey:FBSDKGraphRequestErrorGraphErrorCodeKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:[FBSDKTypeUtility dictionary:parameters objectForKey:@"error" ofType:NSString.class] forKey:FBSDKErrorDeveloperMessageKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:[FBSDKTypeUtility dictionary:parameters objectForKey:@"error_code" ofType:NSString.class] forKey:FBSDKGraphRequestErrorGraphErrorCodeKey]; if (!userInfo[FBSDKErrorDeveloperMessageKey]) { - [FBSDKTypeUtility dictionary:userInfo setObject:parameters[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey]; + [FBSDKTypeUtility dictionary:userInfo setObject:[FBSDKTypeUtility dictionary:parameters objectForKey:@"error_reason" ofType:NSString.class] forKey:FBSDKErrorDeveloperMessageKey]; } [FBSDKTypeUtility dictionary:userInfo setObject:@(FBSDKGraphRequestErrorOther) forKey:FBSDKGraphRequestErrorKey]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m index 1272c0e22b..c667b4f8cd 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -25,6 +25,7 @@ #else #import "FBSDKLoginCompletion+Internal.h" #endif +#import "FBSDKLoginKitTests-Swift.h" static NSString *const _fakeAppID = @"1234567"; static NSString *const _fakeChallence = @"some_challenge"; @@ -161,6 +162,14 @@ - (void)testInitWithError XCTAssertNotNil(completer.parameters.error); } +- (void)testInitWithFuzzyParameters +{ + for (int i = 0; i < 100; i++) { + NSDictionary *parameters = [Fuzzer randomizeWithJson:_parameters]; + FBSDKLoginURLCompleter *_completer __unused = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + } +} + // MARK: Helpers - (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParameter:(NSDictionary *)urlParameters diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift b/FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift new file mode 100644 index 0000000000..68ab0b6c3a --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift @@ -0,0 +1,132 @@ +// 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 Foundation + +@objc +public class Fuzzer: NSObject { + + private static let values: [Any] = [ + // Booleans + true, + false, + // Numbers + 1, + 0, + -1, + Int.max, + Double.greatestFiniteMagnitude, + Float.greatestFiniteMagnitude, + Double.leastNonzeroMagnitude, + Double.leastNormalMagnitude, + // Strings + "1", + "a", + " ", + "{}", + "[]", + "{", + "}", + "[ { \"something\": nonexistent } ]", + "\\{ \"foo\": \"bar\" \\}", + // Data + Data(), + "Foo".data(using: .utf8) ?? Data(), + Data(count: 100), + + //swiftlint:disable force_try + try! JSONSerialization.data(withJSONObject: ["foo": "bar"], options: .fragmentsAllowed), + //swiftlint:enable force_try + // Special Characters + "\\", + // Arrays + [], + [1, 2, 3], + [1, 2, 3, "a", "b", "c"], + (0 ... 100), + ("a" ..< "z"), + // Dictionaries + "[:]", + [:], + ["Foo": "Bar"], + ["": [1, 2, 3]], + ["Foo": true], + ["Foo": ["Bar": "Baz"]], + ["Foo": ["a", 1, [:]]] + ] + + @objc + public class var random: Any { + return values.randomElement() ?? values[0] + } + + /// Randomizes the values of a JSON object + /// Will not replace keys. Will either change their values or trim them entirely. + /// Will be called recursively on dictionaries and arrays + @objc + public class func randomize(json: Any) -> Any { + if var dictionary = json as? [String: Any] { + return randomizeInPlace(json: &dictionary) + } + else if var array = json as? [Any] { + return randomizeInPlace(array: &array) + } + else { + return json + } + } + + private class func randomizeInPlace(array: inout [Any]) -> [Any] { + var array = array + + array.enumerated().forEach { enumeration in + if var dictionary = enumeration.element as? [String: Any] { + array[enumeration.offset] = Bool.random() ? dictionary : randomizeInPlace(json: &dictionary) + } else if let subarray = enumeration.element as? [Any] { + array[enumeration.offset] = Bool.random() ? subarray : randomizeInPlace(array: &array) + } else { + array[enumeration.offset] = Bool.random() ? enumeration.element : random + } + } + + return array + } + + private class func randomizeInPlace(json: inout [String: Any]) -> [String: Any] { + json.keys.forEach { key in + if var value = json[key] as? [String: Any] { + json[key] = Bool.random() ? random : randomizeInPlace(json: &value) + } + // randomize array values if they are dictionaries + else if var values = json[key] as? [Any] { + json[key] = Bool.random() ? values : randomizeInPlace(array: &values) + } + else { + if Bool.random() { + json[key] = random + } + + else if Bool.random() { + json.removeValue(forKey: key) + } + } + } + + return json + } +} From c4d2b1f790b4e9d65fc07b4ca8f2966f1d40533c Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 18 Dec 2020 11:29:20 -0800 Subject: [PATCH 198/227] fix nil login configuration Summary: There are some login pathes that we were not setting login configuration, ex.`reauhtorizeDataAccess`. This diff will make sure that we have a non nil confuguration for all the login paths, including login functions that can be called internally. Reviewed By: joesus Differential Revision: D25601855 fbshipit-source-id: 0260f416189c62da84b73978596022a6eb4477ed --- .../FBSDKLoginKit/FBSDKLoginManager.h | 2 -- .../FBSDKLoginKit/FBSDKLoginManager.m | 16 +++++++++ .../Internal/FBSDKLoginManager+Internal.h | 4 --- .../FBSDKLoginManagerTests.m | 35 +++++++++++++++---- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index 1c0963ed5c..b76e98e56c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -204,8 +204,6 @@ You should provide as much context to the user as possible as to why you need to access being reathorized, and what added value your app provides when the access is reathorized. You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. This method will present UI the user. You typically should call this if `[FBSDKAccessToken isDataAccessExpired]` returns true. - - @warning This method will reauthorize using a `LoginConfiguration` with `FBSDKBetaLoginExperience` set to enabled. */ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FBSDKLoginManagerLoginResultBlock)handler diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 3238508dbf..dc9c112657 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -390,6 +390,15 @@ - (NSString *)loadExpectedNonce - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)configuration serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration { + // Making sure configuration is not nil in case this method gets called + // internally without specifying a cofiguration. + if (!configuration) { + NSString *failureMessage = @"Unable to perform login."; + NSError *error = [FBSDKError errorWithCode:FBSDKErrorUnknown message:failureMessage]; + [self invokeHandler:nil error:error]; + return nil; + } + [FBSDKInternalUtility validateURLSchemes]; NSMutableDictionary *loginParams = [NSMutableDictionary dictionary]; @@ -407,6 +416,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings isAutoLogAppEventsEnabled] ? @1 : @0 forKey:@"ies"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings appURLSchemeSuffix] forKey:@"local_client_id"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKLoginUtility stringForAudience:self.defaultAudience] forKey:@"default_audience"]; + NSSet *permissions = [configuration.requestedPermissions setByAddingObject:@"openid"]; [FBSDKTypeUtility dictionary:loginParams setObject:[permissions.allObjects componentsJoinedByString:@","] forKey:@"scope"]; @@ -495,6 +505,7 @@ - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler _handler = [handler copy]; // Don't need to pass permissions for data reauthorization. _requestedPermissions = [NSSet set]; + _configuration = [[FBSDKLoginConfiguration alloc] initWithTracking:FBSDKLoginTrackingEnabled]; self.authType = FBSDKLoginAuthTypeReauthorize; [_logger startSessionForLoginManager:self]; [self logIn]; @@ -582,6 +593,11 @@ - (void)setRequestedPermissions:(NSSet *)requestedPermissions _requestedPermissions = [requestedPermissions copy]; } +- (FBSDKLoginConfiguration *)configuration +{ + return _configuration; +} + // change bool to auth method string. - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams handler:(FBSDKBrowserLoginSuccessBlock)handler diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h index 96a8b2911a..eb6421fa2e 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h @@ -64,8 +64,6 @@ typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expectChallenge:(BOOL)expectChallenge; -// available to internal types to trigger login without checking read/publish mixtures. -- (void)logInWithPermissions:(NSSet *)permissions handler:(FBSDKLoginManagerLoginResultBlock)handler; - (void)logIn; // made available for testing only @@ -78,8 +76,6 @@ typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { - (void)setHandler:(FBSDKLoginManagerLoginResultBlock)handler; // for testing only - (void)setRequestedPermissions:(NSSet *)requestedPermissions; -// for testing only -- (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams handler:(FBSDKBrowserLoginSuccessBlock)handler; // available to internal modules - (void)handleImplicitCancelOfLogIn; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 4417275327..2eddf29400 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -49,6 +49,8 @@ - (NSString *)loadExpectedNonce; - (void)storeExpectedNonce:(NSString *)nonceExpected keychainStore:(FBSDKKeychainStore *)keychainStore; +- (FBSDKLoginConfiguration *)configuration; + @end @interface FBSDKAuthenticationTokenFactory (Testing) @@ -536,6 +538,22 @@ - (void)testLoginTrackingLimitedLoginParams XCTAssertEqualObjects(params[@"tp"], @"sentinel_test_value"); } +- (void)testLoginParamsWithNilConfiguration +{ + __block BOOL wasCalled = NO; + FBSDKLoginManagerLoginResultBlock handler = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTAssertNil(result); + XCTAssertNotNil(error); + wasCalled = YES; + }; + [_mockLoginManager setHandler:handler]; + + NSDictionary *params = [_mockLoginManager logInParametersWithConfiguration:nil serverConfiguration:nil]; + + XCTAssertNil(params); + XCTAssert(wasCalled); +} + - (void)testlogInParametersFromURL { NSURL *url = [NSURL URLWithString:@"myapp://somelink/?al_applink_data=%7B%22target_url%22%3Anull%2C%22extras%22%3A%7B%22fb_login%22%3A%22%7B%5C%22granted_scopes%5C%22%3A%5C%22public_profile%5C%22%2C%5C%22denied_scopes%5C%22%3A%5C%22%5C%22%2C%5C%22signed_request%5C%22%3A%5C%22ggarbage.eyJhbGdvcml0aG0iOiJITUFDSEEyNTYiLCJjb2RlIjoid2h5bm90IiwiaXNzdWVkX2F0IjoxNDIyNTAyMDkyLCJ1c2VyX2lkIjoiMTIzIn0%5C%22%2C%5C%22nonce%5C%22%3A%5C%22someNonce%5C%22%2C%5C%22data_access_expiration_time%5C%22%3A%5C%221607374566%5C%22%2C%5C%22expires_in%5C%22%3A%5C%225183401%5C%22%7D%22%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%22%2C%22app_name%22%3A%22Facebook%22%7D%7D"]; @@ -623,13 +641,18 @@ - (void)testReauthorizingWithoutAccessToken - (void)testReauthorizingWithAccessToken { [FBSDKAccessToken setCurrentAccessToken:self.sampleAccessToken shouldDispatchNotif:NO]; - OCMStub([_mockLoginManager logIn]); + FBSDKLoginManager *manager = _mockLoginManager; + OCMStub([manager logIn]); - [_mockLoginManager reauthorizeDataAccess:[UIViewController new] - handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { - XCTFail("Should not actually reauthorize and call the handler in this test"); - }]; - OCMVerify([_mockLoginManager logIn]); + [manager reauthorizeDataAccess:[UIViewController new] + handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { + XCTFail("Should not actually reauthorize and call the handler in this test"); + }]; + + XCTAssertEqual(manager.configuration.tracking, FBSDKLoginTrackingEnabled); + XCTAssertEqualObjects(manager.configuration.requestedPermissions, NSSet.new); + XCTAssertNotNil(manager.configuration.nonce); + OCMVerify([manager logIn]); } - (FBSDKAccessToken *)sampleAccessToken From 1ccdc90bf3918bb436edb3da31d5c96a8043727d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 18 Dec 2020 11:57:29 -0800 Subject: [PATCH 199/227] Update header import for CocoaPods Summary: Fixes bad header import for CocoaPods. Reviewed By: ppansy Differential Revision: D25642939 fbshipit-source-id: ea569b654629a530611c077cd26bfb5671a65c17 --- FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m index 829e492b2c..02b984b3fc 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKNonceUtility.m @@ -18,7 +18,11 @@ #import "FBSDKNonceUtility.h" -#import "FBSDKCoreKit+Internal.h" +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif @implementation FBSDKNonceUtility From 4a4e05105cc66bf3506613a1fe2e95f974d80285 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 18 Dec 2020 13:18:17 -0800 Subject: [PATCH 200/227] rename tp perference value Summary: title Reviewed By: robtimp Differential Revision: D25632660 fbshipit-source-id: 098de90840aaa8aa87794d1ad255860acce915ef --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 5 ++++- FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index dc9c112657..7ed0eb3b70 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -426,13 +426,16 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co [self storeExpectedChallenge:expectedChallenge]; NSString *responseType; + NSString *tp; if (configuration.tracking == FBSDKLoginTrackingLimited) { responseType = @"id_token"; - [FBSDKTypeUtility dictionary:loginParams setObject:@"sentinel_test_value" forKey:@"tp"]; + tp = @"ios_14_do_not_track"; } else { responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; + tp = @"ios_14_can_track"; } [FBSDKTypeUtility dictionary:loginParams setObject:responseType forKey:@"response_type"]; + [FBSDKTypeUtility dictionary:loginParams setObject:tp forKey:@"tp"]; [FBSDKTypeUtility dictionary:loginParams setObject:configuration.nonce forKey:@"nonce"]; [self storeExpectedNonce:configuration.nonce keychainStore:_keychainStore]; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m index 2eddf29400..d6cb36f3b7 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginManagerTests.m @@ -520,7 +520,7 @@ - (void)testLoginTrackingEnabledLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token,token_or_nonce,signed_request,graph_domain"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertNotNil(params[@"nonce"]); - XCTAssertNil(params[@"tp"]); + XCTAssertEqualObjects(params[@"tp"], @"ios_14_can_track"); } - (void)testLoginTrackingLimitedLoginParams @@ -535,7 +535,7 @@ - (void)testLoginTrackingLimitedLoginParams XCTAssertEqualObjects(params[@"response_type"], @"id_token"); XCTAssertEqualObjects(params[@"scope"], @"public_profile,email,openid"); XCTAssertEqualObjects(params[@"nonce"], @"some_nonce"); - XCTAssertEqualObjects(params[@"tp"], @"sentinel_test_value"); + XCTAssertEqualObjects(params[@"tp"], @"ios_14_do_not_track"); } - (void)testLoginParamsWithNilConfiguration From ef9cbe621cd52d41019d55580ad5acd214a3154c Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 18 Dec 2020 14:31:08 -0800 Subject: [PATCH 201/227] Remove deprecated device sharing methods Summary: $title Additionally removed ShareKit dependency from TVOSKit. Reviewed By: jingping2015 Differential Revision: D25642985 fbshipit-source-id: 5e207bf3d0fed08c4ff3171630b7ed1c63624f23 --- FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h | 6 - .../FBSDKShareKit.xcodeproj/project.pbxproj | 16 -- .../FBSDKShareKit/FBSDKDeviceShareButton.h | 44 ------ .../FBSDKShareKit/FBSDKDeviceShareButton.m | 87 ---------- .../FBSDKDeviceShareViewController.h | 104 ------------ .../FBSDKDeviceShareViewController.m | 149 ------------------ FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h | 3 - .../include/FBSDKDeviceShareButton.h | 1 - .../include/FBSDKDeviceShareViewController.h | 1 - .../FBSDKTVOSKit.xcodeproj/project.pbxproj | 145 ----------------- .../FBSDKTVOSKit/FBSDKTVInterfaceFactory.h | 1 - .../FBSDKTVOSKit/FBSDKTVInterfaceFactory.m | 45 ------ FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h | 1 - .../FBSDKTVOSKit/FBSDKTVShareButtonElement.h | 43 ----- .../FBSDKTVOSKit/FBSDKTVShareButtonElement.m | 23 --- 15 files changed, 669 deletions(-) delete mode 100644 FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h delete mode 100644 FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m delete mode 100644 FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h delete mode 100644 FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m delete mode 120000 FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareButton.h delete mode 120000 FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareViewController.h delete mode 100644 FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.h delete mode 100644 FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.m diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h index d9b4660329..b6ae406a7d 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h @@ -18,12 +18,6 @@ #import -#if TARGET_OS_TV - #ifndef DEVICE_SHARING_DEPRECATED - #define DEVICE_SHARING_DEPRECATED DEPRECATED_MSG_ATTRIBUTE("Sharing from devices will no longer work as of Nov 2nd 2020") - #endif -#endif - #ifdef BUCK #import diff --git a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj index 08c0203179..13f4a71adb 100644 --- a/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj +++ b/FBSDKShareKit/FBSDKShareKit.xcodeproj/project.pbxproj @@ -43,11 +43,9 @@ 8131FB4F1D261E5F000350FF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 893774A71A3B807300BE2807 /* UIKit.framework */; }; 8144D8EC1D261D2900C8E4AC /* FBSDKHashtag.m in Sources */ = {isa = PBXBuildFile; fileRef = D5158B5B1C5FD492003E32EE /* FBSDKHashtag.m */; }; 8144D8ED1D261D2900C8E4AC /* FBSDKShareLinkContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 89CE02E41A3F56470033C9CA /* FBSDKShareLinkContent.m */; }; - 8144D8EE1D261D2900C8E4AC /* FBSDKDeviceShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D10A64A1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m */; }; 8144D8EF1D261D2900C8E4AC /* FBSDKShareConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 893774881A3B5B9A00BE2807 /* FBSDKShareConstants.m */; }; 8144D8F11D261D2900C8E4AC /* FBSDKSharePhotoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FC9C6E1A3FA1E00001910E /* FBSDKSharePhotoContent.m */; }; 8144D8F31D261D2900C8E4AC /* FBSDKShareVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 896DE2111A9E280900195731 /* FBSDKShareVideo.m */; }; - 8144D8F41D261D2900C8E4AC /* FBSDKDeviceShareButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D9E16B31CB46E8F00C8B68F /* FBSDKDeviceShareButton.m */; }; 8144D8F61D261D2900C8E4AC /* FBSDKShareVideoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 896DE2191A9E282800195731 /* FBSDKShareVideoContent.m */; }; 8144D8F91D261D2900C8E4AC /* FBSDKShareMediaContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A419D91C922A2A006E7767 /* FBSDKShareMediaContent.m */; }; 8144D8FC1D261D2900C8E4AC /* FBSDKSharePhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = 892EBBF51A3A50D700721B03 /* FBSDKSharePhoto.m */; }; @@ -57,12 +55,10 @@ 8144D9051D261D2900C8E4AC /* FBSDKShareUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 891C54561A3BB23F00DF05AF /* FBSDKShareUtility.h */; }; 8144D9071D261D2900C8E4AC /* FBSDKShareConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 893774871A3B5B9A00BE2807 /* FBSDKShareConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9081D261D2900C8E4AC /* FBSDKShareDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 8904148A1A648DAC00617215 /* FBSDKShareDefines.h */; }; - 8144D9091D261D2900C8E4AC /* FBSDKDeviceShareButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9E16B21CB46E8F00C8B68F /* FBSDKDeviceShareButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D90B1D261D2900C8E4AC /* FBSDKSharingContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 8973B37B1A40A93D0001EDC5 /* FBSDKSharingContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D90C1D261D2900C8E4AC /* FBSDKSharing.h in Headers */ = {isa = PBXBuildFile; fileRef = 8904147F1A64849100617215 /* FBSDKSharing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D90D1D261D2900C8E4AC /* FBSDKShareKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D46C5F51A11E5D800A0DDB6 /* FBSDKShareKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9101D261D2900C8E4AC /* FBSDKShareVideoContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 896DE2181A9E282800195731 /* FBSDKShareVideoContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8144D9111D261D2900C8E4AC /* FBSDKDeviceShareViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D10A6491CB3806700F42AC1 /* FBSDKDeviceShareViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9131D261D2900C8E4AC /* FBSDKShareVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = 896DE2101A9E280900195731 /* FBSDKShareVideo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9141D261D2900C8E4AC /* FBSDKShareLinkContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 89CE02E31A3F56470033C9CA /* FBSDKShareLinkContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8144D9161D261D2900C8E4AC /* FBSDKHashtag.h in Headers */ = {isa = PBXBuildFile; fileRef = D5158B5A1C5FD492003E32EE /* FBSDKHashtag.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -187,8 +183,6 @@ 89FC9C701A3FA1E00001910E /* FBSDKSharePhotoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FC9C6E1A3FA1E00001910E /* FBSDKSharePhotoContent.m */; }; 89FC9C761A3FAB4B0001910E /* FBSDKSharePhotoContentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FC9C751A3FAB4B0001910E /* FBSDKSharePhotoContentTests.m */; }; 939000641EB80C1A00250D4C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 939000631EB80C1A00250D4C /* CoreGraphics.framework */; }; - 9D10A64B1CB3806700F42AC1 /* FBSDKDeviceShareViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D10A6491CB3806700F42AC1 /* FBSDKDeviceShareViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D10A64C1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D10A64A1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m */; }; 9D2D999F1BC4538300929E76 /* FBSDKShareKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D46C5F51A11E5D800A0DDB6 /* FBSDKShareKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D2D99A71BC453DB00929E76 /* FBSDKSharePhoto.h in Headers */ = {isa = PBXBuildFile; fileRef = 892EBBF41A3A50D700721B03 /* FBSDKSharePhoto.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D2D99A81BC453E100929E76 /* FBSDKSharePhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = 892EBBF51A3A50D700721B03 /* FBSDKSharePhoto.m */; }; @@ -211,8 +205,6 @@ 9D2DE4271CA34ADC0072CF7E /* FBSDKHashtag.h in Headers */ = {isa = PBXBuildFile; fileRef = D5158B5A1C5FD492003E32EE /* FBSDKHashtag.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; - 9D9E16B41CB46E8F00C8B68F /* FBSDKDeviceShareButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9E16B21CB46E8F00C8B68F /* FBSDKDeviceShareButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D9E16B51CB46E8F00C8B68F /* FBSDKDeviceShareButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D9E16B31CB46E8F00C8B68F /* FBSDKDeviceShareButton.m */; }; 9DE155621C161B5F005FCF5C /* FBSDKShareDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 8904148A1A648DAC00617215 /* FBSDKShareDefines.h */; }; 9DEE5C901A671B2100D750E1 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DEE5C8F1A671B2100D750E1 /* XCTest.framework */; }; A41549F71E6653AE001F7152 /* FBSDKCameraEffectTextures+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A41549F61E6653AE001F7152 /* FBSDKCameraEffectTextures+Internal.h */; }; @@ -924,7 +916,6 @@ F462DBFC23B9526300FFCECA /* FBSDKCoreKit+Internal.h in Headers */, 8144D9071D261D2900C8E4AC /* FBSDKShareConstants.h in Headers */, 8144D9081D261D2900C8E4AC /* FBSDKShareDefines.h in Headers */, - 8144D9091D261D2900C8E4AC /* FBSDKDeviceShareButton.h in Headers */, B3D17FF4212CD046000D28D6 /* FBSDKSharingValidation.h in Headers */, 8144D90B1D261D2900C8E4AC /* FBSDKSharingContent.h in Headers */, F4ECC66C23EE2065005DBF05 /* FBSDKCoreKitImport.h in Headers */, @@ -932,7 +923,6 @@ 883644BD1F969CA800124BCB /* FBSDKShareMediaContent.h in Headers */, 8144D90D1D261D2900C8E4AC /* FBSDKShareKit.h in Headers */, 8144D9101D261D2900C8E4AC /* FBSDKShareVideoContent.h in Headers */, - 8144D9111D261D2900C8E4AC /* FBSDKDeviceShareViewController.h in Headers */, 8144D9131D261D2900C8E4AC /* FBSDKShareVideo.h in Headers */, 8144D9141D261D2900C8E4AC /* FBSDKShareLinkContent.h in Headers */, 8144D9161D261D2900C8E4AC /* FBSDKHashtag.h in Headers */, @@ -1001,7 +991,6 @@ F462DBF223B9526200FFCECA /* FBSDKCoreKit+Internal.h in Headers */, 9D2D99AB1BC453F700929E76 /* FBSDKShareConstants.h in Headers */, 9DE155621C161B5F005FCF5C /* FBSDKShareDefines.h in Headers */, - 9D9E16B41CB46E8F00C8B68F /* FBSDKDeviceShareButton.h in Headers */, B3D17FF3212CD046000D28D6 /* FBSDKSharingValidation.h in Headers */, 9D2D99B41BC4543300929E76 /* FBSDKSharingContent.h in Headers */, F4ECC66B23EE2065005DBF05 /* FBSDKCoreKitImport.h in Headers */, @@ -1009,7 +998,6 @@ 883644BC1F969CA700124BCB /* FBSDKShareMediaContent.h in Headers */, 9D2D999F1BC4538300929E76 /* FBSDKShareKit.h in Headers */, 9D2D99B91BC4545D00929E76 /* FBSDKShareVideoContent.h in Headers */, - 9D10A64B1CB3806700F42AC1 /* FBSDKDeviceShareViewController.h in Headers */, 9D2D99B71BC4545200929E76 /* FBSDKShareVideo.h in Headers */, 9D2D99B01BC4541200929E76 /* FBSDKShareLinkContent.h in Headers */, 9D2DE4271CA34ADC0072CF7E /* FBSDKHashtag.h in Headers */, @@ -1387,11 +1375,9 @@ files = ( 8144D8EC1D261D2900C8E4AC /* FBSDKHashtag.m in Sources */, 8144D8ED1D261D2900C8E4AC /* FBSDKShareLinkContent.m in Sources */, - 8144D8EE1D261D2900C8E4AC /* FBSDKDeviceShareViewController.m in Sources */, 8144D8EF1D261D2900C8E4AC /* FBSDKShareConstants.m in Sources */, 8144D8F11D261D2900C8E4AC /* FBSDKSharePhotoContent.m in Sources */, 8144D8F31D261D2900C8E4AC /* FBSDKShareVideo.m in Sources */, - 8144D8F41D261D2900C8E4AC /* FBSDKDeviceShareButton.m in Sources */, 8144D8F61D261D2900C8E4AC /* FBSDKShareVideoContent.m in Sources */, 8144D8F91D261D2900C8E4AC /* FBSDKShareMediaContent.m in Sources */, 8144D8FC1D261D2900C8E4AC /* FBSDKSharePhoto.m in Sources */, @@ -1444,11 +1430,9 @@ files = ( 9D2DE4251CA348AA0072CF7E /* FBSDKHashtag.m in Sources */, 9D2D99B11BC4541A00929E76 /* FBSDKShareLinkContent.m in Sources */, - 9D10A64C1CB3806700F42AC1 /* FBSDKDeviceShareViewController.m in Sources */, 9D2D99AC1BC453FC00929E76 /* FBSDKShareConstants.m in Sources */, 9D2D99B61BC4544C00929E76 /* FBSDKSharePhotoContent.m in Sources */, 9D2D99B81BC4545600929E76 /* FBSDKShareVideo.m in Sources */, - 9D9E16B51CB46E8F00C8B68F /* FBSDKDeviceShareButton.m in Sources */, 9D2D99BA1BC4546100929E76 /* FBSDKShareVideoContent.m in Sources */, 9D2DE4261CA34ABA0072CF7E /* FBSDKShareMediaContent.m in Sources */, 9D2D99A81BC453E100929E76 /* FBSDKSharePhoto.m in Sources */, diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h deleted file mode 100644 index 9c69793dd5..0000000000 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.h +++ /dev/null @@ -1,44 +0,0 @@ -// 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 "TargetConditionals.h" - -#if TARGET_OS_TV - -#import "FBSDKCoreKitImport.h" - -#import "FBSDKSharingContent.h" - -NS_ASSUME_NONNULL_BEGIN - -DEVICE_SHARING_DEPRECATED -NS_SWIFT_NAME(FBDeviceShareButton) -@interface FBSDKDeviceShareButton : FBSDKDeviceButton - -/** - The required content to share. The button is disabled until this is set. - - @see FBSDKDeviceShareViewController - */ -@property (nullable, nonatomic, strong) id shareContent; - -@end - -NS_ASSUME_NONNULL_END - -#endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m deleted file mode 100644 index 369eda4f6e..0000000000 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareButton.m +++ /dev/null @@ -1,87 +0,0 @@ -// 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 "TargetConditionals.h" - -#if TARGET_OS_TV - - #import "FBSDKDeviceShareButton.h" - - #import "FBSDKDeviceShareViewController.h" - - #if defined BUCK || defined FBSDKCOCOAPODS || defined __cplusplus - #import - #else - #import "FBSDKCoreKit+Internal.h" - #endif - - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-implementations" -@implementation FBSDKDeviceShareButton - #pragma clang diagnostic pop - -- (void)configureButton -{ - [self configureWithIcon:nil - title:nil - backgroundColor:nil - highlightedColor:nil]; - - NSString *title = - NSLocalizedStringWithDefaultValue( - @"ShareButton.Share", - @"FacebookSDK", - [FBSDKInternalUtility bundleForStrings], - @"Share", - @"The label for FBSDKShareButton" - ); - NSAttributedString *attributedTitle = [self attributedTitleStringFromString:title]; - [self setAttributedTitle:attributedTitle forState:UIControlStateNormal]; - [self setAttributedTitle:attributedTitle forState:UIControlStateFocused]; - [self setAttributedTitle:attributedTitle forState:UIControlStateSelected]; - [self setAttributedTitle:attributedTitle forState:UIControlStateSelected | UIControlStateHighlighted]; - [self setAttributedTitle:attributedTitle forState:UIControlStateSelected | UIControlStateFocused]; - - self.enabled = NO; - [self addTarget:self action:@selector(_buttonPressed:) forControlEvents:UIControlEventPrimaryActionTriggered]; -} - - #pragma mark - Properties - -- (void)setShareContent:(id)shareContent -{ - if (_shareContent != shareContent) { - _shareContent = shareContent; - self.enabled = (shareContent != nil); - } -} - - #pragma mark - Implementation - -- (void)_buttonPressed:(id)sender -{ - UIViewController *parentViewController = [FBSDKInternalUtility viewControllerForView:self]; - if (_shareContent) { - FBSDKDeviceShareViewController *vc = [[FBSDKDeviceShareViewController alloc] initWithShareContent:_shareContent]; - [parentViewController presentViewController:vc animated:YES completion:NULL]; - } -} - -@end - -#endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h deleted file mode 100644 index 0bc5b89f40..0000000000 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.h +++ /dev/null @@ -1,104 +0,0 @@ -// 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 "TargetConditionals.h" - -#if TARGET_OS_TV - -#import - -#import "FBSDKCoreKitImport.h" - -#import "FBSDKSharingContent.h" - -NS_ASSUME_NONNULL_BEGIN - -@class FBSDKDeviceShareViewController; - -/** - A delegate for `FBSDKDeviceShareViewController` - */ -DEVICE_SHARING_DEPRECATED -NS_SWIFT_NAME(DeviceShareViewControllerDelegate) -@protocol FBSDKDeviceShareViewControllerDelegate - -/** - Indicates the dialog was completed - - This can happen if the user tapped cancel, or menu on their Siri remote, or if the - device code has expired. You will not be informed if the user actually posted a share to Facebook. - */ -- (void)deviceShareViewControllerDidComplete:(FBSDKDeviceShareViewController *)viewController - error:(nullable NSError *)error; - -@end - -/** - Use this view controller to initiate Sharing for Devices, an easy way for people to share content - from your tvOS app without requiring Facebook Login. - - The `FBSDKDeviceShareViewController` can dismiss itself and notify its delegate - of completion. You should not re-use a `FBSDKDeviceShareViewController` instance again. - - See [Sharing for Devices](https://developers.facebook.com/docs/sharing/for-devices). - - @code - // from your view controller: - FBSDKDeviceShareViewController *vc = [[FBSDKDeviceShareViewController alloc] initWithShareContent:...]; - vc.delegate = self; - [self presentViewController:vc - animated:YES - completion:NULL]; - */ -DEVICE_SHARING_DEPRECATED -NS_SWIFT_NAME(FBDeviceShareViewController) -@interface FBSDKDeviceShareViewController : FBSDKDeviceViewControllerBase - -/** - Initializes a new instance with share content. - @param shareContent The share content. Only `FBSDKShareLinkContent` is supported. - - Invalid content types will result in notifying the delegate with an error when the view controller is presented. - - For `FBSDKShareLinkContent`, only contentURL is used (e.g., properties are not supported) - */ -- (instancetype)initWithShareContent:(id)shareContent -NS_SWIFT_NAME(init(content:)) -NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)new NS_UNAVAILABLE; -- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; -- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil - bundle:(nullable NSBundle *)nibBundleOrNil NS_UNAVAILABLE; - -/** - The delegate. - */ -@property (nullable, nonatomic, weak) id delegate; - -/** - The share content. - */ -@property (nonatomic, readonly, strong) id shareContent; - -@end - -NS_ASSUME_NONNULL_END - -#endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m b/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m deleted file mode 100644 index 21f05707db..0000000000 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKDeviceShareViewController.m +++ /dev/null @@ -1,149 +0,0 @@ -// 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 "TargetConditionals.h" - -#if TARGET_OS_TV - - #import "FBSDKDeviceShareViewController.h" - - #ifdef FBSDKCOCOAPODS - #import - #else - #import "FBSDKCoreKit+Internal.h" - #endif - #import "FBSDKShareLinkContent.h" - #import "FBSDKShareUtility.h" - - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-implementations" -@implementation FBSDKDeviceShareViewController - #pragma clang diagnostic pop - -- (instancetype)initWithShareContent:(id)shareContent -{ - if ((self = [super initWithNibName:nil bundle:nil])) { - _shareContent = shareContent; - } - return self; -} - -- (void)loadView -{ - CGRect frame = [UIScreen mainScreen].bounds; - FBSDKDeviceDialogView *deviceView = [[FBSDKDeviceDialogView alloc] initWithFrame:frame]; - deviceView.delegate = self; - self.view = deviceView; -} - -- (void)viewDidDisappear:(BOOL)animated -{ - [super viewDidDisappear:animated]; - [self.delegate deviceShareViewControllerDidComplete:self error:nil]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - [FBSDKInternalUtility validateRequiredClientAccessToken]; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - - NSError *error; - NSDictionary *params = [self _graphRequestParametersForContent:_shareContent error:&error]; - if (!params) { - [self _dismissWithError:error]; - return; - } - NSMutableDictionary *mutableParameters = [params mutableCopy]; - [mutableParameters setValue:[FBSDKDeviceRequestsHelper getDeviceInfo] forKey:FBSDK_DEVICE_INFO_PARAM]; - FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] - initWithGraphPath:@"device/share" - parameters:[mutableParameters copy] - tokenString:[FBSDKInternalUtility validateRequiredClientAccessToken] - HTTPMethod:@"POST" - flags:FBSDKGraphRequestFlagNone]; - [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *requestError) { - if (requestError) { - [self _dismissWithError:error]; - return; - } - NSString *code = result[@"user_code"]; - NSUInteger expires = [result[@"expires_in"] unsignedIntegerValue]; - if (!code || !expires) { - [self _dismissWithError:[FBSDKError unknownErrorWithMessage:@"Malformed response from server"]]; - return; - } - self.deviceDialogView.confirmationCode = code; - __weak typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(expires * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - [weakSelf _dismissWithError:nil]; - }); - }]; -} - - #pragma mark - Private impl - -- (void)_dismissWithError:(NSError *)error -{ - id delegate = self.delegate; - // clear delegate to avoid double messaging after viewDidDisappear - self.delegate = nil; - [self dismissViewControllerAnimated:YES - completion:^{ - [delegate deviceShareViewControllerDidComplete:self - error:error]; - }]; -} - -- (NSDictionary *)_graphRequestParametersForContent:(id)shareContent error:(NSError **)error -{ - if (error != NULL) { - *error = nil; - } - if (!_shareContent) { - if (error != NULL) { - *error = [FBSDKError requiredArgumentErrorWithName:@"shareContent" message:nil]; - } - return nil; - } - if ([_shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { - NSString *unused; - NSDictionary *params; - [FBSDKShareUtility buildWebShareContent:_shareContent - methodName:&unused - parameters:¶ms - error:error]; - return params; - } - if (error != NULL) { - *error = [FBSDKError - invalidArgumentErrorWithName:@"shareContent" - value:shareContent - message:[NSString stringWithFormat:@"%@ is not a supported content type", [shareContent class]]]; - } - return nil; -} - -@end - -#endif diff --git a/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h b/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h index f304c6e627..cca91f95e5 100644 --- a/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h +++ b/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h @@ -41,7 +41,4 @@ #import "FBSDKShareCameraEffectContent.h" #import "FBSDKShareDialog.h" #import "FBSDKShareDialogMode.h" -#else - #import "FBSDKDeviceShareButton.h" - #import "FBSDKDeviceShareViewController.h" #endif diff --git a/FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareButton.h b/FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareButton.h deleted file mode 120000 index 7d3f136e32..0000000000 --- a/FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareButton.h +++ /dev/null @@ -1 +0,0 @@ -../FBSDKDeviceShareButton.h \ No newline at end of file diff --git a/FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareViewController.h b/FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareViewController.h deleted file mode 120000 index b92b5af1cb..0000000000 --- a/FBSDKShareKit/FBSDKShareKit/include/FBSDKDeviceShareViewController.h +++ /dev/null @@ -1 +0,0 @@ -../FBSDKDeviceShareViewController.h \ No newline at end of file diff --git a/FBSDKTVOSKit/FBSDKTVOSKit.xcodeproj/project.pbxproj b/FBSDKTVOSKit/FBSDKTVOSKit.xcodeproj/project.pbxproj index 0b974ae1ae..677934d9d5 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit.xcodeproj/project.pbxproj +++ b/FBSDKTVOSKit/FBSDKTVOSKit.xcodeproj/project.pbxproj @@ -30,7 +30,6 @@ 8117C27E1D30303D00784D79 /* FBSDKTVOSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D8E94771BC332900012023B /* FBSDKTVOSConstants.m */; }; 8117C2801D30303D00784D79 /* FBSDKTVLoginButtonElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D81FDA21C50433D00AF5F8D /* FBSDKTVLoginButtonElement.m */; }; 8117C2811D30303D00784D79 /* FBSDKJS.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D82CF1C1C56EB5300CB7AD7 /* FBSDKJS.m */; }; - 8117C2821D30303D00784D79 /* FBSDKTVShareButtonElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D084B141CB57FF000A51DA0 /* FBSDKTVShareButtonElement.m */; }; 8117C2851D30303D00784D79 /* FBSDKTVLoginButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D81FDA11C50433D00AF5F8D /* FBSDKTVLoginButtonElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8117C2861D30303D00784D79 /* FBSDKCoreKit+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D8E94741BC32F920012023B /* FBSDKCoreKit+Internal.h */; }; 8117C2871D30303D00784D79 /* FBSDKTVOSKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DEC55861BBA636A00C7DB4A /* FBSDKTVOSKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -40,17 +39,12 @@ 8117C2901D30303D00784D79 /* FBSDKTVInterfaceFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D81FD9D1C50407000AF5F8D /* FBSDKTVInterfaceFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8117C2911D30303D00784D79 /* FBSDKTVOSConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D8E94761BC332900012023B /* FBSDKTVOSConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8117C2921D30303D00784D79 /* FBSDKTVLoginViewControllerElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D82CF171C56C3EE00CB7AD7 /* FBSDKTVLoginViewControllerElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8117C2931D30303D00784D79 /* FBSDKTVShareButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D084B131CB57FF000A51DA0 /* FBSDKTVShareButtonElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8117C2BC1D30308700784D79 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B6151D0A45F000962084 /* FBSDKCoreKit.framework */; }; - 8117C2BD1D30308700784D79 /* FBSDKShareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B62D1D0A462B00962084 /* FBSDKShareKit.framework */; }; 8117C2C21D30309600784D79 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8117C2C11D30309600784D79 /* UIKit.framework */; }; 8117C2C51D30309C00784D79 /* TVMLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8117C2C41D30309C00784D79 /* TVMLKit.framework */; }; 8117C2C81D3030A000784D79 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8117C2C71D3030A000784D79 /* CoreGraphics.framework */; }; 8118B6941D0A5F9800962084 /* FBSDKTVOSKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DEC55831BBA636A00C7DB4A /* FBSDKTVOSKit.framework */; }; 8118B6951D0A5F9800962084 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B6151D0A45F000962084 /* FBSDKCoreKit.framework */; }; - 8118B6961D0A5F9800962084 /* FBSDKShareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8118B62D1D0A462B00962084 /* FBSDKShareKit.framework */; }; - 9D084B151CB57FF000A51DA0 /* FBSDKTVShareButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D084B131CB57FF000A51DA0 /* FBSDKTVShareButtonElement.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D084B161CB57FF000A51DA0 /* FBSDKTVShareButtonElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D084B141CB57FF000A51DA0 /* FBSDKTVShareButtonElement.m */; }; 9D6538261BF40AB3008A08E9 /* FBSDKDeviceLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D6538241BF40AB3008A08E9 /* FBSDKDeviceLoginButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D6538271BF40AB3008A08E9 /* FBSDKDeviceLoginButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D6538251BF40AB3008A08E9 /* FBSDKDeviceLoginButton.m */; }; 9D81FD9F1C50407000AF5F8D /* FBSDKTVInterfaceFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D81FD9D1C50407000AF5F8D /* FBSDKTVInterfaceFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -155,13 +149,6 @@ remoteGlobalIDString = 814AC7E11D1B528900D61E6C; remoteInfo = "FBSDKCoreKit_TV-Dynamic"; }; - 8117C2BA1D30307C00784D79 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D084B1A1CB5887000A51DA0 /* FBSDKShareKit.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 8144D8E81D261D2900C8E4AC; - remoteInfo = "FBSDKShareKit_TV-Dynamic"; - }; 8118B6101D0A45F000962084 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8118B6081D0A45F000962084 /* FBSDKCoreKit.xcodeproj */; @@ -211,13 +198,6 @@ remoteGlobalIDString = 9D2D99941BC452DE00929E76; remoteInfo = FBSDKShareKit_TV; }; - 8118B62F1D0A463000962084 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D084B1A1CB5887000A51DA0 /* FBSDKShareKit.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 9D2D99931BC452DE00929E76; - remoteInfo = FBSDKShareKit_TV; - }; 8118B6971D0A5FA300962084 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8118B6081D0A45F000962084 /* FBSDKCoreKit.xcodeproj */; @@ -225,13 +205,6 @@ remoteGlobalIDString = 9DB0FA721BC1CA71005EB8B1; remoteInfo = FBSDKCoreKit_TV; }; - 8118B6991D0A5FA300962084 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D084B1A1CB5887000A51DA0 /* FBSDKShareKit.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 9D2D99931BC452DE00929E76; - remoteInfo = FBSDKShareKit_TV; - }; 9DEC558F1BBA636A00C7DB4A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 9DEC557A1BBA636A00C7DB4A /* Project object */; @@ -274,48 +247,6 @@ remoteGlobalIDString = C5C4B4EA2276BA8D00CA3706; remoteInfo = "FBSDKCoreKit_Basics_TV-Dynamic"; }; - F46A2C8224464D30000EFBAC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8118B6081D0A45F000962084 /* FBSDKCoreKit.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F487DBB9231EBCD2008416A9; - remoteInfo = FBSDKCoreKitSwift; - }; - F46A2C8424464D30000EFBAC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8118B6081D0A45F000962084 /* FBSDKCoreKit.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F483F414233AC13000703DE3; - remoteInfo = "FBSDKCoreKitSwift-Dynamic"; - }; - F46A2C8D24464D30000EFBAC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0B9DBF54207C080600662776 /* FBSDKLoginKit.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F487DC03231EC34B008416A9; - remoteInfo = FBSDKLoginKitSwift; - }; - F46A2C8F24464D30000EFBAC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0B9DBF54207C080600662776 /* FBSDKLoginKit.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F483F44D233AC85F00703DE3; - remoteInfo = "FBSDKLoginKitSwift-Dynamic"; - }; - F46A2C9824464D30000EFBAC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D084B1A1CB5887000A51DA0 /* FBSDKShareKit.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F487DC86231EC4CC008416A9; - remoteInfo = FBSDKShareKitSwift; - }; - F46A2C9A24464D30000EFBAC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 9D084B1A1CB5887000A51DA0 /* FBSDKShareKit.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = F483F4CA233AC91700703DE3; - remoteInfo = "FBSDKShareKitSwift-Dynamic"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -350,8 +281,6 @@ 8117C2C41D30309C00784D79 /* TVMLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TVMLKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/System/Library/Frameworks/TVMLKit.framework; sourceTree = DEVELOPER_DIR; }; 8117C2C71D3030A000784D79 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; 8118B6081D0A45F000962084 /* FBSDKCoreKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FBSDKCoreKit.xcodeproj; path = ../../FBSDKCoreKit/FBSDKCoreKit.xcodeproj; sourceTree = ""; }; - 9D084B131CB57FF000A51DA0 /* FBSDKTVShareButtonElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKTVShareButtonElement.h; sourceTree = ""; }; - 9D084B141CB57FF000A51DA0 /* FBSDKTVShareButtonElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTVShareButtonElement.m; sourceTree = ""; }; 9D084B1A1CB5887000A51DA0 /* FBSDKShareKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FBSDKShareKit.xcodeproj; path = ../../FBSDKShareKit/FBSDKShareKit.xcodeproj; sourceTree = ""; }; 9D6538241BF40AB3008A08E9 /* FBSDKDeviceLoginButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKDeviceLoginButton.h; sourceTree = ""; }; 9D6538251BF40AB3008A08E9 /* FBSDKDeviceLoginButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKDeviceLoginButton.m; sourceTree = ""; }; @@ -397,7 +326,6 @@ 8117C2C51D30309C00784D79 /* TVMLKit.framework in Frameworks */, 8117C2C21D30309600784D79 /* UIKit.framework in Frameworks */, 8117C2BC1D30308700784D79 /* FBSDKCoreKit.framework in Frameworks */, - 8117C2BD1D30308700784D79 /* FBSDKShareKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -414,7 +342,6 @@ files = ( 8118B6941D0A5F9800962084 /* FBSDKTVOSKit.framework in Frameworks */, 8118B6951D0A5F9800962084 /* FBSDKCoreKit.framework in Frameworks */, - 8118B6961D0A5F9800962084 /* FBSDKShareKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -429,8 +356,6 @@ 0B9DBF62207C080600662776 /* FBSDKLoginKitTests.xctest */, 0B9DBF64207C080600662776 /* FBSDKLoginKit.framework */, 0B9DBF66207C080600662776 /* FBSDKLoginKit.framework */, - F46A2C8E24464D30000EFBAC /* FBSDKLoginKit.framework */, - F46A2C9024464D30000EFBAC /* FBSDKLoginKit.framework */, ); name = Products; sourceTree = ""; @@ -519,8 +444,6 @@ C57538DA2292B7DD007C2EFF /* FBSDKCoreKit.framework */, C57538DC2292B7DD007C2EFF /* FBSDKCoreKit.framework */, C57538DE2292B7DD007C2EFF /* FBSDKCoreKit.framework */, - F46A2C8324464D30000EFBAC /* FBSDKCoreKit.framework */, - F46A2C8524464D30000EFBAC /* FBSDKCoreKit.framework */, ); name = Products; sourceTree = ""; @@ -533,8 +456,6 @@ 8118B62B1D0A462B00962084 /* FBSDKShareKitTests.xctest */, 8118B62D1D0A462B00962084 /* FBSDKShareKit.framework */, 8117C2461D302F6900784D79 /* FBSDKShareKit.framework */, - F46A2C9924464D30000EFBAC /* FBSDKShareKit.framework */, - F46A2C9B24464D30000EFBAC /* FBSDKShareKit.framework */, ); name = Products; sourceTree = ""; @@ -581,8 +502,6 @@ 9D8E94761BC332900012023B /* FBSDKTVOSConstants.h */, 9D8E94771BC332900012023B /* FBSDKTVOSConstants.m */, 9DEC55861BBA636A00C7DB4A /* FBSDKTVOSKit.h */, - 9D084B131CB57FF000A51DA0 /* FBSDKTVShareButtonElement.h */, - 9D084B141CB57FF000A51DA0 /* FBSDKTVShareButtonElement.m */, 526CE1CD21768C9100F69C7C /* Internal */, 9DEC55BD1BBA684500C7DB4A /* Supporting Files */, ); @@ -655,7 +574,6 @@ 8117C2901D30303D00784D79 /* FBSDKTVInterfaceFactory.h in Headers */, 8117C2911D30303D00784D79 /* FBSDKTVOSConstants.h in Headers */, 8117C2921D30303D00784D79 /* FBSDKTVLoginViewControllerElement.h in Headers */, - 8117C2931D30303D00784D79 /* FBSDKTVShareButtonElement.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -672,7 +590,6 @@ 9D81FD9F1C50407000AF5F8D /* FBSDKTVInterfaceFactory.h in Headers */, 9D8E94781BC332900012023B /* FBSDKTVOSConstants.h in Headers */, 9D82CF191C56C3EE00CB7AD7 /* FBSDKTVLoginViewControllerElement.h in Headers */, - 9D084B151CB57FF000A51DA0 /* FBSDKTVShareButtonElement.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -693,7 +610,6 @@ dependencies = ( 0B3229382093848300F011F9 /* PBXTargetDependency */, 8117C2B91D30307C00784D79 /* PBXTargetDependency */, - 8117C2BB1D30307C00784D79 /* PBXTargetDependency */, ); name = "FBSDKTVOSKit_TV-Dynamic"; productName = FBSDKTVOSKit; @@ -713,7 +629,6 @@ ); dependencies = ( 0B9DBF68207C080E00662776 /* PBXTargetDependency */, - 8118B6301D0A463000962084 /* PBXTargetDependency */, 8118B6171D0A45F600962084 /* PBXTargetDependency */, ); name = FBSDKTVOSKit_TV; @@ -733,7 +648,6 @@ ); dependencies = ( 8118B6981D0A5FA300962084 /* PBXTargetDependency */, - 8118B69A1D0A5FA300962084 /* PBXTargetDependency */, 9DEC55901BBA636A00C7DB4A /* PBXTargetDependency */, ); name = FBSDKTVOSKitTests; @@ -930,48 +844,6 @@ remoteRef = C57538DD2292B7DD007C2EFF /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F46A2C8324464D30000EFBAC /* FBSDKCoreKit.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = FBSDKCoreKit.framework; - remoteRef = F46A2C8224464D30000EFBAC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F46A2C8524464D30000EFBAC /* FBSDKCoreKit.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = FBSDKCoreKit.framework; - remoteRef = F46A2C8424464D30000EFBAC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F46A2C8E24464D30000EFBAC /* FBSDKLoginKit.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = FBSDKLoginKit.framework; - remoteRef = F46A2C8D24464D30000EFBAC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F46A2C9024464D30000EFBAC /* FBSDKLoginKit.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = FBSDKLoginKit.framework; - remoteRef = F46A2C8F24464D30000EFBAC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F46A2C9924464D30000EFBAC /* FBSDKShareKit.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = FBSDKShareKit.framework; - remoteRef = F46A2C9824464D30000EFBAC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - F46A2C9B24464D30000EFBAC /* FBSDKShareKit.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = FBSDKShareKit.framework; - remoteRef = F46A2C9A24464D30000EFBAC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -1026,7 +898,6 @@ 8117C27E1D30303D00784D79 /* FBSDKTVOSConstants.m in Sources */, 8117C2801D30303D00784D79 /* FBSDKTVLoginButtonElement.m in Sources */, 8117C2811D30303D00784D79 /* FBSDKJS.m in Sources */, - 8117C2821D30303D00784D79 /* FBSDKTVShareButtonElement.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1041,7 +912,6 @@ 9D8E94791BC332900012023B /* FBSDKTVOSConstants.m in Sources */, 9D81FDA41C50433D00AF5F8D /* FBSDKTVLoginButtonElement.m in Sources */, 9D82CF1E1C56EB5300CB7AD7 /* FBSDKJS.m in Sources */, - 9D084B161CB57FF000A51DA0 /* FBSDKTVShareButtonElement.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1071,31 +941,16 @@ name = "FBSDKCoreKit_TV-Dynamic"; targetProxy = 8117C2B81D30307C00784D79 /* PBXContainerItemProxy */; }; - 8117C2BB1D30307C00784D79 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "FBSDKShareKit_TV-Dynamic"; - targetProxy = 8117C2BA1D30307C00784D79 /* PBXContainerItemProxy */; - }; 8118B6171D0A45F600962084 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKCoreKit_TV; targetProxy = 8118B6161D0A45F600962084 /* PBXContainerItemProxy */; }; - 8118B6301D0A463000962084 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FBSDKShareKit_TV; - targetProxy = 8118B62F1D0A463000962084 /* PBXContainerItemProxy */; - }; 8118B6981D0A5FA300962084 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKCoreKit_TV; targetProxy = 8118B6971D0A5FA300962084 /* PBXContainerItemProxy */; }; - 8118B69A1D0A5FA300962084 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = FBSDKShareKit_TV; - targetProxy = 8118B6991D0A5FA300962084 /* PBXContainerItemProxy */; - }; 9DEC55901BBA636A00C7DB4A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 9DEC55821BBA636A00C7DB4A /* FBSDKTVOSKit_TV */; diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.h b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.h index 50634abd3a..cef1e3e964 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.h +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.h @@ -37,7 +37,6 @@ NS_ASSUME_NONNULL_BEGIN * `` (see FBSDKTVLoginButtonElement.h for details) * `` (see FBSDKTVLoginViewControllerElement.h for details) - * `` (see FBSDKTVShareButtonElement.h for details) */ NS_SWIFT_NAME(TVInterfaceFactory) diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.m b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.m index 438eae91da..48261d50aa 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.m +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVInterfaceFactory.m @@ -18,7 +18,6 @@ #import "FBSDKTVInterfaceFactory.h" -#import #import #ifdef FBSDKCOCOAPODS @@ -29,32 +28,10 @@ #import "FBSDKDeviceLoginButton.h" #import "FBSDKTVLoginButtonElement.h" #import "FBSDKTVLoginViewControllerElement.h" -#import "FBSDKTVShareButtonElement.h" static NSString *const FBSDKLoginButtonTag = @"FBSDKLoginButton"; -static NSString *const FBSDKShareButtonTag = @"FBSDKShareButton"; static NSString *const FBSDKLoginViewControllerTag = @"FBSDKLoginViewController"; -static Class FBSDKDynamicallyLoadShareKitClassFromString(NSString *className) -{ - static NSMutableDictionary *classes; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - classes = [NSMutableDictionary dictionary]; - }); - if (!classes[className]) { - classes[className] = NSClassFromString(className); - } - Class clazz = classes[className]; - if (clazz == nil) { - NSString *message = [NSString stringWithFormat:@"Unable to load class %1$@. Did you link FBSDKShareKit.framework or add [%1$@ class] in your application delegate?", className]; - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:message - userInfo:nil]; - } - return clazz; -} - @implementation FBSDKTVInterfaceFactory { id _interfaceCreator; @@ -68,8 +45,6 @@ - (instancetype)initWithInterfaceCreator:(id)interfaceCreat [TVElementFactory registerViewElementClass:[FBSDKTVLoginButtonElement class] forElementName:FBSDKLoginButtonTag]; [TVElementFactory registerViewElementClass:[FBSDKTVLoginViewControllerElement class] forElementName:FBSDKLoginViewControllerTag]; - [TVElementFactory registerViewElementClass:[FBSDKTVShareButtonElement class] forElementName:FBSDKShareButtonTag]; - return self; } @@ -84,26 +59,6 @@ - (UIView *)viewForElement:(TVViewElement *)element button.permissions = [self permissionsFromElement:element]; button.redirectURL = [NSURL URLWithString:element.attributes[@"redirectURL"]]; return button; - } else if ([element isKindOfClass:[FBSDKTVShareButtonElement class]]) { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - FBSDKDeviceShareButton *button = [[FBSDKDynamicallyLoadShareKitClassFromString(@"FBSDKDeviceShareButton") alloc] initWithFrame:CGRectZero]; - #pragma clang diagnostic pop - id content = nil; - if (element.attributes[@"href"]) { - content = [[FBSDKDynamicallyLoadShareKitClassFromString(@"FBSDKShareLinkContent") alloc] init]; - content.contentURL = [NSURL URLWithString:element.attributes[@"href"]]; - } - - if (content) { - button.shareContent = content; - return button; - } else { - NSString *message = [NSString stringWithFormat:@"Invalid parameters for %@ (%@)", element.elementIdentifier, element.elementName]; - @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:message - userInfo:nil]; - } } if ([_interfaceCreator respondsToSelector:@selector(viewForElement:existingView:)]) { return [_interfaceCreator viewForElement:element existingView:existingView]; diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h index 4e36ab3c27..c484a3ff9b 100644 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h +++ b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVOSKit.h @@ -23,6 +23,5 @@ #import #import #import -#import #import diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.h b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.h deleted file mode 100644 index f9a62c1116..0000000000 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.h +++ /dev/null @@ -1,43 +0,0 @@ -// 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 - -NS_ASSUME_NONNULL_BEGIN - -/*! - @abstract Represents a tag in TVML. Requires FBSDKShareKit.framework to be linked. - @discussion You should not need to use this class directly. Instead, make sure you - initialize a `FBSDKTVInterfaceFactory` instance correctly. - - The '' tag must also have the following attributes to define - the share content: - - `href` the url to share - - Examples: - @code - - */ -NS_SWIFT_NAME(FBTVShareButtonElement) -@interface FBSDKTVShareButtonElement : TVViewElement - -@end - -NS_ASSUME_NONNULL_END diff --git a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.m b/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.m deleted file mode 100644 index df8dcb4852..0000000000 --- a/FBSDKTVOSKit/FBSDKTVOSKit/FBSDKTVShareButtonElement.m +++ /dev/null @@ -1,23 +0,0 @@ -// 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 "FBSDKTVShareButtonElement.h" - -@implementation FBSDKTVShareButtonElement - -@end From 4043c3467aca0f49344c16d20ff6b8756722d67f Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Fri, 18 Dec 2020 15:51:31 -0800 Subject: [PATCH 202/227] Change logout endpoint parameters Summary: We will call the logout endpoint with id token (authentication token) string instead of JTI Reviewed By: joesus Differential Revision: D25646193 fbshipit-source-id: 31b11e05122af03a3d2901c7e4e8d65443dd877a --- .../FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m | 4 ++-- .../Internal/FBSDKAuthenticationStatusUtilityTests.m | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m index 4c3dd2af81..ccf25d4e9a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m @@ -77,11 +77,11 @@ + (NSURL *)_requestURL { FBSDKAuthenticationToken *token = FBSDKAuthenticationToken.currentAuthenticationToken; - if (!token || !token.jti) { + if (!token.tokenString) { return nil; } - NSDictionary *params = @{@"jti" : token.jti}; + NSDictionary *params = @{@"id_token" : token.tokenString}; NSError *urlError; NSString *host; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m index 75a837ebef..7905bdd513 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationStatusUtilityTests.m @@ -79,7 +79,7 @@ - (void)testRequestURL XCTAssertEqualObjects(url.path, @"/platform/oidc/status"); NSDictionary *params = [FBSDKInternalUtility parametersFromFBURL:url]; - XCTAssertEqualObjects(params[@"jti"], FBSDKAuthenticationToken.currentAuthenticationToken.jti, @"Incorrent JTI parameter in request url"); + XCTAssertEqualObjects(params[@"id_token"], FBSDKAuthenticationToken.currentAuthenticationToken.tokenString, @"Incorrect ID token parameter in request url"); } // MARK: _handleResponse From d96915194fcbecdd234b80caf0fa1fbf79c5a38b Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Fri, 18 Dec 2020 16:08:53 -0800 Subject: [PATCH 203/227] Use switches for enums Summary: Minor cleanup around checking enum cases. Reviewed By: robtimp Differential Revision: D25647669 fbshipit-source-id: 7ec49b544204c4270024a516fe1a527ca440b19a --- .../FBSDKLoginKit/FBSDKLoginConfiguration.m | 16 +++++++++------- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 17 +++++++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m index b995846205..1b7b60d081 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m @@ -88,14 +88,16 @@ - (instancetype)init + (BOOL)_arePermissionsValid:(NSSet *)permissions forTrackingPreference:(FBSDKLoginTracking)tracking { - if (tracking == FBSDKLoginTrackingLimited) { - NSSet *validPermissions = [NSSet setWithArray:@[@"email", @"public_profile"]]; - NSSet *combined = [permissions setByAddingObjectsFromSet:validPermissions]; - - return (permissions.count == 0) || (combined.count <= validPermissions.count); + switch (tracking) { + case FBSDKLoginTrackingLimited: { + NSSet *validPermissions = [NSSet setWithArray:@[@"email", @"public_profile"]]; + NSSet *combined = [permissions setByAddingObjectsFromSet:validPermissions]; + + return (permissions.count == 0) || (combined.count <= validPermissions.count); + } + case FBSDKLoginTrackingEnabled: + return YES; } - - return YES; } @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 7ed0eb3b70..ec6385cf72 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -427,13 +427,18 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co NSString *responseType; NSString *tp; - if (configuration.tracking == FBSDKLoginTrackingLimited) { - responseType = @"id_token"; - tp = @"ios_14_do_not_track"; - } else { - responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; - tp = @"ios_14_can_track"; + + switch (configuration.tracking) { + case FBSDKLoginTrackingLimited: + responseType = @"id_token"; + tp = @"ios_14_do_not_track"; + break; + case FBSDKLoginTrackingEnabled: + responseType = @"id_token,token_or_nonce,signed_request,graph_domain"; + tp = @"ios_14_can_track"; + break; } + [FBSDKTypeUtility dictionary:loginParams setObject:responseType forKey:@"response_type"]; [FBSDKTypeUtility dictionary:loginParams setObject:tp forKey:@"tp"]; From 6feeafc09e8435629c8117973d43e5d0757f18a9 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 12:04:26 -0800 Subject: [PATCH 204/227] add prefix to private methods and pragma mark in FBSDKCrashShield Summary: as title Reviewed By: Oliverccccct Differential Revision: D25662812 fbshipit-source-id: 15f86cddcee5642b3812c1c3b750882e282973f1 --- .../Instrument/CrashReport/FBSDKCrashShield.m | 10 ++++--- .../Instrument/FBSDKCrashShieldTests.m | 28 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m index d529e63d3b..589d1c3aa0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/CrashReport/FBSDKCrashShield.m @@ -82,7 +82,7 @@ + (void)analyze:(NSArray *> *)crashLogs NSMutableSet *disabledFeatues = [NSMutableSet set]; for (NSDictionary *crashLog in crashLogs) { NSArray *callstack = crashLog[@"callstack"]; - NSString *featureName = [self getFeature:callstack]; + NSString *featureName = [self _getFeature:callstack]; if (featureName) { [FBSDKFeatureManager disableFeature:featureName]; [disabledFeatues addObject:featureName]; @@ -109,12 +109,14 @@ + (void)analyze:(NSArray *> *)crashLogs } } -+ (nullable NSString *)getFeature:(NSArray *)callstack +#pragma mark - Private Methods + ++ (nullable NSString *)_getFeature:(NSArray *)callstack { NSArray *validCallstack = [FBSDKTypeUtility arrayValue:callstack]; NSArray *featureNames = _featureMapping.allKeys; for (NSString *entry in validCallstack) { - NSString *className = [self getClassName:[FBSDKTypeUtility stringValue:entry]]; + NSString *className = [self _getClassName:[FBSDKTypeUtility stringValue:entry]]; for (NSString *featureName in featureNames) { NSArray *classArray = [FBSDKTypeUtility dictionary:_featureMapping objectForKey:featureName ofType:NSObject.class]; if (className && [classArray containsObject:className]) { @@ -125,7 +127,7 @@ + (nullable NSString *)getFeature:(NSArray *)callstack return nil; } -+ (nullable NSString *)getClassName:(NSString *)entry ++ (nullable NSString *)_getClassName:(NSString *)entry { NSString *validEntry = [FBSDKTypeUtility stringValue:entry]; NSArray *items = [validEntry componentsSeparatedByString:@" "]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m index 8ddc549422..63f6799d6c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Instrument/FBSDKCrashShieldTests.m @@ -26,8 +26,8 @@ @interface FBSDKCrashShield (Testing) -+ (nullable NSString *)getFeature:(NSArray *)callstack; -+ (nullable NSString *)getClassName:(NSString *)entry; ++ (nullable NSString *)_getFeature:(NSArray *)callstack; ++ (nullable NSString *)_getClassName:(NSString *)entry; @end @@ -45,28 +45,28 @@ - (void)testGetFeature @"+[FBSDKMetadataIndexer crash]+84", @"(22 DEV METHODS)"]; - NSString *featureName1 = [FBSDKCrashShield getFeature:callstack1]; + NSString *featureName1 = [FBSDKCrashShield _getFeature:callstack1]; XCTAssertTrue([featureName1 isEqualToString:@"AAM"]); NSArray *callstack2 = @[@"(4 DEV METHODS)", @"+[FBSDKCodelessIndexer crash]+84", @"(22 DEV METHODS)"]; - NSString *featureName2 = [FBSDKCrashShield getFeature:callstack2]; + NSString *featureName2 = [FBSDKCrashShield _getFeature:callstack2]; XCTAssertTrue([featureName2 isEqualToString:@"CodelessEvents"]); NSArray *callstack3 = @[@"(4 DEV METHODS)", @"+[FBSDKRestrictiveDataFilterManager crash]+84", @"(22 DEV METHODS)"]; - NSString *featureName3 = [FBSDKCrashShield getFeature:callstack3]; + NSString *featureName3 = [FBSDKCrashShield _getFeature:callstack3]; XCTAssertTrue([featureName3 isEqualToString:@"RestrictiveDataFiltering"]); NSArray *callstack4 = @[@"(4 DEV METHODS)", @"+[FBSDKErrorReport crash]+84", @"(22 DEV METHODS)"]; - NSString *featureName4 = [FBSDKCrashShield getFeature:callstack4]; + NSString *featureName4 = [FBSDKCrashShield _getFeature:callstack4]; XCTAssertTrue([featureName4 isEqualToString:@"ErrorReport"]); // feature in other kit @@ -74,7 +74,7 @@ - (void)testGetFeature @"+[FBSDKVideoUploader crash]+84", @"(22 DEV METHODS)"]; - NSString *featureName5 = [FBSDKCrashShield getFeature:callstack5]; + NSString *featureName5 = [FBSDKCrashShield _getFeature:callstack5]; XCTAssertNil(featureName5); } @@ -84,14 +84,14 @@ - (void)testParsingFeatureFromValidCallstack @"+[FBSDKVideoUploader crash]+84", @"(22 DEV METHODS)"]; for (int i = 0; i < 100; i++) { - [FBSDKCrashShield getFeature:[Fuzzer randomizeWithJson:callstack]]; + [FBSDKCrashShield _getFeature:[Fuzzer randomizeWithJson:callstack]]; } } - (void)testParsingFeatureFromGarbage { for (int i = 0; i < 100; i++) { - [FBSDKCrashShield getFeature:Fuzzer.random]; + [FBSDKCrashShield _getFeature:Fuzzer.random]; } } @@ -101,24 +101,24 @@ - (void)testGetClassName { // class method NSString *entry1 = @"+[FBSDKRestrictiveDataFilterManager crash]+84"; - NSString *className1 = [FBSDKCrashShield getClassName:entry1]; + NSString *className1 = [FBSDKCrashShield _getClassName:entry1]; XCTAssertTrue([className1 isEqualToString:@"FBSDKRestrictiveDataFilterManager"]); // instance method NSString *entry2 = @"-[FBSDKRestrictiveDataFilterManager crash]+84"; - NSString *className2 = [FBSDKCrashShield getClassName:entry2]; + NSString *className2 = [FBSDKCrashShield _getClassName:entry2]; XCTAssertTrue([className2 isEqualToString:@"FBSDKRestrictiveDataFilterManager"]); // ineligible format NSString *entry3 = @"(6 DEV METHODS)"; - NSString *className3 = [FBSDKCrashShield getClassName:entry3]; + NSString *className3 = [FBSDKCrashShield _getClassName:entry3]; XCTAssertNil(className3); } - (void)testParsingClassName { for (int i = 0; i < 100; i++) { - [FBSDKCrashShield getClassName:Fuzzer.random]; + [FBSDKCrashShield _getClassName:Fuzzer.random]; } } @@ -133,7 +133,7 @@ - (void)testAnalyzingEmptyCrashLogs - (void)testAnalyzingInvalidCrashLogs { for (int i = 0; i < 100; i++) { - [FBSDKCrashShield getClassName:[Fuzzer randomizeWithJson:self.coreKitCrashLogs]]; + [FBSDKCrashShield _getClassName:[Fuzzer randomizeWithJson:self.coreKitCrashLogs]]; } } From e3a8f4daef22d5ba8a959ce9fc6c83f8f83f7b3f Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 12:39:11 -0800 Subject: [PATCH 205/227] add prefix to private methods in FBSDKCrashHandler Summary: Add prefix to private methods in FBSDKCrashHandler. No logic change. Reviewed By: joesus Differential Revision: D25662746 fbshipit-source-id: 9494e9174feb26482218369d33771d93d27feb40 --- .../Internal/Basics/FBSDKCrashHandlerTests.m | 32 ++++---- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 74 +++++++++---------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m index 5a4ba77cde..dd86a35072 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKCrashHandlerTests.m @@ -26,15 +26,15 @@ @interface FBSDKCrashHandler () -+ (void)uninstallExceptionsHandler; -+ (NSArray *)getCrashLogFileNames:(NSArray *)files; -+ (NSString *)getPathToCrashFile:(NSString *)timestamp; -+ (NSString *)getPathToLibDataFile:(NSString *)identifier; -+ (BOOL)callstack:(NSArray *)callstack - containsPrefix:(NSArray *)prefixList; -+ (NSArray *> *)filterCrashLogs:(NSArray *)prefixList - processedCrashLogs:(NSArray *> *)processedCrashLogs; -+ (void)saveCrashLog:(NSDictionary *)crashLog; ++ (void)_uninstallExceptionsHandler; ++ (NSArray *)_getCrashLogFileNames:(NSArray *)files; ++ (NSString *)_getPathToCrashFile:(NSString *)timestamp; ++ (NSString *)_getPathToLibDataFile:(NSString *)identifier; ++ (BOOL)_callstack:(NSArray *)callstack + containsPrefix:(NSArray *)prefixList; ++ (NSArray *> *)_filterCrashLogs:(NSArray *)prefixList + processedCrashLogs:(NSArray *> *)processedCrashLogs; ++ (void)_saveCrashLog:(NSDictionary *)crashLog; @end @@ -67,7 +67,7 @@ - (void)testGetCrashLogFileNames @"SUGGEST_EVENT_3.rules", @"crash.text", ]; - NSArray *result1 = [FBSDKCrashHandler getCrashLogFileNames:files]; + NSArray *result1 = [FBSDKCrashHandler _getCrashLogFileNames:files]; XCTAssertTrue([result1 containsObject:@"crash_log_1576471375.json"]); XCTAssertFalse([result1 containsObject:@"crash_lib_data_05DEDC8AFC724E09A5E68190C492B92B.json"]); @@ -77,7 +77,7 @@ - (void)testGetCrashLogFileNames XCTAssertFalse([result1 containsObject:@"crash.text"]); files = [NSArray array]; - NSArray *result2 = [FBSDKCrashHandler getCrashLogFileNames:files]; + NSArray *result2 = [FBSDKCrashHandler _getCrashLogFileNames:files]; XCTAssertTrue(result2.count == 0); } @@ -85,7 +85,7 @@ - (void)testGetPathToCrashFile { NSString *timestampMock = @"test_timestamp"; NSString *crashLogFileName = [NSString stringWithFormat:@"crash_log_%@.json", timestampMock]; - NSString *pathToCrashFile = [FBSDKCrashHandler getPathToCrashFile:timestampMock]; + NSString *pathToCrashFile = [FBSDKCrashHandler _getPathToCrashFile:timestampMock]; XCTAssertTrue([pathToCrashFile hasSuffix:crashLogFileName]); } @@ -94,7 +94,7 @@ - (void)testGetPathToLibDataFile { NSString *identifierMock = @"test_identifier"; NSString *libDataFileName = [NSString stringWithFormat:@"crash_lib_data_%@.json", identifierMock]; - NSString *pathToLibDataFile = [FBSDKCrashHandler getPathToLibDataFile:identifierMock]; + NSString *pathToLibDataFile = [FBSDKCrashHandler _getPathToLibDataFile:identifierMock]; XCTAssertTrue([pathToLibDataFile hasSuffix:libDataFileName]); } @@ -108,19 +108,19 @@ - (void)testCallStackContainsPrefix @"-[FBSDKWebViewAppLinkResolver appLinkFromALData:destination:]+10540", @"(14 DEV METHODS)", ]; - XCTAssertTrue([FBSDKCrashHandler callstack:callStack1 containsPrefix:prefixList]); + XCTAssertTrue([FBSDKCrashHandler _callstack:callStack1 containsPrefix:prefixList]); NSArray *callStack2 = @[ @"(2 DEV METHODS)", @"-[FBAdPersistentCacheImpl storeAssetInMemory:forKey:expiration:]+14455428", @"(12 DEV METHODS)", ]; - XCTAssertFalse([FBSDKCrashHandler callstack:callStack2 containsPrefix:prefixList]); + XCTAssertFalse([FBSDKCrashHandler _callstack:callStack2 containsPrefix:prefixList]); } - (void)testFilterCrashLogs { - NSArray *filteredCrashLogs = [FBSDKCrashHandler filterCrashLogs:@[@"FBSDK", @"_FBSDK"] processedCrashLogs:[self mockProcessedCrashLogs]]; + NSArray *filteredCrashLogs = [FBSDKCrashHandler _filterCrashLogs:@[@"FBSDK", @"_FBSDK"] processedCrashLogs:[self mockProcessedCrashLogs]]; XCTAssertEqual(1, filteredCrashLogs.count); diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index c33becb7c4..08cd222006 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -65,31 +65,31 @@ + (void)initialize _observers = [[NSHashTable alloc] init]; } -+ (void)sendCrashLogs ++ (void)_sendCrashLogs { for (id observer in _observers) { if (observer && [observer respondsToSelector:@selector(didReceiveCrashLogs:)]) { - NSArray *> *filteredCrashLogs = [self filterCrashLogs:observer.prefixes processedCrashLogs:_processedCrashLogs]; + NSArray *> *filteredCrashLogs = [self _filterCrashLogs:observer.prefixes processedCrashLogs:_processedCrashLogs]; [observer didReceiveCrashLogs:filteredCrashLogs]; } } } -+ (NSArray *> *)filterCrashLogs:(NSArray *)prefixList - processedCrashLogs:(NSArray *> *)processedCrashLogs ++ (NSArray *> *)_filterCrashLogs:(NSArray *)prefixList + processedCrashLogs:(NSArray *> *)processedCrashLogs { NSMutableArray *> *crashLogs = [NSMutableArray array]; for (NSDictionary *crashLog in processedCrashLogs) { NSArray *callstack = crashLog[kFBSDKCallstack]; - if ([self callstack:callstack containsPrefix:prefixList]) { + if ([self _callstack:callstack containsPrefix:prefixList]) { [FBSDKTypeUtility array:crashLogs addObject:crashLog]; } } return crashLogs; } -+ (BOOL)callstack:(NSArray *)callstack - containsPrefix:(NSArray *)prefixList ++ (BOOL)_callstack:(NSArray *)callstack + containsPrefix:(NSArray *)prefixList { NSString *callStackString = [callstack componentsJoinedByString:@""]; for (NSString *prefix in prefixList) { @@ -103,27 +103,27 @@ + (BOOL)callstack:(NSArray *)callstack + (void)disable { _isTurnedOff = YES; - [FBSDKCrashHandler uninstallExceptionsHandler]; + [FBSDKCrashHandler _uninstallExceptionsHandler]; _observers = nil; } + (void)addObserver:(id)observer { - if (_isTurnedOff || ![self isSafeToGenerateMapping]) { + if (_isTurnedOff || ![self _isSafeToGenerateMapping]) { return; } static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ - [FBSDKCrashHandler installExceptionsHandler]; - _processedCrashLogs = [self getProcessedCrashLogs]; + [FBSDKCrashHandler _installExceptionsHandler]; + _processedCrashLogs = [self _getProcessedCrashLogs]; }); @synchronized(_observers) { if (![_observers containsObject:observer]) { [_observers addObject:observer]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) { - [self generateMethodMapping:observer]; + [self _generateMethodMapping:observer]; }); - [self sendCrashLogs]; + [self _sendCrashLogs]; } } } @@ -134,7 +134,7 @@ + (void)removeObserver:(id)observer if ([_observers containsObject:observer]) { [_observers removeObject:observer]; if (_observers.count == 0) { - [FBSDKCrashHandler uninstallExceptionsHandler]; + [FBSDKCrashHandler _uninstallExceptionsHandler]; } } } @@ -142,7 +142,7 @@ + (void)removeObserver:(id)observer # pragma mark handler function -+ (void)installExceptionsHandler ++ (void)_installExceptionsHandler { NSUncaughtExceptionHandler *currentHandler = NSGetUncaughtExceptionHandler(); @@ -152,7 +152,7 @@ + (void)installExceptionsHandler } } -+ (void)uninstallExceptionsHandler ++ (void)_uninstallExceptionsHandler { NSSetUncaughtExceptionHandler(previousExceptionHandler); previousExceptionHandler = nil; @@ -160,7 +160,7 @@ + (void)uninstallExceptionsHandler static void FBSDKExceptionHandler(NSException *exception) { - [FBSDKCrashHandler saveException:exception]; + [FBSDKCrashHandler _saveException:exception]; if (previousExceptionHandler) { previousExceptionHandler(exception); } @@ -168,20 +168,20 @@ static void FBSDKExceptionHandler(NSException *exception) #pragma mark - Storage -+ (void)saveException:(NSException *)exception ++ (void)_saveException:(NSException *)exception { if (exception.callStackSymbols && exception.name) { NSArray *stackSymbols = [NSArray arrayWithArray:exception.callStackSymbols]; - [self saveCrashLog:@{ + [self _saveCrashLog:@{ kFBSDKCallstack : stackSymbols, kFBSDKCrashReason : exception.name, }]; } } -+ (NSArray *> *)getProcessedCrashLogs ++ (NSArray *> *)_getProcessedCrashLogs { - NSArray *> *crashLogs = [self loadCrashLogs]; + NSArray *> *crashLogs = [self _loadCrashLogs]; if (0 == crashLogs.count) { [self clearCrashReportFiles]; return nil; @@ -190,7 +190,7 @@ + (void)saveException:(NSException *)exception for (NSDictionary *crashLog in crashLogs) { NSArray *callstack = crashLog[kFBSDKCallstack]; - NSData *data = [self loadLibData:crashLog]; + NSData *data = [self _loadLibData:crashLog]; if (!data) { continue; } @@ -208,16 +208,16 @@ + (void)saveException:(NSException *)exception return processedCrashLogs; } -+ (NSArray *> *)loadCrashLogs ++ (NSArray *> *)_loadCrashLogs { NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:NULL]; - NSArray *fileNames = [[self getCrashLogFileNames:files] sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { + NSArray *fileNames = [[self _getCrashLogFileNames:files] sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { return [obj2 compare:obj1]; }]; NSMutableArray *> *crashLogArray = [NSMutableArray array]; for (NSUInteger i = 0; i < MIN(fileNames.count, FBSDK_MAX_CRASH_LOGS); i++) { - NSData *data = [self loadCrashLog:[FBSDKTypeUtility array:fileNames objectAtIndex:i]]; + NSData *data = [self _loadCrashLog:[FBSDKTypeUtility array:fileNames objectAtIndex:i]]; if (!data) { continue; } @@ -231,7 +231,7 @@ + (void)saveException:(NSException *)exception return [crashLogArray copy]; } -+ (nullable NSData *)loadCrashLog:(NSString *)fileName ++ (nullable NSData *)_loadCrashLog:(NSString *)fileName { return [NSData dataWithContentsOfFile:[directoryPath stringByAppendingPathComponent:fileName] options:NSDataReadingMappedIfSafe error:nil]; } @@ -248,7 +248,7 @@ + (void)clearCrashReportFiles } } -+ (NSArray *)getCrashLogFileNames:(NSArray *)files ++ (NSArray *)_getCrashLogFileNames:(NSArray *)files { NSMutableArray *fileNames = [NSMutableArray array]; @@ -261,7 +261,7 @@ + (void)clearCrashReportFiles return fileNames; } -+ (void)saveCrashLog:(NSDictionary *)crashLog ++ (void)_saveCrashLog:(NSDictionary *)crashLog { NSMutableDictionary *completeCrashLog = [NSMutableDictionary dictionaryWithDictionary:crashLog]; NSString *currentTimestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; @@ -282,11 +282,11 @@ + (void)saveCrashLog:(NSDictionary *)crashLog NSData *data = [FBSDKTypeUtility dataWithJSONObject:completeCrashLog options:0 error:nil]; - [data writeToFile:[self getPathToCrashFile:currentTimestamp] + [data writeToFile:[self _getPathToCrashFile:currentTimestamp] atomically:YES]; } -+ (void)generateMethodMapping:(id)observer ++ (void)_generateMethodMapping:(id)observer { if (observer.prefixes.count == 0) { return; @@ -296,30 +296,30 @@ + (void)generateMethodMapping:(id)observer frameworks:observer.frameworks]; if (methodMapping.count > 0) { NSData *data = [FBSDKTypeUtility dataWithJSONObject:methodMapping options:0 error:nil]; - [data writeToFile:[self getPathToLibDataFile:mappingTableIdentifier] + [data writeToFile:[self _getPathToLibDataFile:mappingTableIdentifier] atomically:YES]; } } -+ (nullable NSData *)loadLibData:(NSDictionary *)crashLog ++ (nullable NSData *)_loadLibData:(NSDictionary *)crashLog { NSString *identifier = [FBSDKTypeUtility dictionary:crashLog objectForKey:kFBSDKMappingTableIdentifier ofType:NSObject.class]; - return [NSData dataWithContentsOfFile:[self getPathToLibDataFile:identifier] options:NSDataReadingMappedIfSafe error:nil]; + return [NSData dataWithContentsOfFile:[self _getPathToLibDataFile:identifier] options:NSDataReadingMappedIfSafe error:nil]; } -+ (NSString *)getPathToCrashFile:(NSString *)timestamp ++ (NSString *)_getPathToCrashFile:(NSString *)timestamp { return [directoryPath stringByAppendingPathComponent: [NSString stringWithFormat:@"crash_log_%@.json", timestamp]]; } -+ (NSString *)getPathToLibDataFile:(NSString *)identifier ++ (NSString *)_getPathToLibDataFile:(NSString *)identifier { return [directoryPath stringByAppendingPathComponent: [NSString stringWithFormat:@"crash_lib_data_%@.json", identifier]]; } -+ (BOOL)isSafeToGenerateMapping ++ (BOOL)_isSafeToGenerateMapping { #if TARGET_OS_SIMULATOR return YES; @@ -330,7 +330,7 @@ + (BOOL)isSafeToGenerateMapping return YES; } - return [[NSFileManager defaultManager] fileExistsAtPath:[self getPathToLibDataFile:identifier]]; + return [[NSFileManager defaultManager] fileExistsAtPath:[self _getPathToLibDataFile:identifier]]; #endif } From 8e3d0309893c0253c18d464b011d2432f378b8f0 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 13:41:09 -0800 Subject: [PATCH 206/227] add pragma mark to FBSDKCrashHandler Summary: as title Reviewed By: joesus Differential Revision: D25667409 fbshipit-source-id: d1b95908c692f6418678b130e9eb2735280abfc0 --- .../FBSDKCoreKit_Basics/FBSDKCrashHandler.m | 106 +++++++++--------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m index 08cd222006..ccae730c05 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKCrashHandler.m @@ -51,8 +51,6 @@ @implementation FBSDKCrashHandler static NSArray *> *_processedCrashLogs; static BOOL _isTurnedOff; -# pragma mark - Class Methods - + (void)initialize { NSString *dirPath = [NSTemporaryDirectory() stringByAppendingPathComponent:FBSDK_CRASH_PATH_NAME]; @@ -65,39 +63,11 @@ + (void)initialize _observers = [[NSHashTable alloc] init]; } -+ (void)_sendCrashLogs -{ - for (id observer in _observers) { - if (observer && [observer respondsToSelector:@selector(didReceiveCrashLogs:)]) { - NSArray *> *filteredCrashLogs = [self _filterCrashLogs:observer.prefixes processedCrashLogs:_processedCrashLogs]; - [observer didReceiveCrashLogs:filteredCrashLogs]; - } - } -} +#pragma mark - Public API -+ (NSArray *> *)_filterCrashLogs:(NSArray *)prefixList - processedCrashLogs:(NSArray *> *)processedCrashLogs -{ - NSMutableArray *> *crashLogs = [NSMutableArray array]; - for (NSDictionary *crashLog in processedCrashLogs) { - NSArray *callstack = crashLog[kFBSDKCallstack]; - if ([self _callstack:callstack containsPrefix:prefixList]) { - [FBSDKTypeUtility array:crashLogs addObject:crashLog]; - } - } - return crashLogs; -} - -+ (BOOL)_callstack:(NSArray *)callstack - containsPrefix:(NSArray *)prefixList ++ (NSString *)getFBSDKVersion { - NSString *callStackString = [callstack componentsJoinedByString:@""]; - for (NSString *prefix in prefixList) { - if ([callStackString containsString:prefix]) { - return YES; - } - } - return NO; + return FBSDK_VERSION_STRING; } + (void)disable @@ -140,7 +110,19 @@ + (void)removeObserver:(id)observer } } -# pragma mark handler function ++ (void)clearCrashReportFiles +{ + NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil]; + + for (NSUInteger i = 0; i < files.count; i++) { + // remove all crash related files except for the current mapping table + if ([[FBSDKTypeUtility array:files objectAtIndex:i] hasPrefix:@"crash_"] && ![[FBSDKTypeUtility array:files objectAtIndex:i] containsString:mappingTableIdentifier]) { + [[NSFileManager defaultManager] removeItemAtPath:[directoryPath stringByAppendingPathComponent:[FBSDKTypeUtility array:files objectAtIndex:i]] error:nil]; + } + } +} + +# pragma mark - Handler + (void)_installExceptionsHandler { @@ -166,7 +148,7 @@ static void FBSDKExceptionHandler(NSException *exception) } } -#pragma mark - Storage +#pragma mark - Storage & Process + (void)_saveException:(NSException *)exception { @@ -236,18 +218,6 @@ + (nullable NSData *)_loadCrashLog:(NSString *)fileName return [NSData dataWithContentsOfFile:[directoryPath stringByAppendingPathComponent:fileName] options:NSDataReadingMappedIfSafe error:nil]; } -+ (void)clearCrashReportFiles -{ - NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil]; - - for (NSUInteger i = 0; i < files.count; i++) { - // remove all crash related files except for the current mapping table - if ([[FBSDKTypeUtility array:files objectAtIndex:i] hasPrefix:@"crash_"] && ![[FBSDKTypeUtility array:files objectAtIndex:i] containsString:mappingTableIdentifier]) { - [[NSFileManager defaultManager] removeItemAtPath:[directoryPath stringByAppendingPathComponent:[FBSDKTypeUtility array:files objectAtIndex:i]] error:nil]; - } - } -} - + (NSArray *)_getCrashLogFileNames:(NSArray *)files { NSMutableArray *fileNames = [NSMutableArray array]; @@ -286,6 +256,43 @@ + (void)_saveCrashLog:(NSDictionary *)crashLog atomically:YES]; } ++ (void)_sendCrashLogs +{ + for (id observer in _observers) { + if (observer && [observer respondsToSelector:@selector(didReceiveCrashLogs:)]) { + NSArray *> *filteredCrashLogs = [self _filterCrashLogs:observer.prefixes processedCrashLogs:_processedCrashLogs]; + [observer didReceiveCrashLogs:filteredCrashLogs]; + } + } +} + ++ (NSArray *> *)_filterCrashLogs:(NSArray *)prefixList + processedCrashLogs:(NSArray *> *)processedCrashLogs +{ + NSMutableArray *> *crashLogs = [NSMutableArray array]; + for (NSDictionary *crashLog in processedCrashLogs) { + NSArray *callstack = crashLog[kFBSDKCallstack]; + if ([self _callstack:callstack containsPrefix:prefixList]) { + [FBSDKTypeUtility array:crashLogs addObject:crashLog]; + } + } + return crashLogs; +} + ++ (BOOL)_callstack:(NSArray *)callstack + containsPrefix:(NSArray *)prefixList +{ + NSString *callStackString = [callstack componentsJoinedByString:@""]; + for (NSString *prefix in prefixList) { + if ([callStackString containsString:prefix]) { + return YES; + } + } + return NO; +} + +#pragma mark - Method Mapping + + (void)_generateMethodMapping:(id)observer { if (observer.prefixes.count == 0) { @@ -334,9 +341,4 @@ + (BOOL)_isSafeToGenerateMapping #endif } -+ (NSString *)getFBSDKVersion -{ - return FBSDK_VERSION_STRING; -} - @end From 9e9e85392cc53c83588c75e65db07117c26bc564 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 21 Dec 2020 14:41:40 -0800 Subject: [PATCH 207/227] fix ProfilePictureView bug Summary: Fixing bug that ProfilePictureView is not getting cleared when a limited login session is invalidated by logout endpoint. The bug is caused by two notifications trying to update profile picture at the same time: 1) On app launched, a saved Profile instance is read from cache, which triggers a notification 2) ProfilePictureView makes an async network call to fetch the image from Profile 3) "Not Authorized" status returned from logout endpoint, Profile is set to nil, which triggers another notification. 4) ProfilePictureView clears the image after seeing Profile is nil 5) image fetch from step 2) completed. ProfilePictureView sets the image using the fecthed data The fix is to make sure `lastState` is set when the view will use an image, and is `nil` when the view will be cleared (use a placeholder). `_updateImageWithData:state` should return directly if the given state doesn't match `_lastState`. In the above example, `_lastState` will be set to nil in step 4), which will prevent the view from overwriting image in step 5) Reviewed By: joesus, regresscheck Differential Revision: D25650327 fbshipit-source-id: 59098376c93ea0f7e3cfc1355a2f8154e11d213a --- FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m | 11 ++++++++--- .../FBSDKCoreKitTests-Bridging-Header.h | 1 + .../FBSDKCoreKitTests/ProfilePictureViewTests.swift | 5 ++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m index 1e98115c1f..3b3053dd61 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m +++ b/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m @@ -245,8 +245,6 @@ - (void)configureProfilePictureView selector:@selector(_profileDidChangeNotification:) name:FBSDKProfileDidChangeNotification object:nil]; - - [self setNeedsImageUpdate]; } #pragma mark - Notifications @@ -286,12 +284,12 @@ - (void)_updateImageWithProfile if (![_lastState isValidForState:state]) { [self _setPlaceholderImage]; } - _lastState = state; FBSDKProfile *profile = FBSDKProfile.currentProfile; if (![state.profileID isEqualToString:@"me"] || !profile.imageURL) { return; } + _lastState = state; [self _fetchAndSetImageWithURL:profile.imageURL state:state]; } @@ -450,6 +448,13 @@ - (void)_updateImageWithData:(NSData *)data state:(FBSDKProfilePictureViewState } } + #pragma mark - Test Helpers + +- (FBSDKProfilePictureViewState *)lastState +{ + return _lastState; +} + @end #endif diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h index 4a6913604d..1a6bf81ea9 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h +++ b/FBSDKCoreKit/FBSDKCoreKitTests/FBSDKCoreKitTests-Bridging-Header.h @@ -63,6 +63,7 @@ NS_SWIFT_NAME(FBProfilePictureViewState) - (void)_updateImageWithAccessToken; - (void)_updateImage; - (void)_fetchAndSetImageWithURL:(NSURL *)imageURL state:(FBSDKProfilePictureViewState *)state; +- (nullable FBSDKProfilePictureViewState *)lastState; @end diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift b/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift index aee27cea67..626214f56c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift +++ b/FBSDKCoreKit/FBSDKCoreKitTests/ProfilePictureViewTests.swift @@ -198,6 +198,7 @@ class ProfilePictureView: XCTestCase { 1, "Should try to fetch image for a profile that have an imageURL" ) + XCTAssertNotNil(view.lastState(), "Should update state when profile has an imageURL"); } func testUpdatinImageWithProfileWithoutImageURL() { @@ -211,6 +212,7 @@ class ProfilePictureView: XCTestCase { 0, "Should try to fetch image for a profile that does not have an imageURL" ) + XCTAssertNil(view.lastState(), "Should not update state when profile does not have an imageURL") } func testUpdatingImageWithValidAccessToken() { @@ -224,6 +226,7 @@ class ProfilePictureView: XCTestCase { 1, "Should try to fetch image for a valid access token" ) + XCTAssertNotNil(view.lastState(), "Should update state when access token is valid"); } func testUpdatingImageWithInvalidAccessToken() { @@ -237,13 +240,13 @@ class ProfilePictureView: XCTestCase { 0, "Should not try to fetch image for an invalid access token" ) + XCTAssertNil(view.lastState(), "Should not update state when access token is not valid") } } class TestView: FBProfilePictureView { var updateImageWithAccessTokenCount = 0 var updateImageWithProfileCount = 0 - var updateImageWithDataCount = 0 var fetchAndSetImageCount = 0 override func _updateImageWithAccessToken() { From c086b72e475891cc2d4565a1610c531127962150 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 21 Dec 2020 15:03:51 -0800 Subject: [PATCH 208/227] Remove unused methods Summary: Removed `LoginManager.raiseLoginException` and `LoginManager.assertPermissions`, both of them are unused. Reviewed By: joesus Differential Revision: D25597945 fbshipit-source-id: 8b2e1f34533aac1386893c6568ecbadc55c7cf3f --- .../FBSDKLoginKit/FBSDKLoginManager.m | 92 +++++++------------ 1 file changed, 35 insertions(+), 57 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index ec6385cf72..2fa9e9ca29 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -135,14 +135,27 @@ - (void)logOut [FBSDKProfile setCurrentProfile:nil]; } - #pragma mark - Private - -- (void)raiseLoginException:(NSException *)exception +- (void)logInWithURL:(NSURL *)url + handler:(nullable FBSDKLoginManagerLoginResultBlock)handler { - _state = FBSDKLoginManagerStateIdle; - [exception raise]; + FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; + _logger = [[FBSDKLoginManagerLogger alloc] initWithLoggingToken:serverConfiguration.loggingToken]; + _handler = [handler copy]; + + [_logger startSessionForLoginManager:self]; + [_logger startAuthMethod:FBSDKLoginManagerLoggerAuthMethod_Applink]; + + NSDictionary *params = [self logInParametersFromURL:url]; + if (params) { + id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:params appID:[FBSDKSettings appID]]; + [completer completeLoginWithHandler:^(FBSDKLoginCompletionParameters *parameters) { + [self completeAuthentication:parameters expectChallenge:NO]; + }]; + } } + #pragma mark - Private + - (void)handleImplicitCancelOfLogIn { FBSDKLoginManagerLoginResult *result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil @@ -187,22 +200,6 @@ - (BOOL)isPerformingLogin return _state == FBSDKLoginManagerStatePerformingLogin; } -- (void)assertPermissions:(NSArray *)permissions -{ - for (NSString *permission in permissions) { - if (![permission isKindOfClass:[NSString class]]) { - [self raiseLoginException:[NSException exceptionWithName:NSInvalidArgumentException - reason:@"Permissions must be string values." - userInfo:nil]]; - } - if ([permission rangeOfString:@","].location != NSNotFound) { - [self raiseLoginException:[NSException exceptionWithName:NSInvalidArgumentException - reason:@"Permissions should each be specified in separate string values in the array." - userInfo:nil]]; - } - } -} - - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expectChallenge:(BOOL)expectChallenge { NSSet *recentlyGrantedPermissions = nil; @@ -479,25 +476,6 @@ - (NSDictionary *)logInParametersFromURL:(NSURL *)url return nil; } -- (void)logInWithURL:(NSURL *)url - handler:(nullable FBSDKLoginManagerLoginResultBlock)handler -{ - FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; - _logger = [[FBSDKLoginManagerLogger alloc] initWithLoggingToken:serverConfiguration.loggingToken]; - _handler = [handler copy]; - - [_logger startSessionForLoginManager:self]; - [_logger startAuthMethod:FBSDKLoginManagerLoggerAuthMethod_Applink]; - - NSDictionary *params = [self logInParametersFromURL:url]; - if (params) { - id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:params appID:[FBSDKSettings appID]]; - [completer completeLoginWithHandler:^(FBSDKLoginCompletionParameters *parameters) { - [self completeAuthentication:parameters expectChallenge:NO]; - }]; - } -} - - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler { if (!FBSDKAccessToken.currentAccessToken) { @@ -589,23 +567,6 @@ - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FB }]; } - #pragma mark - Test Methods - -- (void)setHandler:(FBSDKLoginManagerLoginResultBlock)handler -{ - _handler = [handler copy]; -} - -- (void)setRequestedPermissions:(NSSet *)requestedPermissions -{ - _requestedPermissions = [requestedPermissions copy]; -} - -- (FBSDKLoginConfiguration *)configuration -{ - return _configuration; -} - // change bool to auth method string. - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams handler:(FBSDKBrowserLoginSuccessBlock)handler @@ -659,6 +620,23 @@ - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams } } + #pragma mark - Test Methods + +- (void)setHandler:(FBSDKLoginManagerLoginResultBlock)handler +{ + _handler = [handler copy]; +} + +- (void)setRequestedPermissions:(NSSet *)requestedPermissions +{ + _requestedPermissions = [requestedPermissions copy]; +} + +- (FBSDKLoginConfiguration *)configuration +{ + return _configuration; +} + #pragma mark - FBSDKURLOpening - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { From f6ad1cf558e41acb8e9ac4dcfbc24cd17d9c5bd2 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 21 Dec 2020 16:02:27 -0800 Subject: [PATCH 209/227] Adding unit tests for LoginCompleter Summary: Started out interested in shoring up anywhere in this file that we may accidentally access a dictionary without type-checking. Scope creep happened: * Updates to use helper methods for unpacking expiration dates. * Refactors to pass in a `GraphRequestConnectionProviding` begin decoupling FBSDKCoreKit and making it easier to unit test various responses. Reviewed By: ppansy Differential Revision: D25650323 fbshipit-source-id: 03865603fb3ab83b4378e0875f051ef14f8a5a33 --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 38 +++- .../xcschemes/FBSDKLoginKit-Dynamic.xcscheme | 3 +- .../FBSDKGraphRequestConnectionProviding.h | 39 ++++ .../Internal/FBSDKLoginCompletion.m | 37 ++-- .../FBSDKLoginCompletionTests.m | 192 ++++++++++++++++++ .../FBSDKLoginKitTests-Bridging-Header.h | 2 + .../FakeGraphRequestConnectionProvider.swift | 17 ++ .../{ => Helpers}/Fuzzer.swift | 0 .../{ => Helpers}/SampleAccessToken.swift | 0 9 files changed, 297 insertions(+), 31 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/Helpers/FakeGraphRequestConnectionProvider.swift rename FBSDKLoginKit/FBSDKLoginKitTests/{ => Helpers}/Fuzzer.swift (100%) rename FBSDKLoginKit/FBSDKLoginKitTests/{ => Helpers}/SampleAccessToken.swift (100%) diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 6fda41c1d5..0e8bf6e1a8 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -135,7 +135,6 @@ C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6470B2024F45A3A00E7AEF7 /* FBSDKReferralManagerResult.m in Sources */ = {isa = PBXBuildFile; fileRef = C68C1C6B24F07688005067E1 /* FBSDKReferralManagerResult.m */; }; C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */; }; - C67DC42D258851C3004D7E43 /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C67DC42C258851C3004D7E43 /* Fuzzer.swift */; }; C681486C24F866EA004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C681486D24F866EA004EED1A /* FBSDKReferralCode.m in Sources */ = {isa = PBXBuildFile; fileRef = C681486B24F866EA004EED1A /* FBSDKReferralCode.m */; }; C681486E24F86712004EED1A /* FBSDKReferralCode.h in Headers */ = {isa = PBXBuildFile; fileRef = C681486124F866EA004EED1A /* FBSDKReferralCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -160,11 +159,15 @@ F4647492256B031600502449 /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; F4647493256B031600502449 /* FBSDKLoginConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = F464748F256B031600502449 /* FBSDKLoginConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F464749B256B048500502449 /* LoginConfigurationTests.swift */; }; + F4665CC2258D684300981FDE /* Fuzzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4665CC0258D684300981FDE /* Fuzzer.swift */; }; + F4665CC3258D684300981FDE /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4665CC1258D684300981FDE /* SampleAccessToken.swift */; }; + F4665CD3258D687500981FDE /* FakeGraphRequestConnectionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4665CD2258D687500981FDE /* FakeGraphRequestConnectionProvider.swift */; }; + F4665D31258D699100981FDE /* FBSDKGraphRequestConnectionProviding.h in Headers */ = {isa = PBXBuildFile; fileRef = F4665CAD258D66A800981FDE /* FBSDKGraphRequestConnectionProviding.h */; }; + F4665D39258D699200981FDE /* FBSDKGraphRequestConnectionProviding.h in Headers */ = {isa = PBXBuildFile; fileRef = F4665CAD258D66A800981FDE /* FBSDKGraphRequestConnectionProviding.h */; }; F46FA65A245347580060C902 /* FBLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA659245347570060C902 /* FBLoginButton.swift */; }; F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA659245347570060C902 /* FBLoginButton.swift */; }; F46FA65D245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; F46FA65E245347820060C902 /* LoginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FA65C245347820060C902 /* LoginManager.swift */; }; - F46FE68B2579764F000F4F53 /* SampleAccessToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */; }; F47E5CDC25895C5F008CA03E /* FBSDKLoginManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */; }; F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */; }; F4AA32822574448C005EDF04 /* LoginConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA32812574448C005EDF04 /* LoginConfiguration.swift */; }; @@ -390,7 +393,6 @@ 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginCompletionTests.m; sourceTree = ""; }; - C67DC42C258851C3004D7E43 /* Fuzzer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; C681486B24F866EA004EED1A /* FBSDKReferralCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCode.m; sourceTree = ""; }; C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerResult.h; sourceTree = ""; }; @@ -407,9 +409,12 @@ F464748E256B031600502449 /* FBSDKLoginConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginConfiguration.m; sourceTree = ""; }; F464748F256B031600502449 /* FBSDKLoginConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKLoginConfiguration.h; sourceTree = ""; }; F464749B256B048500502449 /* LoginConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginConfigurationTests.swift; sourceTree = ""; }; + F4665CAD258D66A800981FDE /* FBSDKGraphRequestConnectionProviding.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKGraphRequestConnectionProviding.h; sourceTree = ""; }; + F4665CC0258D684300981FDE /* Fuzzer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fuzzer.swift; sourceTree = ""; }; + F4665CC1258D684300981FDE /* SampleAccessToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; + F4665CD2258D687500981FDE /* FakeGraphRequestConnectionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeGraphRequestConnectionProvider.swift; sourceTree = ""; }; F46FA659245347570060C902 /* FBLoginButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBLoginButton.swift; sourceTree = ""; }; F46FA65C245347820060C902 /* LoginManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginManager.swift; sourceTree = ""; }; - F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleAccessToken.swift; sourceTree = ""; }; F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginManagerLoggerTests.m; sourceTree = ""; }; F4AA32812574448C005EDF04 /* LoginConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginConfiguration.swift; sourceTree = ""; }; F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKNonceUtility.h; sourceTree = ""; }; @@ -576,6 +581,7 @@ 9D3AF4911A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.h */, 9D3AF4921A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.m */, 9DBC4C3B1A782E2000816FE8 /* FBSDKCoreKit+Internal.h */, + F4665CAD258D66A800981FDE /* FBSDKGraphRequestConnectionProviding.h */, 6B5D2DEC1A8EB1D200D3EF09 /* FBSDKLoginCompletion.h */, 6B5D2DED1A8EB1D200D3EF09 /* FBSDKLoginCompletion.m */, 6BAFD01F1A9531EA0096E4B5 /* FBSDKLoginCompletion+Internal.h */, @@ -670,20 +676,19 @@ 9D9DB8E81A114E500086167B /* FBSDKLoginKitTests */ = { isa = PBXGroup; children = ( - F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */, + C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */, F4647451256AD09000502449 /* FBSDKLoginKitTests-Bridging-Header.h */, + F47FB44E25805E7900922543 /* FBSDKLoginManagerLoggerTests.m */, 9D641F831A7B69160048F563 /* FBSDKLoginManagerTests.m */, 6B6276321A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.h */, 6B6276331A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m */, C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */, C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */, + F4665CBF258D684300981FDE /* Helpers */, F40BFD55257852E5007B85AC /* LoginButtonTests.swift */, F464749B256B048500502449 /* LoginConfigurationTests.swift */, F4647478256AEF8E00502449 /* NonceTests.swift */, 9D9DB8E91A114E500086167B /* Supporting Files */, - F46FE68A2579764F000F4F53 /* SampleAccessToken.swift */, - C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */, - C67DC42C258851C3004D7E43 /* Fuzzer.swift */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -696,6 +701,16 @@ name = "Supporting Files"; sourceTree = ""; }; + F4665CBF258D684300981FDE /* Helpers */ = { + isa = PBXGroup; + children = ( + F4665CC0258D684300981FDE /* Fuzzer.swift */, + F4665CC1258D684300981FDE /* SampleAccessToken.swift */, + F4665CD2258D687500981FDE /* FakeGraphRequestConnectionProvider.swift */, + ); + path = Helpers; + sourceTree = ""; + }; F46FA66E24535E3F0060C902 /* Swift */ = { isa = PBXGroup; children = ( @@ -749,6 +764,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + F4665D31258D699100981FDE /* FBSDKGraphRequestConnectionProviding.h in Headers */, 0B9DBF17207C051800662776 /* FBSDKDeviceLoginCodeInfo.h in Headers */, 0B9DBF11207C051800662776 /* FBSDKDeviceLoginManagerResult.h in Headers */, 0B9DBF0F207C051800662776 /* FBSDKDeviceLoginManager.h in Headers */, @@ -781,6 +797,7 @@ 0B9DBF16207C051800662776 /* FBSDKDeviceLoginCodeInfo.h in Headers */, C68C1C6A24F074FD005067E1 /* FBSDKReferralManagerResult.h in Headers */, 0B9DBF10207C051800662776 /* FBSDKDeviceLoginManagerResult.h in Headers */, + F4665D39258D699200981FDE /* FBSDKGraphRequestConnectionProviding.h in Headers */, 0B9DBF0E207C051800662776 /* FBSDKDeviceLoginManager.h in Headers */, 9D3AF4931A9EFEFB00EEF724 /* _FBSDKLoginRecoveryAttempter.h in Headers */, C6CE2BBF24EB72F200CF2EB6 /* FBSDKReferralManager.h in Headers */, @@ -1198,16 +1215,17 @@ buildActionMask = 2147483647; files = ( F47E5CDC25895C5F008CA03E /* FBSDKLoginManagerTests.m in Sources */, + F4665CC2258D684300981FDE /* Fuzzer.swift in Sources */, F464749C256B048500502449 /* LoginConfigurationTests.swift in Sources */, - C67DC42D258851C3004D7E43 /* Fuzzer.swift in Sources */, F4647479256AEF8E00502449 /* NonceTests.swift in Sources */, F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */, + F4665CC3258D684300981FDE /* SampleAccessToken.swift in Sources */, + F4665CD3258D687500981FDE /* FakeGraphRequestConnectionProvider.swift in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */, 6B6276341A8C1BBF0030FEBD /* FBSDKLoginUtilityTests.m in Sources */, - F46FE68B2579764F000F4F53 /* SampleAccessToken.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme index f08b351142..ed924b6c4d 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/xcshareddata/xcschemes/FBSDKLoginKit-Dynamic.xcscheme @@ -26,7 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h new file mode 100644 index 0000000000..a771c51ac6 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h @@ -0,0 +1,39 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +/// An internal protocol used to describe an object that can handle graph requests +NS_SWIFT_NAME(GraphRequestConnectionProviding) +@protocol FBSDKGraphRequestConnectionProviding + +- (void)addRequest:(FBSDKGraphRequest *)request + completionHandler:(FBSDKGraphRequestBlock)handler; +- (void)start; + +@end + +// MARK: Default Protocol Conformances + +@interface FBSDKGraphRequestConnection (GraphRequestConnection) +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 1d8f427fdb..138e876aec 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -28,6 +28,7 @@ #import #endif + #import "FBSDKGraphRequestConnectionProviding.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" @@ -69,7 +70,7 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID { if ((self = [super init]) != nil) { - _parameters = [[FBSDKLoginCompletionParameters alloc] init]; + _parameters = [FBSDKLoginCompletionParameters new]; BOOL hasNonEmptyNonceString = ((NSString *)[FBSDKTypeUtility dictionary:parameters objectForKey:@"nonce" ofType:NSString.class]).length > 0; BOOL hasNonEmptyIdTokenString = ((NSString *)[FBSDKTypeUtility dictionary:parameters objectForKey:@"id_token" ofType:NSString.class]).length > 0; @@ -184,22 +185,27 @@ - (void)setErrorWithDictionary:(NSDictionary *)parameters } - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler +{ + FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new]; + [self exchangeNonceForTokenWithGraphRequestConnectionProvider:connection handler:handler]; +} + +- (void)exchangeNonceForTokenWithGraphRequestConnectionProvider:(nonnull id)connection + handler:(nonnull FBSDKLoginCompletionParametersBlock)handler { if (!handler) { return; } NSString *nonce = _parameters.nonceString ?: @""; - NSString *appID = [FBSDKSettings appID] ?: @""; + NSString *appID = _parameters.appID ?: @""; if (nonce.length == 0 || appID.length == 0) { _parameters.error = [FBSDKError errorWithCode:FBSDKErrorInvalidArgument message:@"Missing required parameters to exchange nonce for access token."]; - handler(_parameters); return; } - FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; FBSDKGraphRequest *tokenRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"oauth/access_token" parameters:@{ @"grant_type" : @"fb_exchange_nonce", @@ -211,22 +217,13 @@ - (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)ha __block FBSDKLoginCompletionParameters *parameters = _parameters; [connection addRequest:tokenRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, id result, - NSError *error) { - if (!error) { - parameters.accessTokenString = result[@"access_token"]; - NSDate *expirationDate = [NSDate distantFuture]; - if (result[@"expires_in"] && [result[@"expires_in"] integerValue] > 0) { - expirationDate = [NSDate dateWithTimeIntervalSinceNow:[result[@"expires_in"] integerValue]]; - } - parameters.expirationDate = expirationDate; - - NSDate *dataAccessExpirationDate = [NSDate distantFuture]; - if (result[@"data_access_expiration_time"] && [result[@"data_access_expiration_time"] integerValue] > 0) { - dataAccessExpirationDate = [NSDate dateWithTimeIntervalSince1970:[result[@"data_access_expiration_time"] integerValue]]; - } - parameters.dataAccessExpirationDate = dataAccessExpirationDate; + NSError *graphRequestError) { + if (!graphRequestError) { + parameters.accessTokenString = [FBSDKTypeUtility dictionary:result objectForKey:@"access_token" ofType:NSString.class]; + parameters.expirationDate = [FBSDKLoginURLCompleter expirationDateFromParameters:result]; + parameters.dataAccessExpirationDate = [FBSDKLoginURLCompleter dataAccessExpirationDateFromParameters:result]; } else { - parameters.error = error; + parameters.error = graphRequestError; } handler(parameters); @@ -293,7 +290,7 @@ + (NSString *)challengeFromParameters:(NSDictionary *)parameters if (!error) { NSString *challenge = [FBSDKTypeUtility dictionary:state objectForKey:@"challenge" ofType:NSString.class]; if (challenge.length > 0) { - return [FBSDKUtility URLDecode:state[@"challenge"]]; + return [FBSDKUtility URLDecode:challenge]; } } } diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m index c667b4f8cd..ea4b6ada93 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -33,6 +33,8 @@ @interface FBSDKLoginURLCompleter (Testing) - (FBSDKLoginCompletionParameters *)parameters; +- (void)exchangeNonceForTokenWithGraphRequestConnectionProvider:(id)connection + handler:(FBSDKLoginCompletionParametersBlock)handler; @end @@ -170,8 +172,198 @@ - (void)testInitWithFuzzyParameters } } +// MARK: - Nonce Exchange + +- (void)testExchangeNonceForTokenWithMissingHandler +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:_parameters appID:_fakeAppID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:nil]; + XCTAssertNil(connection.capturedGraphRequest, "Should not create a graph request if there's no handler to use the result"); +} + +- (void)testNonceExchangeWithoutNonce +{ + NSDictionary *parameters = self.rawParametersWithMissingNonce; + + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + + __block BOOL completionWasInvoked = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *_Nonnull completionParams) { + XCTAssertEqualObjects( + completer.parameters, + completionParams, + "Should call the completion with the provided parameters" + ); + XCTAssertEqual(completer.parameters.error.code, FBSDKErrorInvalidArgument, "Should provide an error with the expected code"); + completionWasInvoked = YES; + }; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:handler]; + XCTAssertTrue(completionWasInvoked); +} + +- (void)testNonceExchangeWithoutAppID +{ + NSString *appID = @"123"; + appID = nil; + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:_parameters appID:appID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + + __block BOOL completionWasInvoked = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *_Nonnull completionParams) { + XCTAssertEqualObjects( + completer.parameters, + completionParams, + "Should call the completion with the provided parameters" + ); + XCTAssertEqual(completer.parameters.error.code, FBSDKErrorInvalidArgument, "Should provide an error with the expected code"); + completionWasInvoked = YES; + }; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:handler]; + XCTAssertTrue(completionWasInvoked); + XCTAssertNil(connection.capturedGraphRequest, "Should not create a graph request if there's no handler to use the result"); +} + +- (void)testNonceExchangeGraphRequestCreation +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:_parameters appID:_fakeAppID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:^(FBSDKLoginCompletionParameters *_Nonnull parameters) { + // not important here + }]; + XCTAssertEqualObjects( + connection.capturedGraphRequest.graphPath, + @"oauth/access_token", + "Should create a graph request with the expected graph path" + ); + XCTAssertEqualObjects( + [connection.capturedGraphRequest.parameters objectForKey:@"grant_type"], + @"fb_exchange_nonce", + "Should create a graph request with the expected grant type parameter" + ); + XCTAssertEqualObjects( + [connection.capturedGraphRequest.parameters objectForKey:@"fb_exchange_nonce"], + completer.parameters.nonceString, + "Should create a graph request with the expected nonce parameter" + ); + XCTAssertEqualObjects( + [connection.capturedGraphRequest.parameters objectForKey:@"client_id"], + _fakeAppID, + "Should create a graph request with the expected app id parameter" + ); + XCTAssertEqualObjects( + [connection.capturedGraphRequest.parameters objectForKey:@"fields"], + @"", + "Should create a graph request with the expected fields parameter" + ); + XCTAssertEqual( + connection.capturedGraphRequest.flags, + FBSDKGraphRequestFlagDoNotInvalidateTokenOnError + | FBSDKGraphRequestFlagDisableErrorRecovery, + "The graph request should not invalidate the token on error or disable error recovery" + ); +} + +- (void)testNonceExchangeCompletionWithError +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:_parameters appID:_fakeAppID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + + __block BOOL completionWasInvoked = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *_Nonnull completionParams) { + XCTAssertEqualObjects( + completer.parameters, + completionParams, + "Should call the completion with the provided parameters" + ); + XCTAssertEqualObjects(completer.parameters.error, self.sampleError, "Should pass through the error from the graph request"); + completionWasInvoked = YES; + }; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:handler]; + connection.capturedCompletionHandler(nil, nil, self.sampleError); + XCTAssertTrue(completionWasInvoked); +} + +- (void)testNonceExchangeCompletionWithAccessTokenString +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:_parameters appID:_fakeAppID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + NSDictionary *stubbedResult = @{ @"access_token" : self.name }; + + __block BOOL completionWasInvoked = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *_Nonnull completionParams) { + XCTAssertEqualObjects( + completer.parameters, + completionParams, + "Should call the completion with the provided parameters" + ); + XCTAssertEqualObjects( + completer.parameters.accessTokenString, + self.name, + "Should set the access token string from the graph request's result" + ); + completionWasInvoked = YES; + }; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:handler]; + connection.capturedCompletionHandler(nil, stubbedResult, nil); + XCTAssertTrue(completionWasInvoked); +} + +- (void)testNonceExchangeWithRandomResults +{ + FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:_parameters appID:_fakeAppID]; + FakeGraphRequestConnection *connection = [FakeGraphRequestConnection new]; + NSDictionary *stubbedResult = @{ + @"access_token" : self.name, + @"expires_in" : @"10000", + @"data_access_expiration_time" : @1 + }; + + __block BOOL completionWasInvoked = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *_Nonnull completionParams) { + // Basically just making sure that nothing crashes here when we feed it garbage results + completionWasInvoked = YES; + }; + + [completer exchangeNonceForTokenWithGraphRequestConnectionProvider:connection + handler:handler]; + + for (int i = 0; i < 100; i++) { + NSDictionary *params = [stubbedResult copy]; + NSDictionary *parameters = [Fuzzer randomizeWithJson:params]; + connection.capturedCompletionHandler(nil, parameters, nil); + XCTAssertTrue(completionWasInvoked); + completionWasInvoked = NO; + } +} + // MARK: Helpers +- (NSError *)sampleError +{ + return [NSError errorWithDomain:self.name code:0 userInfo:nil]; +} + +- (NSDictionary *)rawParametersWithMissingNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"nonce"]]; + return parameters; +} + - (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParameter:(NSDictionary *)urlParameters { XCTAssertEqualObjects(parameters.accessTokenString, urlParameters[@"access_token"]); diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h index 0126b64546..19ff19cc8b 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -21,8 +21,10 @@ #import "FBSDKCoreKit+Internal.h" #ifdef BUCK + #import #import #else + #import "FBSDKGraphRequestConnectionProviding.h" #import "FBSDKNonceUtility.h" #endif diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/Helpers/FakeGraphRequestConnectionProvider.swift b/FBSDKLoginKit/FBSDKLoginKitTests/Helpers/FakeGraphRequestConnectionProvider.swift new file mode 100644 index 0000000000..8391fafbaf --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/Helpers/FakeGraphRequestConnectionProvider.swift @@ -0,0 +1,17 @@ +import Foundation + +@objcMembers +class FakeGraphRequestConnection: NSObject, GraphRequestConnectionProviding { + var startCallCount = 0 + var capturedGraphRequest: GraphRequest? + var capturedCompletionHandler: GraphRequestBlock? + + func add(_ request: GraphRequest, completionHandler handler: @escaping GraphRequestBlock) { + capturedGraphRequest = request + capturedCompletionHandler = handler + } + + func start() { + startCallCount += 1 + } +} diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift b/FBSDKLoginKit/FBSDKLoginKitTests/Helpers/Fuzzer.swift similarity index 100% rename from FBSDKLoginKit/FBSDKLoginKitTests/Fuzzer.swift rename to FBSDKLoginKit/FBSDKLoginKitTests/Helpers/Fuzzer.swift diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/SampleAccessToken.swift b/FBSDKLoginKit/FBSDKLoginKitTests/Helpers/SampleAccessToken.swift similarity index 100% rename from FBSDKLoginKit/FBSDKLoginKitTests/SampleAccessToken.swift rename to FBSDKLoginKit/FBSDKLoginKitTests/Helpers/SampleAccessToken.swift From d0374d96fc906489f9a4732686be5e88dbd95810 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 21 Dec 2020 16:17:06 -0800 Subject: [PATCH 210/227] Fix authentication token expiration check Summary: If expiration is nil, the token should be invalid. Fixing the verification logic to make it so Reviewed By: joesus Differential Revision: D25671980 fbshipit-source-id: 845022e03d437f84bdccc422219d118119c696eb --- .../Internal/FBSDKAuthenticationTokenClaims.m | 2 +- .../FBSDKAuthenticationTokenFactoryTests.m | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m index fd82d1d197..135398e290 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenClaims.m @@ -77,7 +77,7 @@ + (nullable FBSDKAuthenticationTokenClaims *)validatedClaimsWithEncodedString:(N NSNumber *expValue = [FBSDKTypeUtility numberValue:claimsDict[@"exp"]]; long exp = [expValue doubleValue]; - BOOL isExpired = expValue != nil && exp <= currentTime; + BOOL isExpired = expValue == nil || exp <= currentTime; NSNumber *iatValue = [FBSDKTypeUtility numberValue:claimsDict[@"iat"]]; long iat = [iatValue doubleValue]; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index a41ff8e96e..3341441adb 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -167,22 +167,42 @@ - (void)testDecodeInvalidClaims // non facebook issuer [self assertDecodeClaimsFailWithInvalidEntry:@"iss" value:@"https://notfacebook.com"]; + [self assertDecodeClaimsFailWithInvalidEntry:@"iss" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"iss" + value:@""]; // incorrect audience [self assertDecodeClaimsFailWithInvalidEntry:@"aud" value:@"wrong_app_id"]; + [self assertDecodeClaimsFailWithInvalidEntry:@"aud" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"aud" + value:@""]; // expired [self assertDecodeClaimsFailWithInvalidEntry:@"exp" value:@(currentTime - 60 * 60)]; + [self assertDecodeClaimsFailWithInvalidEntry:@"exp" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"exp" + value:@""]; // issued too long ago [self assertDecodeClaimsFailWithInvalidEntry:@"iat" value:@(currentTime - 60 * 60)]; + [self assertDecodeClaimsFailWithInvalidEntry:@"iat" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"iat" + value:@""]; // incorrect nonce [self assertDecodeClaimsFailWithInvalidEntry:@"nonce" value:@"incorrect_nonce"]; + [self assertDecodeClaimsFailWithInvalidEntry:@"nonce" + value:nil]; + [self assertDecodeClaimsFailWithInvalidEntry:@"nonce" + value:@""]; // invalid user ID [self assertDecodeClaimsFailWithInvalidEntry:@"sub" From 8ac6047f7de3a0ed1c1f190d332e26acac36d03d Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Mon, 21 Dec 2020 16:19:06 -0800 Subject: [PATCH 211/227] Add type verification for authentication token Summary: Add check to make sure "typ" in token header is "JWT" Reviewed By: joesus Differential Revision: D25672931 fbshipit-source-id: 0153fa34037bc67aefad54cc255586c78e77018c --- .../Internal/FBSDKAuthenticationTokenHeader.m | 2 +- .../FBSDKAuthenticationTokenFactoryTests.m | 28 +++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m index c819e5d293..547029ebd0 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenHeader.m @@ -49,7 +49,7 @@ + (nullable FBSDKAuthenticationTokenHeader *)validatedHeaderWithEncodedString:(N NSString *alg = [FBSDKTypeUtility dictionary:header objectForKey:@"alg" ofType:NSString.class]; NSString *typ = [FBSDKTypeUtility dictionary:header objectForKey:@"typ" ofType:NSString.class]; NSString *kid = [FBSDKTypeUtility dictionary:header objectForKey:@"kid" ofType:NSString.class]; - if (!error && alg.length > 0 && [alg isEqualToString:@"RS256"] && kid.length > 0) { + if (!error && [alg isEqualToString:@"RS256"] && [typ isEqualToString:@"JWT"] && kid.length > 0) { return [[FBSDKAuthenticationTokenHeader alloc] initWithAlg:alg typ:typ kid:kid]; } } diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index 3341441adb..d2e90822d2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -258,12 +258,16 @@ - (void)testDecodeInvalidFormatHeader - (void)testDecodeInvalidHeader { - NSMutableDictionary *invalidHeader = [_headerDict mutableCopy]; - [FBSDKTypeUtility dictionary:invalidHeader setObject:@"wrong algorithm" forKey:@"alg"]; - NSData *invalidHeaderData = [FBSDKTypeUtility dataWithJSONObject:invalidHeader options:0 error:nil]; - NSString *encodedHeader = [self base64URLEncodeData:invalidHeaderData]; + [self assertDecodeHeaderFailWithInvalidEntry:@"alg" value:@"wrong_algorithm"]; + [self assertDecodeHeaderFailWithInvalidEntry:@"alg" value:nil]; + [self assertDecodeHeaderFailWithInvalidEntry:@"alg" value:@""]; - XCTAssertNil([FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]); + [self assertDecodeHeaderFailWithInvalidEntry:@"typ" value:@"some_type"]; + [self assertDecodeHeaderFailWithInvalidEntry:@"typ" value:nil]; + [self assertDecodeHeaderFailWithInvalidEntry:@"typ" value:@""]; + + [self assertDecodeHeaderFailWithInvalidEntry:@"kid" value:nil]; + [self assertDecodeHeaderFailWithInvalidEntry:@"kid" value:@""]; } - (void)testDecodeEmptyHeader @@ -479,6 +483,20 @@ - (void)assertDecodeClaimsFailWithInvalidEntry:(NSString *)key value:(id)value XCTAssertNil([FBSDKAuthenticationTokenClaims validatedClaimsWithEncodedString:encodedClaims nonce:_mockNonce]); } +- (void)assertDecodeHeaderFailWithInvalidEntry:(NSString *)key value:(id)value +{ + NSMutableDictionary *invalidHeader = [_headerDict mutableCopy]; + if (value) { + [FBSDKTypeUtility dictionary:invalidHeader setObject:value forKey:key]; + } else { + [invalidHeader removeObjectForKey:key]; + } + NSData *headerData = [FBSDKTypeUtility dataWithJSONObject:invalidHeader options:0 error:nil]; + NSString *encodedHeader = [self base64URLEncodeData:headerData]; + + XCTAssertNil([FBSDKAuthenticationTokenHeader validatedHeaderWithEncodedString:encodedHeader]); +} + - (NSString *)base64URLEncodeData:(NSData *)data { NSString *base64 = [FBSDKBase64 encodeData:data]; From 38cb828f20de40136079ae53e1b1fa80554ba6ec Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 16:26:57 -0800 Subject: [PATCH 212/227] add private methods pragma mark to FBSDKRestrictiveDataFilterManager Summary: Add private methods pragma mark. No logic change. Reviewed By: joesus Differential Revision: D25670541 fbshipit-source-id: 9ccacf398b9ab61b2189abbb9cfa223f9bbe0769 --- .../FBSDKRestrictiveDataFilterManager.m | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m index 4bceefd88c..1ab3eb3390 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/Integrity/FBSDKRestrictiveDataFilterManager.m @@ -56,51 +56,18 @@ @implementation FBSDKRestrictiveDataFilterManager static NSMutableArray *_params; static NSMutableSet *_restrictedEvents; -+ (void)_updateFilters:(nullable NSDictionary *)restrictiveParams -{ - static NSString *const RESTRICTIVE_PARAM_KEY = @"restrictive_param"; - static NSString *const PROCESS_EVENT_NAME_KEY = @"process_event_name"; - - restrictiveParams = [FBSDKTypeUtility dictionaryValue:restrictiveParams]; - if (restrictiveParams.count > 0) { - @synchronized(self) { - [_params removeAllObjects]; - [_restrictedEvents removeAllObjects]; - NSMutableArray *eventFilterArray = [NSMutableArray array]; - NSMutableSet *restrictedEventSet = [NSMutableSet set]; - for (NSString *eventName in restrictiveParams.allKeys) { - NSDictionary *eventInfo = restrictiveParams[eventName]; - if (!eventInfo) { - continue; - } - if (eventInfo[RESTRICTIVE_PARAM_KEY]) { - FBSDKRestrictiveEventFilter *restrictiveEventFilter = [[FBSDKRestrictiveEventFilter alloc] initWithEventName:eventName - restrictiveParams:eventInfo[RESTRICTIVE_PARAM_KEY]]; - [FBSDKTypeUtility array:eventFilterArray addObject:restrictiveEventFilter]; - } - if (restrictiveParams[eventName][PROCESS_EVENT_NAME_KEY]) { - [restrictedEventSet addObject:eventName]; - } - } - _params = eventFilterArray; - _restrictedEvents = restrictedEventSet; - } - } -} - -+ (nullable NSString *)_getMatchedDataTypeWithEventName:(NSString *)eventName - paramKey:(NSString *)paramKey ++ (void)enable { - // match by params in custom events with event name - for (FBSDKRestrictiveEventFilter *filter in _params) { - if ([filter.eventName isEqualToString:eventName]) { - NSString *type = [FBSDKTypeUtility stringValue:filter.restrictiveParams[paramKey]]; - if (type) { - return type; + @try { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary *restrictiveParams = [FBSDKServerConfigurationManager cachedServerConfiguration].restrictiveParams; + if (restrictiveParams) { + [FBSDKRestrictiveDataFilterManager _updateFilters:restrictiveParams]; + g_isRestrictiveEventFilterEnabled = YES; } - } - } - return nil; + }); + } @catch (NSException *exception) {} } + (NSDictionary *)processParameters:(NSDictionary *)parameters @@ -156,21 +123,7 @@ + (void)processEvents:(NSMutableArray *> *)e } @catch (NSException *exception) {} } -+ (void)enable -{ - @try { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSDictionary *restrictiveParams = [FBSDKServerConfigurationManager cachedServerConfiguration].restrictiveParams; - if (restrictiveParams) { - [FBSDKRestrictiveDataFilterManager _updateFilters:restrictiveParams]; - g_isRestrictiveEventFilterEnabled = YES; - } - }); - } @catch (NSException *exception) {} -} - -#pragma mark Helper functions +#pragma mark - Private Methods + (BOOL)_isRestrictedEvent:(NSString *)eventName { @@ -179,4 +132,51 @@ + (BOOL)_isRestrictedEvent:(NSString *)eventName } } ++ (nullable NSString *)_getMatchedDataTypeWithEventName:(NSString *)eventName + paramKey:(NSString *)paramKey +{ + // match by params in custom events with event name + for (FBSDKRestrictiveEventFilter *filter in _params) { + if ([filter.eventName isEqualToString:eventName]) { + NSString *type = [FBSDKTypeUtility stringValue:filter.restrictiveParams[paramKey]]; + if (type) { + return type; + } + } + } + return nil; +} + ++ (void)_updateFilters:(nullable NSDictionary *)restrictiveParams +{ + static NSString *const RESTRICTIVE_PARAM_KEY = @"restrictive_param"; + static NSString *const PROCESS_EVENT_NAME_KEY = @"process_event_name"; + + restrictiveParams = [FBSDKTypeUtility dictionaryValue:restrictiveParams]; + if (restrictiveParams.count > 0) { + @synchronized(self) { + [_params removeAllObjects]; + [_restrictedEvents removeAllObjects]; + NSMutableArray *eventFilterArray = [NSMutableArray array]; + NSMutableSet *restrictedEventSet = [NSMutableSet set]; + for (NSString *eventName in restrictiveParams.allKeys) { + NSDictionary *eventInfo = restrictiveParams[eventName]; + if (!eventInfo) { + continue; + } + if (eventInfo[RESTRICTIVE_PARAM_KEY]) { + FBSDKRestrictiveEventFilter *restrictiveEventFilter = [[FBSDKRestrictiveEventFilter alloc] initWithEventName:eventName + restrictiveParams:eventInfo[RESTRICTIVE_PARAM_KEY]]; + [FBSDKTypeUtility array:eventFilterArray addObject:restrictiveEventFilter]; + } + if (restrictiveParams[eventName][PROCESS_EVENT_NAME_KEY]) { + [restrictedEventSet addObject:eventName]; + } + } + _params = eventFilterArray; + _restrictedEvents = restrictedEventSet; + } + } +} + @end From 45538d23ed768fefb1ef44cf389ec08b59b2afc7 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 16:26:57 -0800 Subject: [PATCH 213/227] private method pragma mark for FBSDKEventDeactivationManager Summary: as title Reviewed By: joesus Differential Revision: D25670700 fbshipit-source-id: 2f454b8e6bad550f5246dbb24fec32744ef246f9 --- .../FBSDKEventDeactivationManager.m | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m index 2e72a4faa9..41a3d04aa8 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/AppEvents/Internal/EventDeactivation/FBSDKEventDeactivationManager.m @@ -71,34 +71,6 @@ + (void)enable } @catch (NSException *exception) {} } -+ (void)_updateDeactivatedEvents:(nullable NSDictionary *)events -{ - events = [FBSDKTypeUtility dictionaryValue:events]; - if (events.count == 0) { - return; - } - [_deactivatedEvents removeAllObjects]; - [_eventsWithDeactivatedParams removeAllObjects]; - NSMutableArray *deactivatedParamsArray = [NSMutableArray array]; - NSMutableSet *deactivatedEventSet = [NSMutableSet set]; - for (NSString *eventName in events.allKeys) { - NSDictionary *eventInfo = [FBSDKTypeUtility dictionary:events objectForKey:eventName ofType:NSDictionary.class]; - if (!eventInfo) { - continue; - } - if (eventInfo[DEPRECATED_EVENT_KEY]) { - [deactivatedEventSet addObject:eventName]; - } - if (eventInfo[DEPRECATED_PARAM_KEY]) { - FBSDKDeactivatedEvent *eventWithDeactivatedParams = [[FBSDKDeactivatedEvent alloc] initWithEventName:eventName - deactivatedParams:[NSSet setWithArray:eventInfo[DEPRECATED_PARAM_KEY]]]; - [FBSDKTypeUtility array:deactivatedParamsArray addObject:eventWithDeactivatedParams]; - } - } - _deactivatedEvents = deactivatedEventSet; - _eventsWithDeactivatedParams = deactivatedParamsArray; -} - + (void)processEvents:(NSMutableArray *> *)events { @try { @@ -135,4 +107,34 @@ + (void)processEvents:(NSMutableArray *> *)events } } +#pragma mark - Private Method + ++ (void)_updateDeactivatedEvents:(nullable NSDictionary *)events +{ + events = [FBSDKTypeUtility dictionaryValue:events]; + if (events.count == 0) { + return; + } + [_deactivatedEvents removeAllObjects]; + [_eventsWithDeactivatedParams removeAllObjects]; + NSMutableArray *deactivatedParamsArray = [NSMutableArray array]; + NSMutableSet *deactivatedEventSet = [NSMutableSet set]; + for (NSString *eventName in events.allKeys) { + NSDictionary *eventInfo = [FBSDKTypeUtility dictionary:events objectForKey:eventName ofType:NSDictionary.class]; + if (!eventInfo) { + continue; + } + if (eventInfo[DEPRECATED_EVENT_KEY]) { + [deactivatedEventSet addObject:eventName]; + } + if (eventInfo[DEPRECATED_PARAM_KEY]) { + FBSDKDeactivatedEvent *eventWithDeactivatedParams = [[FBSDKDeactivatedEvent alloc] initWithEventName:eventName + deactivatedParams:[NSSet setWithArray:eventInfo[DEPRECATED_PARAM_KEY]]]; + [FBSDKTypeUtility array:deactivatedParamsArray addObject:eventWithDeactivatedParams]; + } + } + _deactivatedEvents = deactivatedEventSet; + _eventsWithDeactivatedParams = deactivatedParamsArray; +} + @end From e24ac63e89ff74886fd44d877f7854ba52a9b8dc Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 16:28:52 -0800 Subject: [PATCH 214/227] add prefix to private methods in FBSDKLibAnalyzer Summary: as title Reviewed By: joesus Differential Revision: D25671023 fbshipit-source-id: cf7e3cddb25ced093722cbefe1910f038d627666 --- .../Internal/Basics/FBSDKLibAnalyzerTests.m | 12 +++--- .../FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m | 42 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m index 7cf3355c5b..beb10efc8c 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/Basics/FBSDKLibAnalyzerTests.m @@ -23,9 +23,9 @@ @interface FBSDKLibAnalyzer () -+ (NSArray *)getClassNames:(NSArray *)prefixes - frameworks:(NSArray *)frameworks; -+ (NSString *)getAddress:(NSString *)callstackEntry; ++ (NSArray *)_getClassNames:(NSArray *)prefixes + frameworks:(NSArray *)frameworks; ++ (NSString *)_getAddress:(NSString *)callstackEntry; @end @@ -47,7 +47,7 @@ - (void)testGetMethodsTableFromPrefixesAndFrameworks @"FBSDKShareKit", @"FBSDKTVOSKit"]; id analyzerMock = [OCMockObject niceMockForClass:[FBSDKLibAnalyzer class]]; - [[analyzerMock expect] getClassNames:[OCMArg any] frameworks:[OCMArg any]]; + [[analyzerMock expect] _getClassNames:[OCMArg any] frameworks:[OCMArg any]]; NSDictionary *result = [FBSDKLibAnalyzer getMethodsTable:prefixes frameworks:frameworks]; XCTAssertNotNil(result); @@ -58,11 +58,11 @@ - (void)testGetMethodsTableFromPrefixesAndFrameworks - (void)testGetAddress { NSString *callstackEntry = @"0 CoreFoundation 0x0000000104cbd02e __exceptionPreprocess + 350"; - NSString *result1 = [FBSDKLibAnalyzer getAddress:callstackEntry]; + NSString *result1 = [FBSDKLibAnalyzer _getAddress:callstackEntry]; XCTAssertTrue([result1 isEqualToString:@"0x0000000104cbd02e"]); callstackEntry = @"0 CoreFoundation 0000000104cbd02e __exceptionPreprocess + 350"; - NSString *result2 = [FBSDKLibAnalyzer getAddress:callstackEntry]; + NSString *result2 = [FBSDKLibAnalyzer _getAddress:callstackEntry]; XCTAssertNil(result2); } diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m index 153617cc6c..d4fb42c38a 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m @@ -34,12 +34,12 @@ + (void)initialize + (NSDictionary *)getMethodsTable:(NSArray *)prefixes frameworks:(NSArray *)frameworks { - NSArray *allClasses = [self getClassNames:prefixes frameworks:frameworks]; + NSArray *allClasses = [self _getClassNames:prefixes frameworks:frameworks]; for (NSString *className in allClasses) { Class class = NSClassFromString(className); if (class) { - [self addClass:class isClassMethod:NO]; - [self addClass:object_getClass(class) isClassMethod:YES]; + [self _addClass:class isClassMethod:NO]; + [self _addClass:object_getClass(class) isClassMethod:YES]; } } @synchronized(_methodMapping) { @@ -49,13 +49,13 @@ + (void)initialize #pragma mark - private methods -+ (NSArray *)getClassNames:(NSArray *)prefixes - frameworks:(NSArray *)frameworks ++ (NSArray *)_getClassNames:(NSArray *)prefixes + frameworks:(NSArray *)frameworks { NSMutableArray *classNames = [NSMutableArray new]; // from main bundle - [classNames addObjectsFromArray:[self getClassesFrom:[[NSBundle mainBundle] executablePath] - prefixes:prefixes]]; + [classNames addObjectsFromArray:[self _getClassesFrom:[[NSBundle mainBundle] executablePath] + prefixes:prefixes]]; // from dynamic libraries if (frameworks.count > 0) { unsigned int count = 0; @@ -64,8 +64,8 @@ + (void)initialize NSString *image = [NSString stringWithUTF8String:images[i]]; for (NSString *framework in frameworks) { if ([image containsString:framework]) { - [classNames addObjectsFromArray:[self getClassesFrom:image - prefixes:nil]]; + [classNames addObjectsFromArray:[self _getClassesFrom:image + prefixes:nil]]; } } } @@ -75,8 +75,8 @@ + (void)initialize return [classNames copy]; } -+ (NSArray *)getClassesFrom:(NSString *)image - prefixes:(NSArray *)prefixes ++ (NSArray *)_getClassesFrom:(NSString *)image + prefixes:(NSArray *)prefixes { NSMutableArray *classNames = [NSMutableArray array]; unsigned int count = 0; @@ -98,8 +98,8 @@ + (void)initialize return [classNames copy]; } -+ (void)addClass:(Class)class - isClassMethod:(BOOL)isClassMethod ++ (void)_addClass:(Class)class + isClassMethod:(BOOL)isClassMethod { unsigned int methodsCount = 0; Method *methods = class_copyMethodList(class, &methodsCount); @@ -144,12 +144,12 @@ + (void)addClass:(Class)class NSMutableArray *symbolicatedCallstack = [NSMutableArray array]; for (NSUInteger i = 0; i < callstack.count; i++) { - NSString *rawAddress = [self getAddress:[FBSDKTypeUtility array:callstack objectAtIndex:i]]; + NSString *rawAddress = [self _getAddress:[FBSDKTypeUtility array:callstack objectAtIndex:i]]; if (rawAddress.length < 10) { continue; } NSString *addressString = [NSString stringWithFormat:@"0x%@", [rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]]; - NSString *methodAddress = [self searchMethod:addressString sortedAllAddress:sortedAllAddress]; + NSString *methodAddress = [self _searchMethod:addressString sortedAllAddress:sortedAllAddress]; if (methodAddress) { containsFBSDKFunction = YES; @@ -161,7 +161,7 @@ + (void)addClass:(Class)class if ([methodName containsString:@".cxx_destruct"]) { return nil; } - [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"%@%@", methodName, [self getOffset:addressString secondString:methodAddress]]]; + [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"%@%@", methodName, [self _getOffset:addressString secondString:methodAddress]]]; } else { nonSDKMethodCount++; } @@ -171,7 +171,7 @@ + (void)addClass:(Class)class return containsFBSDKFunction ? symbolicatedCallstack : nil; } -+ (nullable NSString *)getAddress:(nullable NSString *)callstackEntry ++ (nullable NSString *)_getAddress:(nullable NSString *)callstackEntry { if ([callstackEntry isKindOfClass:[NSString class]]) { NSArray *components = [callstackEntry componentsSeparatedByString:@" "]; @@ -184,8 +184,8 @@ + (nullable NSString *)getAddress:(nullable NSString *)callstackEntry return nil; } -+ (NSString *)getOffset:(NSString *)firstString - secondString:(NSString *)secondString ++ (NSString *)_getOffset:(NSString *)firstString + secondString:(NSString *)secondString { unsigned long long first = 0, second = 0; NSScanner *scanner = [NSScanner scannerWithString:firstString]; @@ -198,8 +198,8 @@ + (NSString *)getOffset:(NSString *)firstString return [NSString stringWithFormat:@"+%llu", difference]; } -+ (nullable NSString *)searchMethod:(NSString *)address - sortedAllAddress:(NSArray *)sortedAllAddress ++ (nullable NSString *)_searchMethod:(NSString *)address + sortedAllAddress:(NSArray *)sortedAllAddress { if (0 == sortedAllAddress.count) { return nil; From c1b3612fd4fa415a9d522effe1ceb457ed42d477 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Mon, 21 Dec 2020 16:28:52 -0800 Subject: [PATCH 215/227] group public/private methods in FBSDKLibAnalyzer Summary: as title Reviewed By: joesus Differential Revision: D25672109 fbshipit-source-id: cc28a7b20b34de0164535615f5ffb28f672025a1 --- .../FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m index d4fb42c38a..76312f2422 100644 --- a/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m +++ b/Sources/FBSDKCoreKit_Basics/FBSDKLibAnalyzer.m @@ -47,7 +47,49 @@ + (void)initialize } } -#pragma mark - private methods ++ (nullable NSArray *)symbolicateCallstack:(NSArray *)callstack + methodMapping:(NSDictionary *)methodMapping +{ + if (!callstack || !methodMapping) { + return nil; + } + NSArray *sortedAllAddress = [methodMapping.allKeys sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { + return [obj1 compare:obj2]; + }]; + + BOOL containsFBSDKFunction = NO; + NSInteger nonSDKMethodCount = 0; + NSMutableArray *symbolicatedCallstack = [NSMutableArray array]; + + for (NSUInteger i = 0; i < callstack.count; i++) { + NSString *rawAddress = [self _getAddress:[FBSDKTypeUtility array:callstack objectAtIndex:i]]; + if (rawAddress.length < 10) { + continue; + } + NSString *addressString = [NSString stringWithFormat:@"0x%@", [rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]]; + NSString *methodAddress = [self _searchMethod:addressString sortedAllAddress:sortedAllAddress]; + + if (methodAddress) { + containsFBSDKFunction = YES; + nonSDKMethodCount == 0 ?: [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"(%ld DEV METHODS)", (long)nonSDKMethodCount]]; + nonSDKMethodCount = 0; + NSString *methodName = [FBSDKTypeUtility dictionary:methodMapping objectForKey:methodAddress ofType:NSObject.class]; + + // filter out cxx_destruct + if ([methodName containsString:@".cxx_destruct"]) { + return nil; + } + [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"%@%@", methodName, [self _getOffset:addressString secondString:methodAddress]]]; + } else { + nonSDKMethodCount++; + } + } + nonSDKMethodCount == 0 ?: [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"(%ld DEV METHODS)", (long)nonSDKMethodCount]]; + + return containsFBSDKFunction ? symbolicatedCallstack : nil; +} + +#pragma mark - Private Methods + (NSArray *)_getClassNames:(NSArray *)prefixes frameworks:(NSArray *)frameworks @@ -129,48 +171,6 @@ + (void)_addClass:(Class)class free(methods); } -+ (nullable NSArray *)symbolicateCallstack:(NSArray *)callstack - methodMapping:(NSDictionary *)methodMapping -{ - if (!callstack || !methodMapping) { - return nil; - } - NSArray *sortedAllAddress = [methodMapping.allKeys sortedArrayUsingComparator:^NSComparisonResult (id _Nonnull obj1, id _Nonnull obj2) { - return [obj1 compare:obj2]; - }]; - - BOOL containsFBSDKFunction = NO; - NSInteger nonSDKMethodCount = 0; - NSMutableArray *symbolicatedCallstack = [NSMutableArray array]; - - for (NSUInteger i = 0; i < callstack.count; i++) { - NSString *rawAddress = [self _getAddress:[FBSDKTypeUtility array:callstack objectAtIndex:i]]; - if (rawAddress.length < 10) { - continue; - } - NSString *addressString = [NSString stringWithFormat:@"0x%@", [rawAddress substringWithRange:NSMakeRange(rawAddress.length - 10, 10)]]; - NSString *methodAddress = [self _searchMethod:addressString sortedAllAddress:sortedAllAddress]; - - if (methodAddress) { - containsFBSDKFunction = YES; - nonSDKMethodCount == 0 ?: [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"(%ld DEV METHODS)", (long)nonSDKMethodCount]]; - nonSDKMethodCount = 0; - NSString *methodName = [FBSDKTypeUtility dictionary:methodMapping objectForKey:methodAddress ofType:NSObject.class]; - - // filter out cxx_destruct - if ([methodName containsString:@".cxx_destruct"]) { - return nil; - } - [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"%@%@", methodName, [self _getOffset:addressString secondString:methodAddress]]]; - } else { - nonSDKMethodCount++; - } - } - nonSDKMethodCount == 0 ?: [FBSDKTypeUtility array:symbolicatedCallstack addObject:[NSString stringWithFormat:@"(%ld DEV METHODS)", (long)nonSDKMethodCount]]; - - return containsFBSDKFunction ? symbolicatedCallstack : nil; -} - + (nullable NSString *)_getAddress:(nullable NSString *)callstackEntry { if ([callstackEntry isKindOfClass:[NSString class]]) { From 8ff7d8c80f70fcc1ee90a72399ae2954789dd586 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 22 Dec 2020 09:17:39 -0800 Subject: [PATCH 216/227] General Maintenance Summary: Remove broken symlink Update header to work for building packages Reviewed By: tianqibt Differential Revision: D25676440 fbshipit-source-id: 0d374eeb24078f20b54bf10b8483f2b407156010 --- .../Internal/FBSDKGraphRequestConnectionProviding.h | 5 +++++ .../FBSDKLoginKit/include/FBSDKAuthenticationToken.h | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) delete mode 120000 FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h index a771c51ac6..a2dbabea00 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKGraphRequestConnectionProviding.h @@ -17,7 +17,12 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import + +#if SWIFT_PACKAGE +#import "FBSDKCoreKit.h" +#else #import +#endif NS_ASSUME_NONNULL_BEGIN diff --git a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h b/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h deleted file mode 120000 index a45d0a2fcc..0000000000 --- a/FBSDKLoginKit/FBSDKLoginKit/include/FBSDKAuthenticationToken.h +++ /dev/null @@ -1 +0,0 @@ -../FBSDKAuthenticationToken.h \ No newline at end of file From b4efcef56b3c925dfe9ff51f4b42ee41de673a70 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Tue, 22 Dec 2020 10:26:18 -0800 Subject: [PATCH 217/227] Remove unused domain const Summary: title. Make sure we always use facebook domain for public key & logout endpoint Reviewed By: joesus Differential Revision: D25673572 fbshipit-source-id: 17109ca0385a53c96b7549a12c3c4042f05a116b --- .../FBSDKAuthenticationStatusUtility.m | 21 ++++++------------- .../FBSDKAuthenticationTokenFactory.m | 1 - .../FBSDKAuthenticationTokenFactoryTests.m | 8 +++++++ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m index ccf25d4e9a..b57c9ea6f4 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationStatusUtility.m @@ -28,7 +28,6 @@ #import "FBSDKAuthenticationToken+Internal.h" -static NSString *const FBSDKFacebookDomain = @"facebook.com"; static NSString *const FBSDKOIDCStatusPath = @"/platform/oidc/status"; @implementation FBSDKAuthenticationStatusUtility @@ -82,21 +81,13 @@ + (NSURL *)_requestURL } NSDictionary *params = @{@"id_token" : token.tokenString}; - NSError *urlError; - NSString *host; + NSError *error; - if (FBSDKSettings.facebookDomainPart.length > 0) { - host = [NSString stringWithFormat:@"m.%@.%@", FBSDKSettings.facebookDomainPart, FBSDKFacebookDomain]; - } else { - host = [NSString stringWithFormat:@"m.%@", FBSDKFacebookDomain]; - } - - NSURL *requestURL = [FBSDKInternalUtility URLWithScheme:@"https" - host:host - path:FBSDKOIDCStatusPath - queryParameters:params - error:&urlError]; - return urlError == nil ? requestURL : nil; + NSURL *requestURL = [FBSDKInternalUtility unversionedFacebookURLWithHostPrefix:@"m" + path:FBSDKOIDCStatusPath + queryParameters:params + error:&error]; + return error == nil ? requestURL : nil; } + (void)_invalidateCurrentSession diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m index ebc34f0ac5..5a73592f86 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAuthenticationTokenFactory.m @@ -37,7 +37,6 @@ #import "FBSDKAuthenticationTokenClaims.h" #import "FBSDKSessionProviding.h" -static NSString *const FBSDKDefaultDomain = @"facebook.com"; static NSString *const FBSDKBeginCertificate = @"-----BEGIN CERTIFICATE-----"; static NSString *const FBSDKEndCertificate = @"-----END CERTIFICATE-----"; diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index d2e90822d2..df82b3a009 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -46,6 +46,8 @@ - (BOOL)verifySignature:(NSString *)signature certificateKey:(NSString *)key completion:(FBSDKVerifySignatureCompletionBlock)completion; - (NSDictionary *)claims; +- (NSURL *)_certificateEndpoint; + @end @interface FBSDKAuthenticationTokenClaims (Testing) @@ -292,6 +294,12 @@ - (void)testDecodeRandomHeader // MARK: - Verifying Signature +- (void)testCertificateEndpointURL +{ + NSURL *url = FBSDKAuthenticationTokenFactory.new._certificateEndpoint; + XCTAssertEqualObjects(url.absoluteString, @"https://m.facebook.com/.well-known/oauth/openid/certs/"); +} + - (void)testVerifySignatureWithoutDataWithoutResponseWithoutError { FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; From e32c08e34b678fa2a4c8d71b384eb3b375beebf1 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Tue, 22 Dec 2020 12:38:45 -0800 Subject: [PATCH 218/227] Add test for LoginCompletion.completeLoginWithHandler Summary: title Reviewed By: joesus Differential Revision: D25597761 fbshipit-source-id: 4cc11a74b1208d3b39846a9e30eba1b79ba7c771 --- .../FBSDKLoginCompletionTests.m | 182 ++++++++++++++++-- 1 file changed, 163 insertions(+), 19 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m index ea4b6ada93..bb0d39d8af 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -36,6 +36,12 @@ - (FBSDKLoginCompletionParameters *)parameters; - (void)exchangeNonceForTokenWithGraphRequestConnectionProvider:(id)connection handler:(FBSDKLoginCompletionParametersBlock)handler; +- (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler; + +- (void)fetchAndSetPropertiesForParameters:(nonnull FBSDKLoginCompletionParameters *)parameters + nonce:(nonnull NSString *)nonce + handler:(FBSDKLoginCompletionParametersBlock)handler; + @end @interface FBSDKLoginCompletionTests : XCTestCase @@ -45,6 +51,30 @@ @interface FBSDKLoginCompletionTests : XCTestCase @end +@interface FBSDKTestLoginURLCompleter : FBSDKLoginURLCompleter + +@property int exchangeNonceCount; + +@property int fetchAndSetAuthTokenCount; + +@end + +@implementation FBSDKTestLoginURLCompleter + +- (void)exchangeNonceForTokenWithHandler:(FBSDKLoginCompletionParametersBlock)handler +{ + _exchangeNonceCount += 1; +} + +- (void)fetchAndSetPropertiesForParameters:(nonnull FBSDKLoginCompletionParameters *)parameters + nonce:(nonnull NSString *)nonce + handler:(FBSDKLoginCompletionParametersBlock)handler +{ + _fetchAndSetAuthTokenCount += 1; +} + +@end + @implementation FBSDKLoginCompletionTests - (void)setUp @@ -76,8 +106,8 @@ - (void)setUp - (void)testInitWithAccessTokenWithIDToken { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"nonce", @"error", @"error_message"]]; + NSMutableDictionary *parameters = self.parametersWithIDtoken.mutableCopy; + [parameters addEntriesFromDictionary:self.parametersWithAccessToken]; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -86,8 +116,7 @@ - (void)testInitWithAccessTokenWithIDToken - (void)testInitWithAccessToken { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"id_token", @"nonce", @"error", @"error_message"]]; + NSDictionary *parameters = self.parametersWithAccessToken; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -96,8 +125,7 @@ - (void)testInitWithAccessToken - (void)testInitWithNonce { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"error", @"error_message"]]; + NSDictionary *parameters = self.parametersWithNonce; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -106,8 +134,7 @@ - (void)testInitWithNonce - (void)testInitWithIDToken { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token", @"expires", @"expires_at", @"expires_in", @"data_access_expiration_time", @"graph_domain", @"nonce", @"error", @"error_message"]]; + NSDictionary *parameters = self.parametersWithIDtoken; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -116,8 +143,7 @@ - (void)testInitWithIDToken - (void)testInitWithoutAccessTokenWithoutIDTokenWithoutNonce { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce", @"error", @"error_message"]]; + NSDictionary *parameters = self.parametersWithoutAccessTokenWithoutIDTokenWithoutNonce; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -126,11 +152,7 @@ - (void)testInitWithoutAccessTokenWithoutIDTokenWithoutNonce - (void)testInitWithEmptyAccessTokenWithEmptyIDTokenWithEmptyNonce { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"error", @"error_message"]]; - [parameters setValue:@"" forKey:@"access_token"]; - [parameters setValue:@"" forKey:@"id_token"]; - [parameters setValue:@"" forKey:@"nonce"]; + NSDictionary *parameters = self.parametersWithEmptyAccessTokenWithEmptyIDTokenWithEmptyNonce; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -144,10 +166,10 @@ - (void)testInitWithEmptyParameters [self verifyEmptyParameters:completer.parameters]; } -- (void)testInitWithBothIdTokenAndNonce +- (void)testInitWithIDTokenAndNonce { NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token"]]; + [parameters removeObjectForKey:@"access_token"]; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -156,8 +178,7 @@ - (void)testInitWithBothIdTokenAndNonce - (void)testInitWithError { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectsForKeys:@[@"access_token", @"id_token", @"nonce"]]; + NSDictionary *parameters = self.parametersWithError; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; @@ -350,6 +371,84 @@ - (void)testNonceExchangeWithRandomResults } } +// MARK: Completion + +- (void)testCompleteWithNonce +{ + FBSDKTestLoginURLCompleter *completer = [[FBSDKTestLoginURLCompleter alloc] initWithURLParameters:self.parametersWithNonce appID:_fakeAppID]; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *parameters) { + // do nothing + }; + + [completer completeLoginWithHandler:handler]; + + XCTAssertNil(completer.parameters.error); + XCTAssertEqual(completer.exchangeNonceCount, 1); + XCTAssertEqual(completer.fetchAndSetAuthTokenCount, 0); +} + +- (void)testCompleteWithAuthenticationTokenWithoutNonce +{ + FBSDKTestLoginURLCompleter *completer = [[FBSDKTestLoginURLCompleter alloc] initWithURLParameters:self.parametersWithIDtoken appID:_fakeAppID]; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *parameters) { + // do nothing + }; + + [completer completeLoginWithHandler:handler]; + + XCTAssertNotNil(completer.parameters.error); + XCTAssertEqual(completer.exchangeNonceCount, 0); + XCTAssertEqual(completer.fetchAndSetAuthTokenCount, 0); +} + +- (void)testCompleteWithAuthenticationTokenWithNonce +{ + FBSDKTestLoginURLCompleter *completer = [[FBSDKTestLoginURLCompleter alloc] initWithURLParameters:self.parametersWithIDtoken appID:_fakeAppID]; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *parameters) { + // do nothing + }; + + [completer completeLoginWithHandler:handler nonce:@"some_nonce"]; + + XCTAssertNil(completer.parameters.error); + XCTAssertEqual(completer.exchangeNonceCount, 0); + XCTAssertEqual(completer.fetchAndSetAuthTokenCount, 1); +} + +- (void)testCompleteWithAccessToken +{ + FBSDKTestLoginURLCompleter *completer = [[FBSDKTestLoginURLCompleter alloc] initWithURLParameters:self.parametersWithAccessToken appID:_fakeAppID]; + + __block BOOL wasCalled = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *parameters) { + wasCalled = YES; + }; + + [completer completeLoginWithHandler:handler nonce:@"some_nonce"]; + + XCTAssert(wasCalled, @"Handler should be invoked syncronously"); + XCTAssertNil(completer.parameters.error); + XCTAssertEqual(completer.exchangeNonceCount, 0); + XCTAssertEqual(completer.fetchAndSetAuthTokenCount, 0); +} + +- (void)testCompleteWithEmptyParameters +{ + FBSDKTestLoginURLCompleter *completer = [[FBSDKTestLoginURLCompleter alloc] initWithURLParameters:@{} appID:_fakeAppID]; + + __block BOOL wasCalled = NO; + FBSDKLoginCompletionParametersBlock handler = ^(FBSDKLoginCompletionParameters *parameters) { + wasCalled = YES; + }; + + [completer completeLoginWithHandler:handler nonce:@"some_nonce"]; + + XCTAssert(wasCalled, @"Handler should be invoked syncronously"); + XCTAssertNil(completer.parameters.error); + XCTAssertEqual(completer.exchangeNonceCount, 0); + XCTAssertEqual(completer.fetchAndSetAuthTokenCount, 0); +} + // MARK: Helpers - (NSError *)sampleError @@ -364,6 +463,51 @@ - (NSDictionary *)rawParametersWithMissingNonce return parameters; } +- (NSDictionary *)parametersWithNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"error", @"error_message"]]; + return parameters; +} + +- (NSDictionary *)parametersWithAccessToken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"nonce", @"error", @"error_message"]]; + return parameters; +} + +- (NSDictionary *)parametersWithIDtoken +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"access_token", @"nonce", @"error", @"error_message"]]; + return parameters; +} + +- (NSDictionary *)parametersWithoutAccessTokenWithoutIDTokenWithoutNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"nonce", @"error", @"error_message"]]; + return parameters; +} + +- (NSDictionary *)parametersWithEmptyAccessTokenWithEmptyIDTokenWithEmptyNonce +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"error", @"error_message"]]; + [parameters setValue:@"" forKey:@"access_token"]; + [parameters setValue:@"" forKey:@"id_token"]; + [parameters setValue:@"" forKey:@"nonce"]; + return parameters; +} + +- (NSDictionary *)parametersWithError +{ + NSMutableDictionary *parameters = _parameters.mutableCopy; + [parameters removeObjectsForKeys:@[@"id_token", @"access_token", @"nonce"]]; + return parameters; +} + - (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParameter:(NSDictionary *)urlParameters { XCTAssertEqualObjects(parameters.accessTokenString, urlParameters[@"access_token"]); From b5f34a1c486da2fc49cff33e0f62ca359ba1724d Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 22 Dec 2020 16:12:38 -0800 Subject: [PATCH 219/227] Audit Access Token Usages Summary: * Adds a couple checks in places where we may assume the presence of an access token. * Cleans up some documentation in LoginManager Reviewed By: ppansy Differential Revision: D25684128 fbshipit-source-id: 5ec2a3c6ff72bee5d9def41a3dbf27bc2b937b81 --- .../FBSDKGraphErrorRecoveryProcessor.m | 4 +- .../FBSDKGraphRequestPiggybackManager.m | 3 + .../FBSDKLoginKit/FBSDKLoginManager.h | 56 ++++++++++--------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m index 3ebc35b7b7..187acd972a 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m +++ b/FBSDKCoreKit/FBSDKCoreKit/GraphAPI/FBSDKGraphErrorRecoveryProcessor.m @@ -53,7 +53,7 @@ - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request deleg self.delegate = nil; return YES; case FBSDKGraphRequestErrorRecoverable: - if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { + if (request.tokenString && [request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { _recoveryAttempter = error.recoveryAttempter; // Set up a block to do the typical recovery work so that we can chain it for ios auth special cases. @@ -75,7 +75,7 @@ - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request deleg } return NO; case FBSDKGraphRequestErrorOther: - if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { + if (request.tokenString && [request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { NSString *message = error.userInfo[FBSDKErrorLocalizedDescriptionKey]; NSString *title = error.userInfo[FBSDKErrorLocalizedTitleKey]; if (message) { diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m index 871fc5e92f..14d84b35fe 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m @@ -47,6 +47,9 @@ + (void)addPiggybackRequests:(FBSDKGraphRequestConnection *)connection + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permissionHandler:(FBSDKGraphRequestBlock)permissionHandler { FBSDKAccessToken *expectedToken = [FBSDKAccessToken currentAccessToken]; + if (!expectedToken) { + return; + } __block NSMutableSet *permissions = nil; __block NSMutableSet *declinedPermissions = nil; __block NSMutableSet *expiredPermissions = nil; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h index b76e98e56c..e6b5aafd54 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h @@ -85,9 +85,7 @@ NS_SWIFT_NAME(LoginManagerLoginResultBlock); /** FBSDKDefaultAudience enum - Passed to open to indicate which default audience to use for sessions that post data to Facebook. - - + Passed to openURL to indicate which default audience to use for sessions that post data to Facebook. Certain operations such as publishing a status or publishing a photo require an audience. When the user grants an application permission to perform a publish operation, a default audience is selected as the @@ -107,14 +105,15 @@ typedef NS_ENUM(NSUInteger, FBSDKDefaultAudience) /** `FBSDKLoginManager` provides methods for logging the user in and out. - `FBSDKLoginManager` works directly with `[FBSDKAccessToken currentAccessToken]` and - sets the "currentAccessToken" upon successful authorizations (or sets `nil` in case of `logOut`). + `FBSDKLoginManager` serves to help manage sessions represented by tokens for authentication, + `AuthenticationToken`, and data access, `AccessToken`. - You should check `[FBSDKAccessToken currentAccessToken]` before calling logIn* to see if there is - a cached token available (typically in your viewDidLoad). + You should check if the type of token you expect is present as a singleton instance, either `AccessToken.current` + or `AuthenticationToken.current` before calling any of the login methods to see if there is a cached token + available. A standard place to do this is in `viewDidLoad`. - If you are managing your own token instances outside of "currentAccessToken", you will need to set - "currentAccessToken" before calling logIn* to authorize further permissions on your tokens. + @warning If you are managing your own token instances outside of `AccessToken.current`, you will need to set + `AccessToken.current` before calling any of the login methods to authorize further permissions on your tokens. */ NS_SWIFT_NAME(LoginManager) @interface FBSDKLoginManager : NSObject @@ -140,11 +139,10 @@ NS_SWIFT_NAME(LoginManager) @param handler the callback. Use this method when asking for read permissions. You should only ask for permissions when they - are needed and explain the value to the user. You can inspect the result.declinedPermissions to also - provide more information to the user if they decline permissions. - You typically should check if `[FBSDKAccessToken currentAccessToken]` - already contains the permissions you need before asking to reduce unnecessary app switching. For example, - you could make that check at viewDidLoad. + are needed and explain the value to the user. You can inspect the `FBSDKLoginManagerLoginResultBlock`'s + `result.declinedPermissions` to provide more information to the user if they decline permissions. + You typically should check if `AccessToken.current` already contains the permissions you need before + asking to reduce unnecessary login attempts. For example, you could perform that check in `viewDidLoad`. @warning You can only perform one login call at a time. Calling a login method before the completion handler is called on a previous login attempt will result in an error. @@ -158,14 +156,16 @@ NS_SWIFT_NAME(logIn(permissions:from:handler:)); /** Logs the user in or authorizes additional permissions. - @param viewController the view controller from which to present the login UI. + @param viewController the view controller from which to present the login UI. If nil, the topmost view + controller will be automatically determined and used. @param configuration the login configuration to use. @param completion the login completion handler. Use this method when asking for permissions. You should only ask for permissions when they - are needed and the value should be explained to the user. You can inspect the result's `declinedPermissions` to also - provide more information to the user if they decline permissions. - To reduce unnecessary app switching, you should typically check if `FBSDKAccessToken.currentAccessToken` + are needed and the value should be explained to the user. You can inspect the + `FBSDKLoginManagerLoginResultBlock`'s `result.declinedPermissions` to provide more information + to the user if they decline permissions. + To reduce unnecessary login attempts, you should typically check if `AccessToken.current` already contains the permissions you need. If it does, you probably do not need to call this method. @warning You can only perform one login call at a time. Calling a login method before the completion handler is called @@ -193,17 +193,19 @@ NS_SWIFT_NAME(logIn(url:handler:)); /** Requests user's permission to reathorize application's data access, after it has expired due to inactivity. - @param fromViewController the view controller to present from. If nil, the topmost view controller will be - automatically determined as best as possible. + @param fromViewController the view controller from which to present the login UI. If nil, the topmost view + controller will be automatically determined and used. @param handler the callback. - @warning This method will reauthorize using a `LoginConfiguration` with `FBSDKLoginTracking` set to `.enabled`. +Use this method when you need to reathorize your app's access to user data via the Graph API. +You should only call this after access has expired. +You should provide as much context to the user as possible as to why you need to reauthorize the access, the +scope of access being reathorized, and what added value your app provides when the access is reathorized. +You can inspect the `result.declinedPermissions` to determine if you should provide more information to the +user based on any declined permissions. -Use this method when you need to reathorize your app's access to user data via Graph API, after such an access has expired. -You should provide as much context to the user as possible as to why you need to reauthorize the access, the scope of -access being reathorized, and what added value your app provides when the access is reathorized. -You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. -This method will present UI the user. You typically should call this if `[FBSDKAccessToken isDataAccessExpired]` returns true. + @warning This method will reauthorize using a `LoginConfiguration` with `FBSDKLoginTracking` set to `.enabled`. + @warning This method will present UI the user. You typically should call this if `AccessToken.isDataAccessExpired` is true. */ - (void)reauthorizeDataAccess:(UIViewController *)fromViewController handler:(FBSDKLoginManagerLoginResultBlock)handler @@ -212,7 +214,7 @@ NS_SWIFT_NAME(reauthorizeDataAccess(from:handler:)); /** Logs the user out - This nils out the singleton instances of `FBSDKAccessToken` `FBSDKAuthenticationToken` and `FBSDKProfle`. + This nils out the singleton instances of `AccessToken` `AuthenticationToken` and `Profle`. @note This is only a client side logout. It will not log the user out of their Facebook account. */ From d03348b3911593c60f2e756d2dc77460a9f4f3cb Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Tue, 22 Dec 2020 16:12:38 -0800 Subject: [PATCH 220/227] Harden Unit Tests for Signature Verification Summary: Adds a couple missing test cases for invalid and mangled certificates. Reviewed By: ppansy Differential Revision: D25685406 fbshipit-source-id: 82529a1ac029ca9fc953b131150ef75cefec381b --- .../FBSDKAuthenticationTokenFactoryTests.m | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m index df82b3a009..38326043d2 100644 --- a/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m +++ b/FBSDKCoreKit/FBSDKCoreKitTests/Internal/FBSDKAuthenticationTokenFactoryTests.m @@ -24,7 +24,8 @@ #import "FBSDKSessionProviding.h" #import "FBSDKTestCase.h" -static NSString *const _certificate = @"MIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE="; +static NSString *const _certificate = @"-----BEGIN CERTIFICATE-----\nMIIDgjCCAmoCCQDMso+U6N9AMjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wHhcNMjAxMTAzMDAzNTI1WhcNMzAxMTAxMDAzNTI1WjCBgjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxlMREwDwYDVQQKDAhGYWNlYm9vazEMMAoGA1UECwwDRW5nMRIwEAYDVQQDDAlwYW5zeTA0MTkxHzAdBgkqhkiG9w0BCQEWEHBhbnN5MDQxOUBmYi5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD0R8/zzuJ5SM+8KBgshg+sKARfm4Ad7Qv7Vi0L8xoXpReXxefDHF7jI9o6pLsp5OIEmnhRjTlbdT7APK1pZ8dHjOdod6xWSoQigUplYOqa5iuVx7IqD15PUhx6/LqcAtHFKDtKOPuIc8CqkmVUyGRMq2OxdCoiWix5z79pSDILmlRWsn4UOCpFU/Ix75YL/JD19IHgwgh4XCxDwUVhmpgG+jI5l9a3ZCBx7JwZAoJ/Z/OpVbguAlBnxIpi8Qk5VKdHzLHvkrdGXGFMzao6bReXX3KNrYrurAgd7fD2TAQo8EH5rgB7ewxtCIlHRoXJPSdVKpTPwx4c7Mfu2EMpx66pAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAPKMCK6mlLIFxMvIa4lT3fYY+APPhMazHtiPJ+279dkhzGmugD3x+mWvd+OzdmWlW/bvZWLbG3UXA166FK8ZcYyuTYdhCxP3vRNqBWNC65qURnIYyUK2DT09WrvBWLZqhv/mJFfijnGqvkKA1k3rVtgCGNDEnezmC9uuO8P17y3+/RZY8dBfvd8lkdCyTCFnKHNyKAE83qnqAJwgbc7cv7IKwAYsDdr4u38GFayBdTzCatTVrQDTYZbJDJLx+BcvHw8pdhthsX7wpGbFH5++Y5G4hRF2vGenzLFIHthxFnpgiZO3VjloPB57awA4jmJY9DjsOZNhZT+RbnCO9AQlCZE=\n-----END CERTIFICATE-----"; +static NSString *const _incorrectCertificate = @"-----BEGIN CERTIFICATE-----\nMIIDATCCAemgAwIBAgIJAO+h3vH3X1puMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV\nBAMMDGZhY2Vib29rLmNvbTAeFw0yMDExMTAwMTUzMTFaFw0yMTA1MDkwMTUzMTFa\nMBcxFTATBgNVBAMMDGZhY2Vib29rLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP\nADCCAQoCggEBAOZH/FVV1nsdlg6vhjuQlK8VYbN7F+aFAnkMFKQV+MQ88qj/zyBS\nAGZy5MTB3zHjCjw0IhJxTYoESxLy12T7UWqM7ltyKgEO0d8lLbIXR07QWziMd1Q+\n1AlTG9Yj6cMzQGFceB9x09MrOz/Gg+YrIzuRI2TXCaDW7j4LBhqLAlVrK8aMOVHJ\nFDWVCxuwdSNuJ+FNo/bvUqAWVQtn7KNoOcbot5Y4KAVQ16nufH0dJtRcOHzNELYB\nbxmtLWC8eKNn3H8Yw4whZV2BCVZJ/dQ1HZVlSktSs1wE5amg4wm3rHffyN1fpTah\nvN6bjMCQHrpBH2r0BSrkai/joh2ZeWZC068CAwEAAaNQME4wHQYDVR0OBBYEFIYZ\nJeio2kloli49hq+idEeGz3WwMB8GA1UdIwQYMBaAFIYZJeio2kloli49hq+idEeG\nz3WwMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADU9ODtwRL7YDCJ6\naem7juewkgnXx48Tzcl6JtJijIl+IK0Phzb9r/GYrSC+H/N5rWCK5Ur55owXidb9\nXuLysM9xfHBUv91BK03XpevA0bwXCfRk0KPgyc744b8Qb636QiUOzF2aQTYxXbSF\nmXj1HdREsKow0202LfhjKtQWbL+7Q3lpiOFFOkkEVCBu42LT/Ix8VuL/RF3I2xS0\nBhO7FK6Y+ppw33lcmwfP7lLROpeowZA1WeF6tDsqBYivGg8G+9abAMnW0s4ZZSGD\ncDpGIcIlBRhr4nNo0u11BYuxcY8fukYkHvDYygrNhLVNme7JO3Iix7SOyxeMgT9t\ntBi+u9M=\n-----END CERTIFICATE-----"; static NSString *const _encodedHeader = @"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9"; static NSString *const _encodedClaims = @"eyJzdWIiOiIxMjM0IiwibmFtZSI6IlRlc3QgVXNlciIsImlzcyI6Imh0dHBzOi8vZmFjZWJvb2suY29tL2RpYWxvZy9vYXV0aCIsImF1ZCI6IjQzMjEiLCJub25jZSI6InNvbWVfbm9uY2UiLCJleHAiOjE1MTYyNTkwMjIsImVtYWlsIjoiZW1haWxAZW1haWwuY29tIiwicGljdHVyZSI6Imh0dHBzOi8vd3d3LmZhY2Vib29rLmNvbS9zb21lX3BpY3R1cmUiLCJpYXQiOjE1MTYyMzkwMjJ9"; static NSString *const _signature = @"rTaqfx5Dz0UbzxZ3vBhitgtetWKBJ3-egz5n6l4ngLYqQ7ywapDvS7cM1NRGAh9drT8QeoxKPm0H_1B1LJBNyx-Fiseetfs7XANuocwTx9k7so3bi_EW0V-RYoDTgg5asS9Ra2qYM829xMYkhBHXp1HwHo0uHz1tafQ1hTsxtzH29t23_EnPpnVx5jvu-UeAEL4Q7VeIIfkweQYzuT3cowWAs-Vhyvl9I39Z4Uh_3ZhkpBJW1CblPW3ekHoySC61qwePM9Fk0q3N7K45LtktIMR5biV0RvJceTGOssHGhjaQ3hzpRq318MZKfBtg6C-Ryhh8SmOkuDrrj-VNdoVHKg"; @@ -449,6 +450,42 @@ - (void)testVerifySignatureWithValidDataWithValidResponseWithoutError XCTAssertTrue(wasCalled); } +- (void)testVerifySignatureWithInvalidCertificates +{ + NSArray *certificates = @[ + [self mangledCertificateData], + [self validIncorrectCertificateData] + ]; + + for (NSData *certificateData in certificates) { + FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; + FakeSessionProvider *session = [FakeSessionProvider new]; + session.data = certificateData; + session.urlResponse = [[NSHTTPURLResponse alloc] initWithURL:self.sampleURL statusCode:200 HTTPVersion:nil headerFields:nil]; + session.stubbedDataTask = dataTask; + FBSDKAuthenticationTokenFactory *factory = [[FBSDKAuthenticationTokenFactory alloc] initWithSessionProvider:session]; + + __block BOOL wasCalled = NO; + [factory verifySignature:_signature + header:_encodedHeader + claims:_encodedClaims + certificateKey:_certificateKey + completion:^(BOOL success) { + XCTAssertFalse( + success, + "Should not verify a signature for an incorrect or invalid certificate" + ); + wasCalled = YES; + }]; + XCTAssertEqual( + dataTask.resumeCallCount, + 1, + "Should start the session data task when verifying a signature" + ); + XCTAssertTrue(wasCalled); + } +} + - (void)testVerifySignatureWithFuzzyData { FakeSessionDataTask *dataTask = [FakeSessionDataTask new]; @@ -521,11 +558,30 @@ - (NSDictionary *)validRawCertificateResponse }; } +- (NSData *)mangledCertificateData +{ + NSString *mangledCertificate = [_certificate stringByReplacingOccurrencesOfString:@"a" withString:@"b"]; + NSDictionary *certificates = @{ + _certificateKey : mangledCertificate + }; + + return [FBSDKTypeUtility dataWithJSONObject:certificates options:0 error:nil]; +} + - (NSData *)validCertificateData { return [FBSDKTypeUtility dataWithJSONObject:self.validRawCertificateResponse options:0 error:nil]; } +- (NSData *)validIncorrectCertificateData +{ + NSDictionary *certificates = @{ + _certificateKey : _incorrectCertificate + }; + + return [FBSDKTypeUtility dataWithJSONObject:certificates options:0 error:nil]; +} + - (NSURL *)sampleURL { return [NSURL URLWithString:@"https://example.com"]; From 86f587d62e5647b01079944d268d8d6d8f4db4b8 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 23 Dec 2020 11:01:06 -0800 Subject: [PATCH 221/227] Improve error message for no-nonce check Summary: Before we return cancelled if nonce and id_token are returned together. An error with decription would probably be better in this case Reviewed By: joesus Differential Revision: D25685126 fbshipit-source-id: d4a65555331777fe105b90be11338ff8c38969e5 --- .../FBSDKLoginKit/Internal/FBSDKLoginCompletion.m | 9 ++++++++- .../FBSDKLoginKitTests/FBSDKLoginCompletionTests.m | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 138e876aec..38fa264edc 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -82,8 +82,15 @@ - (instancetype)initWithURLParameters:(NSDictionary *)parameters if (hasNonEmptyAccessTokenString || (hasEitherNonceOrIdToken && !hasBothNonceAndIdToken)) { [self setParametersWithDictionary:parameters appID:appID]; - } else { + } else if ([FBSDKTypeUtility dictionary:parameters objectForKey:@"error" ofType:NSString.class] || [FBSDKTypeUtility dictionary:parameters objectForKey:@"error_message" ofType:NSString.class]) { [self setErrorWithDictionary:parameters]; + } else if (hasBothNonceAndIdToken) { + // If a nonce is present in the parameter we assume that + // user logged in by app switching. + // Currently OIDC is not supported for app switching. We + // will treat the login attempt as invalid if an ID token + // if returned together with nonce. + _parameters.error = [FBSDKError errorWithCode:FBSDKLoginErrorUnknown message:@"Invalid server response. Please try to login again"]; } } return self; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m index bb0d39d8af..905560c946 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -168,8 +168,8 @@ - (void)testInitWithEmptyParameters - (void)testInitWithIDTokenAndNonce { - NSMutableDictionary *parameters = _parameters.mutableCopy; - [parameters removeObjectForKey:@"access_token"]; + NSMutableDictionary *parameters = self.parametersWithIDtoken.mutableCopy; + [parameters addEntriesFromDictionary:self.parametersWithNonce]; FBSDKLoginURLCompleter *completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:parameters appID:_fakeAppID]; From 93c3a99e29bf87bfa79e4e4b018b9de19e4ceb1f Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 23 Dec 2020 15:17:51 -0800 Subject: [PATCH 222/227] Improve error message for reauthrozieDataAccess Summary: title Reviewed By: joesus Differential Revision: D25687263 fbshipit-source-id: 25d01e93e608a5f257107c27a429983de2261e3d --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 2fa9e9ca29..99853b6e35 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -479,10 +479,11 @@ - (NSDictionary *)logInParametersFromURL:(NSURL *)url - (void)reauthorizeDataAccess:(FBSDKLoginManagerLoginResultBlock)handler { if (!FBSDKAccessToken.currentAccessToken) { - NSError *error = [NSError errorWithDomain:FBSDKLoginErrorDomain - code:FBSDKLoginErrorMissingAccessToken - userInfo:nil]; - [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Must have an access token for which to reauthorize data access"]; + NSString *errorMessage = @"Must have an access token for which to reauthorize data access"; + NSError *error = [FBSDKError errorWithDomain:FBSDKLoginErrorDomain + code:FBSDKLoginErrorMissingAccessToken + message:errorMessage]; + [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:errorMessage]; handler(nil, error); return; } From d5a6c7f8454d64045e0e625a7952180888e0fa77 Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 23 Dec 2020 15:26:27 -0800 Subject: [PATCH 223/227] Add gaming basic permissions Summary: Allow gaming basic permissions(gaming_profile, gaming_user_picture) for Limited Login Reviewed By: joesus Differential Revision: D25697203 fbshipit-source-id: 33729009e2ca935834b9540414d83fec0807424d --- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h | 4 ++-- FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h index 9f905d2970..00e849ec8b 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h @@ -49,7 +49,7 @@ NS_SWIFT_NAME(LoginConfiguration) Attempts to initialize a new configuration with the expected parameters. @param permissions the requested permissions for a login attempt. Permissions must be an array of strings that do not contain whitespace. - The only permissions allowed when the `loginTracking` is `.limited` are 'email' and 'public_profile'. + The only permissions allowed when the `loginTracking` is `.limited` are 'email', 'public_profile', 'gaming_profile' and 'gaming_user_picture' @param tracking the tracking preference to use for a login attempt. @param nonce an optional nonce to use for the login attempt. A valid nonce must be a non-empty string without whitespace. Creation of the configuration will fail if the nonce is invalid. @@ -63,7 +63,7 @@ NS_REFINED_FOR_SWIFT; Attempts to initialize a new configuration with the expected parameters. @param permissions the requested permissions for the login attempt. Permissions must be an array of strings that do not contain whitespace. - The only permissions allowed when the `loginTracking` is `.limited` are 'email' and 'public_profile'. + The only permissions allowed when the `loginTracking` is `.limited` are 'email', 'public_profile', 'gaming_profile' and 'gaming_user_picture' @param tracking the tracking preference to use for a login attempt. */ - (nullable instancetype)initWithPermissions:(NSArray *)permissions diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m index 1b7b60d081..f14049d280 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m @@ -61,7 +61,7 @@ - (nullable instancetype)initWithPermissions:(NSArray *)permissions forTrackingPreference:tracking]; if (!arePermissionsValid) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors - formatString:@"Invalid combination of permissions and tracking preference provided to login configuration. The only permissions allowed when `tracking` is `.limited` are 'email' and 'public_profile'. Returning nil."]; + formatString:@"Invalid combination of permissions and tracking preference provided to login configuration. The only permissions allowed when `tracking` is `.limited` are 'email', 'public_profile', 'gaming_profile' and 'gaming_user_picture'. Returning nil."]; return nil; } @@ -90,7 +90,12 @@ + (BOOL)_arePermissionsValid:(NSSet *)permissions { switch (tracking) { case FBSDKLoginTrackingLimited: { - NSSet *validPermissions = [NSSet setWithArray:@[@"email", @"public_profile"]]; + NSSet *validPermissions = [NSSet setWithArray:@[ + @"email", + @"public_profile", + @"gaming_profile", + @"gaming_user_picture", + ]]; NSSet *combined = [permissions setByAddingObjectsFromSet:validPermissions]; return (permissions.count == 0) || (combined.count <= validPermissions.count); From b37b275c58bd62d8c833e70568ba3b6d6d4ebda9 Mon Sep 17 00:00:00 2001 From: Joe Susnick Date: Mon, 28 Dec 2020 10:54:07 -0800 Subject: [PATCH 224/227] Fix cancellation bug Summary: Makes token associated type optional on Swift `LoginResult` Reviewed By: ppansy Differential Revision: D25698171 fbshipit-source-id: d55e3f10edb9fdee116cfd88f98f507e33037d45 --- FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift index d4fbe18804..301e8e1892 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift +++ b/FBSDKLoginKit/FBSDKLoginKit/Swift/LoginManager.swift @@ -30,7 +30,7 @@ public typealias LoginResultBlock = (LoginResult) -> Void @available(tvOS, unavailable) public enum LoginResult { /// User succesfully logged in. Contains granted, declined permissions and access token. - case success(granted: Set, declined: Set, token: FBSDKCoreKit.AccessToken) + case success(granted: Set, declined: Set, token: FBSDKCoreKit.AccessToken?) /// Login attempt was cancelled by the user. case cancelled /// Login attempt failed. @@ -42,14 +42,14 @@ public enum LoginResult { return } - guard !result.isCancelled, let token = result.token else { + guard !result.isCancelled else { self = .cancelled return } let granted: Set = Set(result.grantedPermissions.map { Permission(stringLiteral: $0) }) let declined: Set = Set(result.declinedPermissions.map { Permission(stringLiteral: $0) }) - self = .success(granted: granted, declined: declined, token: token) + self = .success(granted: granted, declined: declined, token: result.token) } } From b96607c1f4d82d5f9043d34bac4076c209d7b31d Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Tue, 29 Dec 2020 10:55:04 -0800 Subject: [PATCH 225/227] add prefix to private methods in FBSDKErrorReport Summary: as title Reviewed By: joesus Differential Revision: D25687409 fbshipit-source-id: 94d662b7132856af7760b5f4c0797b7c1bff0964 --- .../Instrument/ErrorReport/FBSDKErrorReport.m | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m index a39661867f..0fa89742d7 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m @@ -47,18 +47,18 @@ + (void)enable } } directoryPath = dirPath; - [self uploadError]; + [self _uploadError]; [FBSDKError enableErrorReport]; } -+ (void)uploadError ++ (void)_uploadError { if ([FBSDKSettings isDataProcessingRestricted]) { return; } - NSArray *> *errorReports = [self loadErrorReports]; + NSArray *> *errorReports = [self _loadErrorReports]; if ([errorReports count] == 0) { - return [self clearErrorInfo]; + return [self _clearErrorInfo]; } NSData *jsonData = [FBSDKTypeUtility dataWithJSONObject:errorReports options:0 error:nil]; if (!jsonData) { @@ -71,7 +71,7 @@ + (void)uploadError [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error && [result isKindOfClass:[NSDictionary class]] && result[@"success"]) { - [self clearErrorInfo]; + [self _clearErrorInfo]; } }]; } @@ -81,14 +81,14 @@ + (void)saveError:(NSInteger)errorCode message:(nullable NSString *)message { NSString *timestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; - [self saveErrorInfoToDisk:@{ + [self _saveErrorInfoToDisk:@{ kFBSDKErrorCode : @(errorCode), kFBSDKErrorDomain : errorDomain, kFBSDKErrorTimestamp : timestamp, }]; } -+ (NSArray *> *)loadErrorReports ++ (NSArray *> *)_loadErrorReports { NSMutableArray *> *errorReportArr = [NSMutableArray array]; NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:NULL]; @@ -119,7 +119,7 @@ + (void)saveError:(NSInteger)errorCode return [errorReportArr copy]; } -+ (void)clearErrorInfo ++ (void)_clearErrorInfo { NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil]; for (NSUInteger i = 0; i < files.count; i++) { @@ -131,16 +131,16 @@ + (void)clearErrorInfo #pragma mark - disk operations -+ (void)saveErrorInfoToDisk:(NSDictionary *)errorInfo ++ (void)_saveErrorInfoToDisk:(NSDictionary *)errorInfo { if (errorInfo.count > 0) { NSData *data = [FBSDKTypeUtility dataWithJSONObject:errorInfo options:0 error:nil]; - [data writeToFile:[self pathToErrorInfoFile] + [data writeToFile:[self _pathToErrorInfoFile] atomically:YES]; } } -+ (NSString *)pathToErrorInfoFile ++ (NSString *)_pathToErrorInfoFile { NSString *timestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; return [directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"error_report_%@.json", timestamp]]; From b8129b9899f01cce79848ba9739e314d9d3401c8 Mon Sep 17 00:00:00 2001 From: Tianqi Li Date: Tue, 29 Dec 2020 10:55:04 -0800 Subject: [PATCH 226/227] group private methods in FBSDKErrorReport Summary: as title Reviewed By: joesus Differential Revision: D25687639 fbshipit-source-id: 218fd5027bd7ae2ba97a8572b74854092ac7a090 --- .../Instrument/ErrorReport/FBSDKErrorReport.m | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m index 0fa89742d7..314689ebd2 100644 --- a/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m +++ b/FBSDKCoreKit/FBSDKCoreKit/Internal/Instrument/ErrorReport/FBSDKErrorReport.m @@ -36,7 +36,7 @@ @implementation FBSDKErrorReport NSString *const kFBSDKErrorDomain = @"domain"; NSString *const kFBSDKErrorTimestamp = @"timestamp"; -# pragma mark - Class Methods +# pragma mark - Public Methods + (void)enable { @@ -51,6 +51,20 @@ + (void)enable [FBSDKError enableErrorReport]; } ++ (void)saveError:(NSInteger)errorCode + errorDomain:(NSErrorDomain)errorDomain + message:(nullable NSString *)message +{ + NSString *timestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; + [self _saveErrorInfoToDisk:@{ + kFBSDKErrorCode : @(errorCode), + kFBSDKErrorDomain : errorDomain, + kFBSDKErrorTimestamp : timestamp, + }]; +} + +#pragma mark - Private Methods + + (void)_uploadError { if ([FBSDKSettings isDataProcessingRestricted]) { @@ -76,18 +90,6 @@ + (void)_uploadError }]; } -+ (void)saveError:(NSInteger)errorCode - errorDomain:(NSErrorDomain)errorDomain - message:(nullable NSString *)message -{ - NSString *timestamp = [NSString stringWithFormat:@"%.0lf", [[NSDate date] timeIntervalSince1970]]; - [self _saveErrorInfoToDisk:@{ - kFBSDKErrorCode : @(errorCode), - kFBSDKErrorDomain : errorDomain, - kFBSDKErrorTimestamp : timestamp, - }]; -} - + (NSArray *> *)_loadErrorReports { NSMutableArray *> *errorReportArr = [NSMutableArray array]; @@ -129,8 +131,6 @@ + (void)_clearErrorInfo } } -#pragma mark - disk operations - + (void)_saveErrorInfoToDisk:(NSDictionary *)errorInfo { if (errorInfo.count > 0) { From c22af591f2f074098bd9bc35a1d4f0a0443f605d Mon Sep 17 00:00:00 2001 From: Pansy Pan Date: Wed, 30 Dec 2020 11:21:33 -0800 Subject: [PATCH 227/227] Add strongly typed permissions Summary: enforce permission to be consist of only lowercase letter and "_" Reviewed By: joesus Differential Revision: D25682243 fbshipit-source-id: eb74e2532163dbcfc3f27e4ce0ef8b11e2c60a2c --- .../FBSDKLoginKit.xcodeproj/project.pbxproj | 16 ++ .../FBSDKLoginKit/FBSDKLoginConfiguration.h | 4 +- .../FBSDKLoginKit/FBSDKLoginConfiguration.m | 21 +- .../FBSDKLoginKit/FBSDKLoginManager.m | 190 +++++++++--------- .../Internal/FBSDKLoginCompletion.h | 7 +- .../Internal/FBSDKLoginCompletion.m | 7 +- .../Internal/FBSDKLoginKit+Internal.h | 1 + .../Internal/FBSDKLoginManager+Internal.h | 3 +- .../FBSDKLoginKit/Internal/FBSDKPermission.h | 56 ++++++ .../FBSDKLoginKit/Internal/FBSDKPermission.m | 93 +++++++++ .../FBSDKLoginCompletionTests.m | 6 +- .../FBSDKLoginKitTests-Bridging-Header.h | 2 + .../FBSDKLoginKitTests/FBSDKPermissionTests.m | 96 +++++++++ .../LoginConfigurationTests.swift | 2 +- 14 files changed, 390 insertions(+), 114 deletions(-) create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.h create mode 100644 FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.m create mode 100644 FBSDKLoginKit/FBSDKLoginKitTests/FBSDKPermissionTests.m diff --git a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj index 0e8bf6e1a8..2d1927c576 100644 --- a/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj +++ b/FBSDKLoginKit/FBSDKLoginKit.xcodeproj/project.pbxproj @@ -130,6 +130,9 @@ 9DDFBB721A829503006C9208 /* FBSDKTooltipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DDFBB701A829503006C9208 /* FBSDKTooltipView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DDFBB731A829503006C9208 /* FBSDKTooltipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */; }; 9DEE5C941A671B5500D750E1 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DEE5C931A671B5500D750E1 /* XCTest.framework */; }; + C60390CB2592DB5800F9247E /* FBSDKPermission.h in Headers */ = {isa = PBXBuildFile; fileRef = C6E1332B259173AF00B611C6 /* FBSDKPermission.h */; }; + C60390D32592DB5B00F9247E /* FBSDKPermission.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E1333E259174A500B611C6 /* FBSDKPermission.m */; }; + C60390DC2592F40200F9247E /* FBSDKPermissionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C60390DB2592F40200F9247E /* FBSDKPermissionTests.m */; }; C625B49C24F97DF0003DCE23 /* FBSDKReferralManagerLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */; }; C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */; }; C6470B1024F44C0100E7AEF7 /* FBSDKReferralManagerResult.h in Headers */ = {isa = PBXBuildFile; fileRef = C68C1C6024F074FD005067E1 /* FBSDKReferralManagerResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -147,6 +150,8 @@ C6CE2BC324EB73B500CF2EB6 /* FBSDKReferralManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C6CE2BB424EB72F200CF2EB6 /* FBSDKReferralManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; C6CE2BC424EB73CF00CF2EB6 /* FBSDKReferralManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C6CE2BBE24EB72F200CF2EB6 /* FBSDKReferralManager.m */; }; C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */; }; + C6E1332C259173B000B611C6 /* FBSDKPermission.h in Headers */ = {isa = PBXBuildFile; fileRef = C6E1332B259173AF00B611C6 /* FBSDKPermission.h */; }; + C6E1333F259174A500B611C6 /* FBSDKPermission.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E1333E259174A500B611C6 /* FBSDKPermission.m */; }; C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */; }; F40BFD56257852E5007B85AC /* LoginButtonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40BFD55257852E5007B85AC /* LoginButtonTests.swift */; }; F462DC0E23B958E000FFCECA /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D9DB8DE1A114E500086167B /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -391,6 +396,7 @@ 9DDFBB701A829503006C9208 /* FBSDKTooltipView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKTooltipView.h; sourceTree = ""; }; 9DDFBB711A829503006C9208 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKTooltipView.m; sourceTree = ""; }; 9DEE5C931A671B5500D750E1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + C60390DB2592F40200F9247E /* FBSDKPermissionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPermissionTests.m; sourceTree = ""; }; C632597224EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerTests.m; sourceTree = ""; }; C67DC40E25882263004D7E43 /* FBSDKLoginCompletionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKLoginCompletionTests.m; sourceTree = ""; }; C681486124F866EA004EED1A /* FBSDKReferralCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralCode.h; sourceTree = ""; }; @@ -401,6 +407,8 @@ C6CE2BBE24EB72F200CF2EB6 /* FBSDKReferralManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManager.m; sourceTree = ""; }; C6CE2BC124EB732C00CF2EB6 /* FBSDKReferralManager+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FBSDKReferralManager+Internal.h"; sourceTree = ""; }; C6DB850624F87F7B0004DB85 /* FBSDKReferralCodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralCodeTests.m; sourceTree = ""; }; + C6E1332B259173AF00B611C6 /* FBSDKPermission.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKPermission.h; sourceTree = ""; }; + C6E1333E259174A500B611C6 /* FBSDKPermission.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKPermission.m; sourceTree = ""; }; C6E63D2224F8219A0015FC7C /* FBSDKReferralManagerLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSDKReferralManagerLogger.h; sourceTree = ""; }; C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKReferralManagerLogger.m; sourceTree = ""; }; F40BFD55257852E5007B85AC /* LoginButtonTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginButtonTests.swift; sourceTree = ""; }; @@ -596,6 +604,8 @@ 9D03E8291A72DCE300207493 /* FBSDKLoginUtility.m */, F4EC46022575A0CC00D2F47B /* FBSDKNonceUtility.h */, F4EC46032575A0CC00D2F47B /* FBSDKNonceUtility.m */, + C6E1332B259173AF00B611C6 /* FBSDKPermission.h */, + C6E1333E259174A500B611C6 /* FBSDKPermission.m */, C6E63D2224F8219A0015FC7C /* FBSDKReferralManagerLogger.h */, C6E63D2C24F822620015FC7C /* FBSDKReferralManagerLogger.m */, ); @@ -689,6 +699,7 @@ F464749B256B048500502449 /* LoginConfigurationTests.swift */, F4647478256AEF8E00502449 /* NonceTests.swift */, 9D9DB8E91A114E500086167B /* Supporting Files */, + C60390DB2592F40200F9247E /* FBSDKPermissionTests.m */, ); path = FBSDKLoginKitTests; sourceTree = ""; @@ -774,6 +785,7 @@ 818EB4331D1A283100252851 /* FBSDKCoreKit+Internal.h in Headers */, 818EB4341D1A283100252851 /* FBSDKLoginConstants.h in Headers */, 818EB4351D1A283100252851 /* FBSDKLoginKit.h in Headers */, + C60390CB2592DB5800F9247E /* FBSDKPermission.h in Headers */, 818EB4361D1A283100252851 /* FBSDKLoginManagerLoginResult.h in Headers */, F4ECC67A23EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, 818EB4371D1A283100252851 /* FBSDKTooltipView.h in Headers */, @@ -804,6 +816,7 @@ 9DBC4C3C1A782E2000816FE8 /* FBSDKCoreKit+Internal.h in Headers */, 9D03E8341A72DF5800207493 /* FBSDKLoginConstants.h in Headers */, 9D9DB8DF1A114E500086167B /* FBSDKLoginKit.h in Headers */, + C6E1332C259173B000B611C6 /* FBSDKPermission.h in Headers */, F4EC46042575A0CC00D2F47B /* FBSDKNonceUtility.h in Headers */, 9D03E8251A72D89100207493 /* FBSDKLoginManagerLoginResult.h in Headers */, F4ECC67923EE2094005DBF05 /* FBSDKCoreKitImport.h in Headers */, @@ -1161,6 +1174,7 @@ 818EB4281D1A283100252851 /* FBSDKLoginError.m in Sources */, F46FA65E245347820060C902 /* LoginManager.swift in Sources */, 818EB4291D1A283100252851 /* FBSDKLoginManager.m in Sources */, + C60390D32592DB5B00F9247E /* FBSDKPermission.m in Sources */, F4EC46072575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C625B49C24F97DF0003DCE23 /* FBSDKReferralManagerLogger.m in Sources */, F46FA65B245347580060C902 /* FBLoginButton.swift in Sources */, @@ -1190,6 +1204,7 @@ 9D03E8351A72DF5800207493 /* FBSDKLoginConstants.m in Sources */, 6B5D2DEA1A8D91B200D3EF09 /* FBSDKLoginError.m in Sources */, F46FA65D245347820060C902 /* LoginManager.swift in Sources */, + C6E1333F259174A500B611C6 /* FBSDKPermission.m in Sources */, 9D03E8221A72D7E700207493 /* FBSDKLoginManager.m in Sources */, F4EC46062575A0CC00D2F47B /* FBSDKNonceUtility.m in Sources */, C6E63D2D24F822620015FC7C /* FBSDKReferralManagerLogger.m in Sources */, @@ -1221,6 +1236,7 @@ F47FB46C2580646600922543 /* FBSDKLoginManagerLoggerTests.m in Sources */, C632597324EDAF0F00D8F7E3 /* FBSDKReferralManagerTests.m in Sources */, C67DC40F25882264004D7E43 /* FBSDKLoginCompletionTests.m in Sources */, + C60390DC2592F40200F9247E /* FBSDKPermissionTests.m in Sources */, F4665CC3258D684300981FDE /* SampleAccessToken.swift in Sources */, F4665CD3258D687500981FDE /* FakeGraphRequestConnectionProvider.swift in Sources */, C6DB850724F87F7B0004DB85 /* FBSDKReferralCodeTests.m in Sources */, diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h index 00e849ec8b..1c9c42217f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.h @@ -20,6 +20,8 @@ NS_ASSUME_NONNULL_BEGIN +@class FBSDKPermission; + /// The login tracking preference to use for a login attempt. For more information on the differences between /// `enabled` and `limited` see: https://developers.facebook.com/docs/facebook-login/ios/limited-login/ typedef NS_ENUM(NSUInteger, FBSDKLoginTracking) @@ -40,7 +42,7 @@ NS_SWIFT_NAME(LoginConfiguration) @property (nonatomic, readonly) FBSDKLoginTracking tracking; /// The requested permissions for the login attempt. Defaults to an empty set. -@property (nonatomic, readonly, copy) NSSet *requestedPermissions; +@property (nonatomic, readonly, copy) NSSet *requestedPermissions; - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m index f14049d280..57270837b7 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConfiguration.m @@ -30,6 +30,8 @@ #import "FBSDKCoreKit+Internal.h" #endif + #import "FBSDKPermission.h" + @implementation FBSDKLoginConfiguration - (nullable instancetype)initWithTracking:(FBSDKLoginTracking)tracking @@ -56,10 +58,8 @@ - (nullable instancetype)initWithPermissions:(NSArray *)permissions return nil; } - NSSet *permissionsSet = [NSSet setWithArray:permissions]; - BOOL arePermissionsValid = [FBSDKLoginConfiguration _arePermissionsValid:permissionsSet - forTrackingPreference:tracking]; - if (!arePermissionsValid) { + NSSet *permissionsSet = [FBSDKLoginConfiguration permissionsFromRawPermissions:[NSSet setWithArray:permissions] forTrackingPreference:tracking]; + if (!permissionsSet) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"Invalid combination of permissions and tracking preference provided to login configuration. The only permissions allowed when `tracking` is `.limited` are 'email', 'public_profile', 'gaming_profile' and 'gaming_user_picture'. Returning nil."]; return nil; @@ -85,8 +85,8 @@ - (instancetype)init return self; } -+ (BOOL)_arePermissionsValid:(NSSet *)permissions - forTrackingPreference:(FBSDKLoginTracking)tracking ++ (NSSet *)permissionsFromRawPermissions:(NSSet *)permissions + forTrackingPreference:(FBSDKLoginTracking)tracking { switch (tracking) { case FBSDKLoginTrackingLimited: { @@ -98,11 +98,16 @@ + (BOOL)_arePermissionsValid:(NSSet *)permissions ]]; NSSet *combined = [permissions setByAddingObjectsFromSet:validPermissions]; - return (permissions.count == 0) || (combined.count <= validPermissions.count); + if (permissions.count != 0 && combined.count > validPermissions.count) { + return nil; + } + break; } case FBSDKLoginTrackingEnabled: - return YES; + break; } + + return [FBSDKPermission permissionsFromRawPermissions:permissions]; } @end diff --git a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m index 99853b6e35..5c6447b0be 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m +++ b/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m @@ -42,6 +42,7 @@ #import "FBSDKLoginError.h" #import "FBSDKLoginManagerLogger.h" #import "FBSDKLoginUtility.h" + #import "FBSDKPermission.h" #import "_FBSDKLoginRecoveryAttempter.h" static int const FBClientStateChallengeLength = 20; @@ -104,6 +105,7 @@ - (void)logInFromViewController:(UIViewController *)viewController self.fromViewController = viewController; _configuration = configuration; + _requestedPermissions = configuration.requestedPermissions; [self logInWithPermissions:configuration.requestedPermissions handler:completion]; } @@ -202,83 +204,28 @@ - (BOOL)isPerformingLogin - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expectChallenge:(BOOL)expectChallenge { - NSSet *recentlyGrantedPermissions = nil; - NSSet *recentlyDeclinedPermissions = nil; FBSDKLoginManagerLoginResult *result = nil; - NSError *error = parameters.error; + NSError *error = parameters.error; NSString *accessTokenString = parameters.accessTokenString; BOOL cancelled = ((accessTokenString == nil) && (parameters.authenticationToken == nil)); if (expectChallenge && !cancelled && !error) { error = [self _verifyChallengeWithCompletionParameters:parameters]; } - [self storeExpectedChallenge:nil]; if (!error) { if (!cancelled) { - NSSet *grantedPermissions = parameters.permissions; - NSSet *declinedPermissions = parameters.declinedPermissions; - - // Recent permissions are largely based on the existence of an access token - // without an access token the 'recent' permissions will match the - // intersect of the granted permissions and the requested permissions. - // This is important because we want to create a 'result' that accurately reflects - // the currently granted permissions even when there is no access token. - [self determineRecentlyGrantedPermissions:&recentlyGrantedPermissions - recentlyDeclinedPermissions:&recentlyDeclinedPermissions - forGrantedPermission:grantedPermissions - declinedPermissions:declinedPermissions]; - - if (recentlyGrantedPermissions.count > 0) { - if (!accessTokenString) { - // If there is no token string then create a 'tokenless' result - // from the returned permissions - result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil - authenticationToken:parameters.authenticationToken - isCancelled:NO - grantedPermissions:grantedPermissions - declinedPermissions:declinedPermissions]; - } else { - FBSDKAccessToken *token = [[FBSDKAccessToken alloc] initWithTokenString:accessTokenString - permissions:grantedPermissions.allObjects - declinedPermissions:declinedPermissions.allObjects - expiredPermissions:@[] - appID:parameters.appID - userID:parameters.userID - expirationDate:parameters.expirationDate - refreshDate:[NSDate date] - dataAccessExpirationDate:parameters.dataAccessExpirationDate - graphDomain:parameters.graphDomain]; - result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:token - authenticationToken:parameters.authenticationToken - isCancelled:NO - grantedPermissions:recentlyGrantedPermissions - declinedPermissions:recentlyDeclinedPermissions]; - - if ([FBSDKAccessToken currentAccessToken]) { - [self validateReauthentication:[FBSDKAccessToken currentAccessToken] withResult:result]; - // in a reauth, short circuit and let the login handler be called when the validation finishes. - return; - } - } - } - } + result = [self successResultFromParameters:parameters]; - if (cancelled || recentlyGrantedPermissions.count == 0) { - NSSet *declinedPermissions = nil; - if ([FBSDKAccessToken currentAccessToken] != nil) { - // Always include the list of declined permissions from this login request - // if an access token is already cached by the SDK - declinedPermissions = recentlyDeclinedPermissions; + if (result.token && FBSDKAccessToken.currentAccessToken) { + [self validateReauthentication:FBSDKAccessToken.currentAccessToken withResult:result]; + // in a reauth, short circuit and let the login handler be called when the validation finishes. + return; } - - result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil - authenticationToken:nil - isCancelled:cancelled - grantedPermissions:NSSet.set - declinedPermissions:declinedPermissions]; + } else { + result = [self cancelledResultFromParameters:parameters]; } } @@ -324,34 +271,6 @@ - (NSError *)_verifyChallengeWithCompletionParameters:(FBSDKLoginCompletionParam } } -- (void)determineRecentlyGrantedPermissions:(NSSet **)recentlyGrantedPermissionsRef - recentlyDeclinedPermissions:(NSSet **)recentlyDeclinedPermissionsRef - forGrantedPermission:(NSSet *)grantedPermissions - declinedPermissions:(NSSet *)declinedPermissions -{ - NSMutableSet *recentlyGrantedPermissions = [grantedPermissions mutableCopy]; - NSSet *previouslyGrantedPermissions = ([FBSDKAccessToken currentAccessToken] - ? [FBSDKAccessToken currentAccessToken].permissions - : nil); - if (previouslyGrantedPermissions.count > 0) { - // If there were no requested permissions for this auth - treat all permissions as granted. - // Otherwise this is a reauth, so recentlyGranted should be a subset of what was requested. - if (_requestedPermissions.count != 0) { - [recentlyGrantedPermissions intersectSet:_requestedPermissions]; - } - } - - NSMutableSet *recentlyDeclinedPermissions = [_requestedPermissions mutableCopy]; - [recentlyDeclinedPermissions intersectSet:declinedPermissions]; - - if (recentlyGrantedPermissionsRef != NULL) { - *recentlyGrantedPermissionsRef = [recentlyGrantedPermissions copy]; - } - if (recentlyDeclinedPermissionsRef != NULL) { - *recentlyDeclinedPermissionsRef = [recentlyDeclinedPermissions copy]; - } -} - - (void)invokeHandler:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { [_logger endLoginWithResult:result error:error]; @@ -414,7 +333,7 @@ - (NSDictionary *)logInParametersWithConfiguration:(FBSDKLoginConfiguration *)co [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKSettings appURLSchemeSuffix] forKey:@"local_client_id"]; [FBSDKTypeUtility dictionary:loginParams setObject:[FBSDKLoginUtility stringForAudience:self.defaultAudience] forKey:@"default_audience"]; - NSSet *permissions = [configuration.requestedPermissions setByAddingObject:@"openid"]; + NSSet *permissions = [configuration.requestedPermissions setByAddingObject:[[FBSDKPermission alloc]initWithString:@"openid"]]; [FBSDKTypeUtility dictionary:loginParams setObject:[permissions.allObjects componentsJoinedByString:@","] forKey:@"scope"]; NSString *expectedChallenge = [FBSDKLoginManager stringForChallenge]; @@ -451,7 +370,6 @@ - (void)logInWithPermissions:(NSSet *)permissions handler:(FBSDKLoginManagerLogi _logger = [[FBSDKLoginManagerLogger alloc] initWithLoggingToken:serverConfiguration.loggingToken]; _handler = [handler copy]; - _requestedPermissions = permissions; [_logger startSessionForLoginManager:self]; @@ -621,6 +539,88 @@ - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams } } +- (FBSDKLoginManagerLoginResult *)cancelledResultFromParameters:(FBSDKLoginCompletionParameters *)parameters +{ + NSSet *declinedPermissions = nil; + if (FBSDKAccessToken.currentAccessToken != nil) { + // Always include the list of declined permissions from this login request + // if an access token is already cached by the SDK + declinedPermissions = [FBSDKPermission rawPermissionsFromPermissions:parameters.declinedPermissions]; + } + + return [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil + authenticationToken:nil + isCancelled:YES + grantedPermissions:NSSet.set + declinedPermissions:declinedPermissions]; +} + +- (FBSDKLoginManagerLoginResult *)successResultFromParameters:(FBSDKLoginCompletionParameters *)parameters +{ + NSSet *grantedPermissions = parameters.permissions; + NSSet *declinedPermissions = parameters.declinedPermissions; + + // Recent permissions are largely based on the existence of an access token + // without an access token the 'recent' permissions will match the + // intersect of the granted permissions and the requested permissions. + // This is important because we want to create a 'result' that accurately reflects + // the currently granted permissions even when there is no access token. + NSSet *recentlyGrantedPermissions = [self recentlyGrantedPermissionsFromGrantedPermissions:grantedPermissions]; + NSSet *recentlyDeclinedPermissions = [self recentlyDeclinedPermissionsFromDeclinedPermissions:declinedPermissions]; + + if (recentlyGrantedPermissions.count > 0) { + NSSet *rawGrantedPermissions = [FBSDKPermission rawPermissionsFromPermissions:grantedPermissions]; + NSSet *rawDeclinedPermissions = [FBSDKPermission rawPermissionsFromPermissions:declinedPermissions]; + NSSet *rawRecentlyGrantedPermissions = [FBSDKPermission rawPermissionsFromPermissions:recentlyGrantedPermissions]; + NSSet *rawRecentlyDeclinedPermissions = [FBSDKPermission rawPermissionsFromPermissions:recentlyDeclinedPermissions]; + + FBSDKAccessToken *token; + if (parameters.accessTokenString) { + token = [[FBSDKAccessToken alloc] initWithTokenString:parameters.accessTokenString + permissions:rawGrantedPermissions.allObjects + declinedPermissions:rawDeclinedPermissions.allObjects + expiredPermissions:@[] + appID:parameters.appID + userID:parameters.userID + expirationDate:parameters.expirationDate + refreshDate:[NSDate date] + dataAccessExpirationDate:parameters.dataAccessExpirationDate + graphDomain:parameters.graphDomain]; + } + + return [[FBSDKLoginManagerLoginResult alloc] initWithToken:token + authenticationToken:parameters.authenticationToken + isCancelled:NO + grantedPermissions:rawRecentlyGrantedPermissions + declinedPermissions:rawRecentlyDeclinedPermissions]; + } else { + return [self cancelledResultFromParameters:parameters]; + } +} + + #pragma mark - Permissions Helpers + +- (NSSet *)recentlyGrantedPermissionsFromGrantedPermissions:(NSSet *)grantedPermissions +{ + NSMutableSet *recentlyGrantedPermissions = grantedPermissions.mutableCopy; + NSSet *previouslyGrantedPermissions = FBSDKAccessToken.currentAccessToken.permissions; + + // If there were no requested permissions for this auth, or no previously granted permissions - treat all permissions as recently granted. + // Otherwise this is a reauth, so recentlyGranted should be a subset of what was requested. + if (previouslyGrantedPermissions.count > 0 && _requestedPermissions.count != 0) { + [recentlyGrantedPermissions intersectSet:_requestedPermissions]; + } + + return recentlyGrantedPermissions; +} + +- (NSSet *)recentlyDeclinedPermissionsFromDeclinedPermissions:(NSSet *)declinedPermissions +{ + NSMutableSet *recentlyDeclinedPermissions = _requestedPermissions.mutableCopy; + [recentlyDeclinedPermissions intersectSet:declinedPermissions]; + return recentlyDeclinedPermissions; +} + #pragma mark - Test Methods - (void)setHandler:(FBSDKLoginManagerLoginResultBlock)handler @@ -628,9 +628,9 @@ - (void)setHandler:(FBSDKLoginManagerLoginResultBlock)handler _handler = [handler copy]; } -- (void)setRequestedPermissions:(NSSet *)requestedPermissions +- (void)setRequestedPermissions:(NSSet *)requestedPermissions { - _requestedPermissions = [requestedPermissions copy]; + _requestedPermissions = [FBSDKPermission permissionsFromRawPermissions:requestedPermissions]; } - (FBSDKLoginConfiguration *)configuration diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h index 8e4e234de9..c756478449 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h @@ -26,6 +26,7 @@ @class FBSDKAuthenticationTokenClaims; @class FBSDKLoginCompletionParameters; @class FBSDKLoginManager; +@class FBSDKPermission; @class FBSDKProfile; NS_ASSUME_NONNULL_BEGIN @@ -54,9 +55,9 @@ NS_SWIFT_NAME(LoginCompletionParameters) @property (nullable, nonatomic, copy, readonly) NSString *nonceString; @property (nullable, nonatomic, copy, readonly) NSString *authenticationTokenString; -@property (nullable, nonatomic, copy, readonly) NSSet *permissions; -@property (nullable, nonatomic, copy, readonly) NSSet *declinedPermissions; -@property (nullable, nonatomic, copy, readonly) NSSet *expiredPermissions; +@property (nullable, nonatomic, copy, readonly) NSSet *permissions; +@property (nullable, nonatomic, copy, readonly) NSSet *declinedPermissions; +@property (nullable, nonatomic, copy, readonly) NSSet *expiredPermissions; @property (nullable, nonatomic, copy, readonly) NSString *appID; @property (nullable, nonatomic, copy, readonly) NSString *userID; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m index 38fa264edc..d2896dac90 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m @@ -33,6 +33,7 @@ #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginUtility.h" + #import "FBSDKPermission.h" @interface FBSDKAuthenticationToken (ClaimsProviding) @@ -152,13 +153,13 @@ - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString * // check the string length so that we assign an empty set rather than a set with an empty string _parameters.permissions = (grantedPermissionsString.length > 0) - ? [NSSet setWithArray:[grantedPermissionsString componentsSeparatedByString:@","]] + ? [FBSDKPermission permissionsFromRawPermissions:[NSSet setWithArray:[grantedPermissionsString componentsSeparatedByString:@","]]] : NSSet.set; _parameters.declinedPermissions = (declinedPermissionsString.length > 0) - ? [NSSet setWithArray:[declinedPermissionsString componentsSeparatedByString:@","]] + ? [FBSDKPermission permissionsFromRawPermissions:[NSSet setWithArray:[declinedPermissionsString componentsSeparatedByString:@","]]] : NSSet.set; - _parameters.expiredPermissions = [NSSet set]; + _parameters.expiredPermissions = NSSet.set; _parameters.appID = appID; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h index 97cda0957c..42edf3a45c 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h @@ -21,3 +21,4 @@ #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLogger.h" #import "FBSDKLoginUtility.h" +#import "FBSDKPermission.h" diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h index eb6421fa2e..d928a5833f 100644 --- a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h @@ -37,6 +37,7 @@ @class FBSDKAccessToken; @class FBSDKLoginCompletionParameters; @class FBSDKLoginManagerLogger; +@class FBSDKPermission; /** Success Block @@ -54,7 +55,7 @@ typedef NS_ENUM(NSInteger, FBSDKLoginManagerState) { @interface FBSDKLoginManager () @property (nonatomic, weak) UIViewController *fromViewController; -@property (nonatomic, readonly) NSSet *requestedPermissions; +@property (nonatomic, readonly) NSSet *requestedPermissions; @property (nonatomic, strong) FBSDKLoginManagerLogger *logger; @property (nonatomic) FBSDKLoginManagerState state; @property (nonatomic) BOOL usedSFAuthSession; diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.h b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.h new file mode 100644 index 0000000000..7a9fad4a0c --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.h @@ -0,0 +1,56 @@ +// 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 + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(FBPermission) +@interface FBSDKPermission : NSObject + ++ (instancetype)new NS_UNAVAILABLE; +- (instancetype)init NS_UNAVAILABLE; + +/** + The raw string representation of the permission +*/ +@property (nonatomic, readonly, copy) NSString *value; + +/** + Attempts to initialize a new permission with the given string. + Creation will fail and return nil if the string is invalid. + + @param string the raw permission string +*/ +- (nullable instancetype)initWithString:(NSString *)string; + +/** + Returns a set of FBSDKPermission from a set of raw permissions strings. + Will return nil if any of the input permissions is invalid. +*/ ++ (nullable NSSet *)permissionsFromRawPermissions:(NSSet *)rawPermissions; + +/** + Returns a set of string permissions from a set of FBSDKPermission by + extracting the "value" property for each element. +*/ ++ (NSSet *)rawPermissionsFromPermissions:(NSSet *)permissions; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.m b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.m new file mode 100644 index 0000000000..162d1ad6a2 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKPermission.m @@ -0,0 +1,93 @@ +// 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 "FBSDKPermission.h" + +#ifdef FBSDKCOCOAPODS + #import +#else + #import "FBSDKCoreKit+Internal.h" +#endif + +@implementation FBSDKPermission + +- (nullable instancetype)initWithString:(NSString *)string +{ + NSString *permission = [FBSDKTypeUtility stringValue:string]; + if (permission.length <= 0) { + return nil; + } + + NSCharacterSet *allowedSet = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyz_"]; + if (![[string stringByTrimmingCharactersInSet:allowedSet] isEqualToString:@""]) { + return nil; + } + + if ((self = [super init])) { + _value = permission; + } + return self; +} + ++ (NSSet *)permissionsFromRawPermissions:(NSSet *)rawPermissions +{ + NSMutableSet *permissions = NSMutableSet.new; + + for (NSString *rawPermission in rawPermissions) { + FBSDKPermission *permission = [[FBSDKPermission alloc] initWithString:rawPermission]; + if (!permission) { + return nil; + } + [permissions addObject:permission]; + } + + return permissions; +} + ++ (NSSet *)rawPermissionsFromPermissions:(NSSet *)permissions +{ + NSMutableSet *rawPermissions = NSMutableSet.new; + + for (FBSDKPermission *permission in permissions) { + [rawPermissions addObject:permission.value]; + } + + return rawPermissions; +} + +- (BOOL)isEqual:(id)obj +{ + if (![obj isKindOfClass:[FBSDKPermission class]]) { + return NO; + } + + FBSDKPermission *other = (FBSDKPermission *)obj; + return [self.value isEqualToString:other.value]; +} + +- (NSString *)description +{ + return self.value; +} + +- (NSUInteger)hash +{ + return self.value.hash; +} + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m index 905560c946..1e6a4bee43 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginCompletionTests.m @@ -22,8 +22,10 @@ #ifdef BUCK #import + #import #else #import "FBSDKLoginCompletion+Internal.h" + #import "FBSDKPermission.h" #endif #import "FBSDKLoginKitTests-Swift.h" @@ -514,9 +516,9 @@ - (void)verifyParameters:(FBSDKLoginCompletionParameters *)parameters urlParamet XCTAssertEqualObjects(parameters.authenticationTokenString, urlParameters[@"id_token"]); XCTAssertEqualObjects(parameters.appID, _fakeAppID); XCTAssertEqualObjects(parameters.challenge, _fakeChallence); - NSSet *permissions = [NSSet setWithArray:[urlParameters[@"granted_scopes"] componentsSeparatedByString:@","]]; + NSSet *permissions = [FBSDKPermission permissionsFromRawPermissions:[NSSet setWithArray:[urlParameters[@"granted_scopes"] componentsSeparatedByString:@","]]]; XCTAssertEqualObjects(parameters.permissions, permissions); - NSSet *declinedPermissions = [NSSet setWithArray:[urlParameters[@"denied_scopes"] componentsSeparatedByString:@","]]; + NSSet *declinedPermissions = [FBSDKPermission permissionsFromRawPermissions:[NSSet setWithArray:[urlParameters[@"denied_scopes"] componentsSeparatedByString:@","]]]; XCTAssertEqualObjects(parameters.declinedPermissions, declinedPermissions); XCTAssertEqualObjects(parameters.userID, urlParameters[@"user_id"]); XCTAssertEqualObjects(parameters.graphDomain, urlParameters[@"graph_domain"]); diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h index 19ff19cc8b..a5223ad4fb 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKLoginKitTests-Bridging-Header.h @@ -23,9 +23,11 @@ #ifdef BUCK #import #import + #import #else #import "FBSDKGraphRequestConnectionProviding.h" #import "FBSDKNonceUtility.h" + #import "FBSDKPermission.h" #endif @class FBSDKAuthenticationTokenClaims; diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKPermissionTests.m b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKPermissionTests.m new file mode 100644 index 0000000000..859a8131e4 --- /dev/null +++ b/FBSDKLoginKit/FBSDKLoginKitTests/FBSDKPermissionTests.m @@ -0,0 +1,96 @@ +// 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 + +#ifdef BUCK + #import +#else + #import "FBSDKPermission.h" +#endif + +@interface FBSDKPermissionTests : XCTestCase + +@end + +@implementation FBSDKPermissionTests + +- (void)testInvalidPermissions +{ + NSArray *permissions = @[ + @"", + @"foo bar", + @"PUBLIC_PROFILE", + @"public profile", + @"public-profile", + @"123_abc" + ]; + + for (NSString *rawPermission in permissions) { + FBSDKPermission *permission = [[FBSDKPermission alloc] initWithString:rawPermission]; + XCTAssertNil(permission); + } +} + +- (void)testValidPermissions +{ + NSArray *permissions = @[ + @"email", + @"public_profile", + @"pages_manage_ads" + ]; + + for (NSString *rawPermission in permissions) { + FBSDKPermission *permission = [[FBSDKPermission alloc] initWithString:rawPermission]; + XCTAssertEqualObjects(permission.value, rawPermission); + } +} + +- (void)testRawPermissionsFromPermissions +{ + NSSet *permissions = [NSSet setWithArray:@[ + [[FBSDKPermission alloc] initWithString:@"email"], + [[FBSDKPermission alloc] initWithString:@"public_profile"], + ]]; + + NSArray *rawPermissions = [FBSDKPermission rawPermissionsFromPermissions:permissions].allObjects; + NSArray *expectedRawPermissions = @[@"email", @"public_profile"]; + XCTAssertEqualObjects(rawPermissions, expectedRawPermissions); +} + +- (void)testPermissionsFromValidRawPermissions +{ + NSSet *rawPermissions = [NSSet setWithArray:@[@"email", @"user_friends"]]; + + NSArray *permissions = [FBSDKPermission permissionsFromRawPermissions:rawPermissions].allObjects; + NSArray *expectedPermissions = @[ + [[FBSDKPermission alloc] initWithString:@"email"], + [[FBSDKPermission alloc] initWithString:@"user_friends"], + ]; + XCTAssertEqualObjects(permissions, expectedPermissions); +} + +- (void)testPermissionsFromInvalidRawPermissions +{ + NSSet *rawPermissions = [NSSet setWithArray:@[@"email", @""]]; + + NSArray *permissions = [FBSDKPermission permissionsFromRawPermissions:rawPermissions].allObjects; + XCTAssertNil(permissions); +} + +@end diff --git a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift index b5817766d7..7d7044f8ca 100644 --- a/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift +++ b/FBSDKLoginKit/FBSDKLoginKitTests/LoginConfigurationTests.swift @@ -78,7 +78,7 @@ class LoginConfigurationTests: XCTestCase { let config = LoginConfiguration(permissions: permissions) XCTAssertEqual( - config?.requestedPermissions, + Set((config?.requestedPermissions.map { $0.value })!), Set(permissions.map { $0.name }), "Should create a configuration with the provided tracking preference" )