Skip to content

Commit f487e29

Browse files
[MBL-2755] Update Facebook SDK (#2611)
* Update Facebook SDK version * Update Facebook API usage * Isolate Facebook dependency to Library to prevent double symbols * Fix missing import
1 parent 62526eb commit f487e29

16 files changed

+238
-17
lines changed

Kickstarter-iOS/AppDelegate.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import BrazeKit
22
import BrazeUI
3-
import FBSDKCoreKit
43
import Firebase
54
import Foundation
65
import KDS
@@ -42,8 +41,12 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate {
4241
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
4342
) -> Bool {
4443
// FBSDK initialization
45-
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
46-
Settings.shouldLimitEventAndDataUsage = true
44+
let facebookAppID = Bundle.main.infoDictionary?["FacebookAppID"] as? String
45+
AppEnvironment.configureFacebookSDK(
46+
appID: facebookAppID,
47+
application: application,
48+
launchOptions: launchOptions
49+
)
4750

4851
// Braze expects to be configured immediately, but segment destination plugins are initialized
4952
// async. This method bridges that gap.
@@ -334,7 +337,7 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate {
334337
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
335338
) -> Bool {
336339
// If this is not a Facebook login call, handle the potential deep-link
337-
guard !ApplicationDelegate.shared.application(app, open: url, options: options) else {
340+
guard !AppEnvironment.current.facebookSDK.handleOpenURL(app, open: url, options: options) else {
338341
return true
339342
}
340343

Kickstarter-iOS/Features/Activities/Views/Cells/FindFriendsFacebookConnectCell.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import FBSDKLoginKit
1+
import FacebookLogin
22
import KDS
33
import Library
44
import Prelude

Kickstarter-iOS/Features/LoginTout/Controller/LoginToutViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import AuthenticationServices
2-
import FBSDKLoginKit
2+
import FacebookLogin
33
import Foundation
44
import KDS
55
import KsApi

Kickstarter.xcodeproj/project.pbxproj

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,10 @@
12101210
A7FC8C061C8F1DEA00C3B49B /* CircleAvatarImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FC8C051C8F1DEA00C3B49B /* CircleAvatarImageView.swift */; };
12111211
AA1023E42CABD2AE007800B5 /* PPOContainerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA1023E32CABD2AE007800B5 /* PPOContainerViewModel.swift */; };
12121212
AA3EB8432CF687680018C880 /* ServerFeature+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3EB8422CF687680018C880 /* ServerFeature+Helpers.swift */; };
1213+
AA4533642E7A2B6500B569E8 /* FacebookSDKType.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4533632E7A2B6500B569E8 /* FacebookSDKType.swift */; };
1214+
AA4533652E7A2B6500B569E8 /* FacebookSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4533622E7A2B6500B569E8 /* FacebookSDK.swift */; };
1215+
AA4533682E7A2C0A00B569E8 /* MockFacebookSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4533672E7A2C0A00B569E8 /* MockFacebookSDK.swift */; };
1216+
AA4533692E7A2C0A00B569E8 /* FacebookSDKTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4533662E7A2C0A00B569E8 /* FacebookSDKTypeTests.swift */; };
12131217
AA645E972C770D620034705A /* DesignSystemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6049D0102A9CF6840015BB0D /* DesignSystemViewController.swift */; };
12141218
AA645E9C2C7725FB0034705A /* PagedContainerViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA645E9A2C7725FB0034705A /* PagedContainerViewModelTests.swift */; };
12151219
AA645E9E2C772C650034705A /* PagedTabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA645E9D2C772C650034705A /* PagedTabBarTests.swift */; };
@@ -2967,6 +2971,10 @@
29672971
A7FC8C051C8F1DEA00C3B49B /* CircleAvatarImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircleAvatarImageView.swift; sourceTree = "<group>"; };
29682972
AA1023E32CABD2AE007800B5 /* PPOContainerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PPOContainerViewModel.swift; sourceTree = "<group>"; };
29692973
AA3EB8422CF687680018C880 /* ServerFeature+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ServerFeature+Helpers.swift"; sourceTree = "<group>"; };
2974+
AA4533622E7A2B6500B569E8 /* FacebookSDK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookSDK.swift; sourceTree = "<group>"; };
2975+
AA4533632E7A2B6500B569E8 /* FacebookSDKType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookSDKType.swift; sourceTree = "<group>"; };
2976+
AA4533662E7A2C0A00B569E8 /* FacebookSDKTypeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FacebookSDKTypeTests.swift; sourceTree = "<group>"; };
2977+
AA4533672E7A2C0A00B569E8 /* MockFacebookSDK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockFacebookSDK.swift; sourceTree = "<group>"; };
29702978
AA645E9A2C7725FB0034705A /* PagedContainerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagedContainerViewModelTests.swift; sourceTree = "<group>"; };
29712979
AA645E9D2C772C650034705A /* PagedTabBarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PagedTabBarTests.swift; sourceTree = "<group>"; };
29722980
AA6682222CB86EEB00C8522E /* PPOProjectCardModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PPOProjectCardModel.swift; sourceTree = "<group>"; };
@@ -6547,6 +6555,8 @@
65476555
77556F1C20A09993008CEA57 /* ExperimentName+Helpers.swift */,
65486556
D667C2BB2305F03300EC094A /* ExperimentName+HelpersTests.swift */,
65496557
77216CAB20EFE7F70061BE82 /* FacebookConnectionType.swift */,
6558+
AA4533622E7A2B6500B569E8 /* FacebookSDK.swift */,
6559+
AA4533632E7A2B6500B569E8 /* FacebookSDKType.swift */,
65506560
8AF91CDC22EF5AF7005F9C90 /* Feature.swift */,
65516561
A7C725801C85D36D005A016B /* Format.swift */,
65526562
A7ED1F151E830FDC00BFFA01 /* FormatTests.swift */,
@@ -6579,6 +6589,8 @@
65796589
D0200A5321935EDF00F5CC27 /* MessageBannerType.swift */,
65806590
8A3BF51D23F5DB52002AD818 /* MockCoreTelephonyNetworkInfo.swift */,
65816591
D093B4B721A8B0E000910962 /* MockPushRegistration.swift */,
6592+
AA4533662E7A2C0A00B569E8 /* FacebookSDKTypeTests.swift */,
6593+
AA4533672E7A2C0A00B569E8 /* MockFacebookSDK.swift */,
65826594
606C45F929FACE17001BA067 /* MockRemoteConfigClient.swift */,
65836595
80E26A121D500C6A007B3022 /* Navigation.swift */,
65846596
77D19FF4240813240058FC8E /* NavigationController.swift */,
@@ -8645,6 +8657,8 @@
86458657
77F6E73721222E97005A5C55 /* SettingsCellType.swift in Sources */,
86468658
D703FC6B20F7E3F8004A272D /* SettingsPrivacyViewModel.swift in Sources */,
86478659
8A4DDAB52373429300ADE31D /* PledgeStatusLabelViewModel.swift in Sources */,
8660+
AA4533642E7A2B6500B569E8 /* FacebookSDKType.swift in Sources */,
8661+
AA4533652E7A2B6500B569E8 /* FacebookSDK.swift in Sources */,
86488662
0169F9881D6F51C400C8D5C5 /* DiscoveryFiltersViewModel.swift in Sources */,
86498663
94C92E8A2659F09A00A96818 /* PaddingLabel.swift in Sources */,
86508664
01FD71EC1D3808E500070BAC /* BarButtonItemStyles.swift in Sources */,
@@ -8990,6 +9004,8 @@
89909004
A78355B91E85BD2D0021DA5A /* ActivityFriendFollowCellViewModelTests.swift in Sources */,
89919005
A7ED1FF01E831C5C00BFFA01 /* MessagesViewModelTests.swift in Sources */,
89929006
77BC00F82330236600808E75 /* RewardCellViewModelTests.swift in Sources */,
9007+
AA4533682E7A2C0A00B569E8 /* MockFacebookSDK.swift in Sources */,
9008+
AA4533692E7A2C0A00B569E8 /* FacebookSDKTypeTests.swift in Sources */,
89939009
3344A7812D9C973400D7DE91 /* RewardTrackingDetailsViewModelTest.swift in Sources */,
89949010
A7ED1FC91E831C5C00BFFA01 /* ActivitiesViewModelTests.swift in Sources */,
89959011
A7ED1FD21E831C5C00BFFA01 /* LoginToutViewModelTests.swift in Sources */,
@@ -11774,7 +11790,7 @@
1177411790
repositoryURL = "https://github.com/facebook/facebook-ios-sdk";
1177511791
requirement = {
1177611792
kind = upToNextMajorVersion;
11777-
minimumVersion = 9.0.0;
11793+
minimumVersion = 12.0.0;
1177811794
};
1177911795
};
1178011796
60DA50F628BFA331002E2DF1 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = {

Kickstarter.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Library/AppEnvironment.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import FBSDKCoreKit
1+
import FacebookCore
22
import FirebaseCrashlytics
33
import Foundation
44
import KsApi
@@ -102,6 +102,26 @@ public struct AppEnvironment: AppEnvironmentType {
102102
self.replaceCurrentEnvironment(language: language)
103103
}
104104

105+
public static func configureFacebookSDK(
106+
appID: String?,
107+
application: UIApplication,
108+
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
109+
) {
110+
self.current.facebookSDK.configure(
111+
appID: appID,
112+
application: application,
113+
launchOptions: launchOptions
114+
)
115+
}
116+
117+
public static func didFacebookSDKOpenURL(
118+
_ app: UIApplication,
119+
open url: URL,
120+
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
121+
) -> Bool {
122+
return self.current.facebookSDK.handleOpenURL(app, open: url, options: options)
123+
}
124+
105125
// Invoke when you want to end the user's session.
106126
public static func logout() {
107127
let storage = AppEnvironment.current.cookieStorage
@@ -185,6 +205,7 @@ public struct AppEnvironment: AppEnvironmentType {
185205
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
186206
debugData: DebugData? = AppEnvironment.current.debugData,
187207
device: UIDeviceType = AppEnvironment.current.device,
208+
facebookSDK: FacebookSDKType.Type = AppEnvironment.current.facebookSDK,
188209
isVoiceOverRunning: @escaping (() -> Bool) = AppEnvironment.current.isVoiceOverRunning,
189210
ksrAnalytics: KSRAnalytics = AppEnvironment.current.ksrAnalytics,
190211
language: Language = AppEnvironment.current.language,
@@ -218,6 +239,7 @@ public struct AppEnvironment: AppEnvironmentType {
218239
debounceInterval: debounceInterval,
219240
debugData: debugData,
220241
device: device,
242+
facebookSDK: facebookSDK,
221243
isVoiceOverRunning: isVoiceOverRunning,
222244
ksrAnalytics: ksrAnalytics,
223245
language: language,
@@ -258,6 +280,7 @@ public struct AppEnvironment: AppEnvironmentType {
258280
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
259281
debugData: DebugData? = AppEnvironment.current.debugData,
260282
device: UIDeviceType = AppEnvironment.current.device,
283+
facebookSDK: FacebookSDKType.Type = AppEnvironment.current.facebookSDK,
261284
isVoiceOverRunning: @escaping (() -> Bool) = AppEnvironment.current.isVoiceOverRunning,
262285
ksrAnalytics: KSRAnalytics = AppEnvironment.current.ksrAnalytics,
263286
language: Language = AppEnvironment.current.language,
@@ -294,6 +317,7 @@ public struct AppEnvironment: AppEnvironmentType {
294317
debounceInterval: debounceInterval,
295318
debugData: debugData,
296319
device: device,
320+
facebookSDK: facebookSDK,
297321
isVoiceOverRunning: isVoiceOverRunning,
298322
ksrAnalytics: ksrAnalytics,
299323
language: language,

Library/Environment.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import AVFoundation
22
import CoreTelephony
3-
import FBSDKCoreKit
3+
import FacebookCore
44
import Foundation
55
import KsApi
66
import ReactiveSwift
@@ -77,6 +77,9 @@ public struct Environment {
7777
/// The environment variables
7878
public let environmentVariables: EnvironmentVariables
7979

80+
/// A type that manages Facebook SDK operations.
81+
public let facebookSDK: FacebookSDKType.Type
82+
8083
/// A function that returns whether VoiceOver mode is running.
8184
public let isVoiceOverRunning: () -> Bool
8285

@@ -140,6 +143,7 @@ public struct Environment {
140143
debugData: DebugData? = nil,
141144
device: UIDeviceType = UIDevice.current,
142145
environmentVariables: EnvironmentVariables = EnvironmentVariables(),
146+
facebookSDK: FacebookSDKType.Type = FacebookSDK.self,
143147
isVoiceOverRunning: @escaping () -> Bool = { UIAccessibility.isVoiceOverRunning },
144148
ksrAnalytics: KSRAnalytics = KSRAnalytics(),
145149
language: Language = Language(languageStrings: Locale.preferredLanguages) ?? Language.en,
@@ -175,6 +179,7 @@ public struct Environment {
175179
self.debugData = debugData
176180
self.device = device
177181
self.environmentVariables = environmentVariables
182+
self.facebookSDK = facebookSDK
178183
self.isVoiceOverRunning = isVoiceOverRunning
179184
self.ksrAnalytics = ksrAnalytics
180185
self.language = language

Library/FacebookSDK.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import FacebookCore
2+
import Foundation
3+
import UIKit
4+
5+
/// Concrete implementation of FacebookSDKType using FacebookCore
6+
public enum FacebookSDK: FacebookSDKType {
7+
public static func configure(
8+
appID: String?,
9+
application: UIApplication,
10+
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
11+
) {
12+
FacebookCore.Settings.shared.isEventDataUsageLimited = true
13+
FacebookCore.Settings.shared.appID = appID
14+
FacebookCore.ApplicationDelegate.shared.application(
15+
application,
16+
didFinishLaunchingWithOptions: launchOptions
17+
)
18+
}
19+
20+
public static func handleOpenURL(
21+
_ app: UIApplication,
22+
open url: URL,
23+
options: [UIApplication.OpenURLOptionsKey: Any]
24+
) -> Bool {
25+
return FacebookCore.ApplicationDelegate.shared.application(app, open: url, options: options)
26+
}
27+
}

Library/FacebookSDKType.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Foundation
2+
import UIKit
3+
4+
/// Protocol defining Facebook SDK operations for login and URL handling
5+
public protocol FacebookSDKType {
6+
/// Configure the Facebook SDK with app ID and launch options
7+
static func configure(
8+
appID: String?,
9+
application: UIApplication,
10+
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
11+
)
12+
13+
/// Handle URL opening for Facebook SDK
14+
static func handleOpenURL(
15+
_ app: UIApplication,
16+
open url: URL,
17+
options: [UIApplication.OpenURLOptionsKey: Any]
18+
) -> Bool
19+
}

Library/FacebookSDKTypeTests.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import Foundation
2+
@testable import Library
3+
import UIKit
4+
import XCTest
5+
6+
final class FacebookSDKTypeTests: XCTestCase {
7+
override func setUp() {
8+
super.setUp()
9+
MockFacebookSDK.reset()
10+
}
11+
12+
func testMockFacebookSDKConfigure() {
13+
// Given
14+
let appID = "test_app_id"
15+
let application = UIApplication.shared
16+
let launchOptions: [UIApplication.LaunchOptionsKey: Any]? = [.init(rawValue: "test"): "value"]
17+
18+
// When
19+
MockFacebookSDK.configure(
20+
appID: appID,
21+
application: application,
22+
launchOptions: launchOptions
23+
)
24+
25+
// Then
26+
XCTAssertTrue(MockFacebookSDK.configureCalled)
27+
XCTAssertEqual(MockFacebookSDK.configureAppID, appID)
28+
XCTAssertEqual(MockFacebookSDK.configureApplication, application)
29+
XCTAssertEqual(MockFacebookSDK.configureLaunchOptions?[.init(rawValue: "test")] as? String, "value")
30+
}
31+
32+
func testMockFacebookSDKHandleOpenURL() {
33+
// Given
34+
let application = UIApplication.shared
35+
let url = URL(string: "https://example.com")!
36+
let options: [UIApplication.OpenURLOptionsKey: Any] = [.init(rawValue: "test"): "value"]
37+
MockFacebookSDK.handleOpenURLReturnValue = true
38+
39+
// When
40+
let result = MockFacebookSDK.handleOpenURL(application, open: url, options: options)
41+
42+
// Then
43+
XCTAssertTrue(MockFacebookSDK.handleOpenURLCalled)
44+
XCTAssertEqual(MockFacebookSDK.handleOpenURLApp, application)
45+
XCTAssertEqual(MockFacebookSDK.handleOpenURLURL, url)
46+
XCTAssertEqual(MockFacebookSDK.handleOpenURLOptions?[.init(rawValue: "test")] as? String, "value")
47+
XCTAssertTrue(result)
48+
}
49+
50+
func testMockFacebookSDKReset() {
51+
// Given
52+
MockFacebookSDK.configure(appID: "test", application: UIApplication.shared, launchOptions: nil)
53+
_ = MockFacebookSDK.handleOpenURL(
54+
UIApplication.shared,
55+
open: URL(string: "https://test.com")!,
56+
options: [:]
57+
)
58+
59+
// When
60+
MockFacebookSDK.reset()
61+
62+
// Then
63+
XCTAssertFalse(MockFacebookSDK.configureCalled)
64+
XCTAssertNil(MockFacebookSDK.configureAppID)
65+
XCTAssertNil(MockFacebookSDK.configureApplication)
66+
XCTAssertNil(MockFacebookSDK.configureLaunchOptions)
67+
XCTAssertFalse(MockFacebookSDK.handleOpenURLCalled)
68+
XCTAssertNil(MockFacebookSDK.handleOpenURLApp)
69+
XCTAssertNil(MockFacebookSDK.handleOpenURLURL)
70+
XCTAssertNil(MockFacebookSDK.handleOpenURLOptions)
71+
XCTAssertFalse(MockFacebookSDK.handleOpenURLReturnValue)
72+
}
73+
}

0 commit comments

Comments
 (0)