diff --git a/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.pbxproj b/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.pbxproj index 774114af1..a0802a52f 100644 --- a/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.pbxproj +++ b/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.pbxproj @@ -9,6 +9,10 @@ /* Begin PBXBuildFile section */ 551A5FF1251AB1950004C9A0 /* IterableSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 551A5FF0251AB1950004C9A0 /* IterableSDK */; }; 551A5FF3251AB19B0004C9A0 /* IterableAppExtensions in Frameworks */ = {isa = PBXBuildFile; productRef = 551A5FF2251AB19B0004C9A0 /* IterableAppExtensions */; }; + 9F58740D2D8B8BB500163424 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9F58740C2D8B8BB500163424 /* GoogleService-Info.plist */; }; + 9F58740E2D8B8BB500163424 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9F58740C2D8B8BB500163424 /* GoogleService-Info.plist */; }; + 9F5874112D8B93BD00163424 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 9F5874102D8B93BD00163424 /* FirebaseAnalytics */; }; + 9F5874132D8B93BD00163424 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 9F5874122D8B93BD00163424 /* FirebaseMessaging */; }; AC1BDF5820E304BC000010CA /* CoffeeListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC5ECD9E20E304000081E1DA /* CoffeeListTableViewController.swift */; }; AC1BDF5920E304BF000010CA /* DeepLinkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1BDF5720E30436000010CA /* DeepLinkHandler.swift */; }; AC1BDF5A20E304CC000010CA /* CoffeeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC5ECD9F20E304070081E1DA /* CoffeeViewController.swift */; }; @@ -52,6 +56,7 @@ /* Begin PBXFileReference section */ 551A5FEC251AB1510004C9A0 /* swift-sdk */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "swift-sdk"; path = ../..; sourceTree = ""; }; + 9F58740C2D8B8BB500163424 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; AC1BDF5720E30436000010CA /* DeepLinkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = ""; }; AC5ECD9C20E303D20081E1DA /* UIViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extension.swift"; sourceTree = ""; }; AC5ECD9E20E304000081E1DA /* CoffeeListTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoffeeListTableViewController.swift; sourceTree = ""; }; @@ -78,6 +83,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9F5874132D8B93BD00163424 /* FirebaseMessaging in Frameworks */, + 9F5874112D8B93BD00163424 /* FirebaseAnalytics in Frameworks */, 551A5FF1251AB1950004C9A0 /* IterableSDK in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -142,6 +149,7 @@ ACFA148420E3033700AF4A5A /* Model */, ACFA148720E3036200AF4A5A /* Storyboards */, ACA3A13820E2F6AF00FEF74F /* AppDelegate.swift */, + 9F58740C2D8B8BB500163424 /* GoogleService-Info.plist */, ); path = "swift-sample-app"; sourceTree = ""; @@ -219,6 +227,8 @@ name = "swift-sample-app"; packageProductDependencies = ( 551A5FF0251AB1950004C9A0 /* IterableSDK */, + 9F5874102D8B93BD00163424 /* FirebaseAnalytics */, + 9F5874122D8B93BD00163424 /* FirebaseMessaging */, ); productName = "swift-sample-app"; productReference = ACA3A13520E2F6AF00FEF74F /* swift-sample-app.app */; @@ -281,6 +291,9 @@ Base, ); mainGroup = ACA3A12C20E2F6AF00FEF74F; + packageReferences = ( + 9F58740F2D8B93BD00163424 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + ); productRefGroup = ACA3A13620E2F6AF00FEF74F /* Products */; projectDirPath = ""; projectRoot = ""; @@ -298,6 +311,7 @@ files = ( ACA3A14320E2F6B100FEF74F /* LaunchScreen.storyboard in Resources */, ACA3A14020E2F6B100FEF74F /* Assets.xcassets in Resources */, + 9F58740E2D8B8BB500163424 /* GoogleService-Info.plist in Resources */, ACA3A13E20E2F6AF00FEF74F /* Main.storyboard in Resources */, E9C60B7B2B3C2061005C4462 /* embeddedmessages.json in Resources */, ); @@ -307,6 +321,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9F58740D2D8B8BB500163424 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -367,6 +382,99 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + AC123456789ABCDE0 /* Internal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = "swift-sample-app/swift-sample-app.entitlements"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = BP98Z28R86; + INFOPLIST_FILE = "swift-sample-app/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.iterable.swift-sample-app"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Internal; + }; + AC123456789ABCDE1 /* Internal */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = BP98Z28R86; + INFOPLIST_FILE = "swift-sample-app-notification-extension/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.iterable.swift-sample-app.notification-extension"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Internal; + }; + AC123456789ABCDEF /* Internal */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + 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_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + 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; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Internal; + }; ACA3A14520E2F6B100FEF74F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -489,13 +597,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "swift-sample-app/swift-sample-app.entitlements"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = BP98Z28R86; INFOPLIST_FILE = "swift-sample-app/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "*"; + PRODUCT_BUNDLE_IDENTIFIER = "com.iterable.swift-sample-app"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -508,13 +616,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "swift-sample-app/swift-sample-app.entitlements"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = BP98Z28R86; INFOPLIST_FILE = "swift-sample-app/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "*"; + PRODUCT_BUNDLE_IDENTIFIER = "com.iterable.swift-sample-app"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -525,14 +633,14 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = BP98Z28R86; INFOPLIST_FILE = "swift-sample-app-notification-extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = "*"; + PRODUCT_BUNDLE_IDENTIFIER = "com.iterable.swift-sample-app.notification-extension"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; @@ -544,100 +652,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "swift-sample-app-notification-extension/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@executable_path/../../Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "*"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - AC123456789ABCDEF /* Internal */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - 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_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - 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; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Internal; - }; - AC123456789ABCDE0 /* Internal */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = "swift-sample-app/swift-sample-app.entitlements"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "BP98Z28R86"; - INFOPLIST_FILE = "swift-sample-app/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.iterable.swift-sample-app"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Internal; - }; - AC123456789ABCDE1 /* Internal */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = "BP98Z28R86"; + DEVELOPMENT_TEAM = BP98Z28R86; INFOPLIST_FILE = "swift-sample-app-notification-extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -650,7 +665,7 @@ SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; - name = Internal; + name = Release; }; /* End XCBuildConfiguration section */ @@ -687,6 +702,17 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + 9F58740F2D8B93BD00163424 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 11.10.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + /* Begin XCSwiftPackageProductDependency section */ 551A5FF0251AB1950004C9A0 /* IterableSDK */ = { isa = XCSwiftPackageProductDependency; @@ -696,6 +722,16 @@ isa = XCSwiftPackageProductDependency; productName = IterableAppExtensions; }; + 9F5874102D8B93BD00163424 /* FirebaseAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = 9F58740F2D8B93BD00163424 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalytics; + }; + 9F5874122D8B93BD00163424 /* FirebaseMessaging */ = { + isa = XCSwiftPackageProductDependency; + package = 9F58740F2D8B93BD00163424 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseMessaging; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = ACA3A12D20E2F6AF00FEF74F /* Project object */; diff --git a/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata index b4c94ba12..919434a62 100644 --- a/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..39d688ffd --- /dev/null +++ b/sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,124 @@ +{ + "object": { + "pins": [ + { + "package": "abseil", + "repositoryURL": "https://github.com/google/abseil-cpp-binary.git", + "state": { + "branch": null, + "revision": "bbe8b69694d7873315fd3a4ad41efe043e1c07c5", + "version": "1.2024072200.0" + } + }, + { + "package": "AppCheck", + "repositoryURL": "https://github.com/google/app-check.git", + "state": { + "branch": null, + "revision": "61b85103a1aeed8218f17c794687781505fbbef5", + "version": "11.2.0" + } + }, + { + "package": "Firebase", + "repositoryURL": "https://github.com/firebase/firebase-ios-sdk.git", + "state": { + "branch": null, + "revision": "2e4a4daac9da51f79c131e76cb47e785dd7708c4", + "version": "11.10.0" + } + }, + { + "package": "GoogleAppMeasurement", + "repositoryURL": "https://github.com/google/GoogleAppMeasurement.git", + "state": { + "branch": null, + "revision": "defe1970a9099d47765592ebd7ac5f5e9fdb57c6", + "version": "11.10.0" + } + }, + { + "package": "GoogleDataTransport", + "repositoryURL": "https://github.com/google/GoogleDataTransport.git", + "state": { + "branch": null, + "revision": "617af071af9aa1d6a091d59a202910ac482128f9", + "version": "10.1.0" + } + }, + { + "package": "GoogleUtilities", + "repositoryURL": "https://github.com/google/GoogleUtilities.git", + "state": { + "branch": null, + "revision": "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb", + "version": "8.0.2" + } + }, + { + "package": "gRPC", + "repositoryURL": "https://github.com/google/grpc-binary.git", + "state": { + "branch": null, + "revision": "cc0001a0cf963aa40501d9c2b181e7fc9fd8ec71", + "version": "1.69.0" + } + }, + { + "package": "GTMSessionFetcher", + "repositoryURL": "https://github.com/google/gtm-session-fetcher.git", + "state": { + "branch": null, + "revision": "5cfe5f090c982de9c58605d2a82a4fc77b774fbd", + "version": "4.1.0" + } + }, + { + "package": "InteropForGoogle", + "repositoryURL": "https://github.com/google/interop-ios-for-google-sdks.git", + "state": { + "branch": null, + "revision": "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe", + "version": "101.0.0" + } + }, + { + "package": "leveldb", + "repositoryURL": "https://github.com/firebase/leveldb.git", + "state": { + "branch": null, + "revision": "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version": "1.22.5" + } + }, + { + "package": "nanopb", + "repositoryURL": "https://github.com/firebase/nanopb.git", + "state": { + "branch": null, + "revision": "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version": "2.30910.0" + } + }, + { + "package": "Promises", + "repositoryURL": "https://github.com/google/promises.git", + "state": { + "branch": null, + "revision": "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version": "2.4.0" + } + }, + { + "package": "SwiftProtobuf", + "repositoryURL": "https://github.com/apple/swift-protobuf.git", + "state": { + "branch": null, + "revision": "ebc7251dd5b37f627c93698e4374084d98409633", + "version": "1.28.2" + } + } + ] + }, + "version": 1 +} diff --git a/sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift b/sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift index b0c80f51a..63f834bd2 100644 --- a/sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift +++ b/sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift @@ -10,9 +10,11 @@ import UIKit import UserNotifications import IterableSDK +import Firebase +import FirebaseMessaging @UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate { var window: UIWindow? // ITBL: Set your actual api key here. @@ -21,12 +23,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // ITBL: Setup Notification setupNotifications() + FirebaseApp.configure() + Messaging.messaging().delegate = self // ITBL: Initialize API let config = IterableConfig() config.customActionDelegate = self config.urlDelegate = self config.inAppDisplayInterval = 1 + config.useFirebaseMessaging = true IterableAPI.initialize(apiKey: iterableApiKey, launchOptions: launchOptions, @@ -103,7 +108,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // ITBL: func application(_: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { - IterableAPI.register(token: deviceToken) + if !deviceToken.hexString.isEmpty { + Messaging.messaging().apnsToken = deviceToken + } } func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError _: Error) {} @@ -132,8 +139,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } } + + @objc func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { + print("Firebase token: \(String(describing: fcmToken))") + if let token = fcmToken { + IterableAPI.registerFCM(token: token) + } + } } + // MARK: UNUserNotificationCenterDelegate extension AppDelegate: UNUserNotificationCenterDelegate { @@ -171,3 +186,9 @@ extension AppDelegate: IterableCustomActionDelegate { return false } } + +extension Data { + public var hexString: String { + return map { String(format: "%02.2hhx", arguments: [$0]) }.joined() + } +} diff --git a/sample-apps/swift-sample-app/swift-sample-app/GoogleService-Info.plist b/sample-apps/swift-sample-app/swift-sample-app/GoogleService-Info.plist new file mode 100644 index 000000000..d1d4e4b5c --- /dev/null +++ b/sample-apps/swift-sample-app/swift-sample-app/GoogleService-Info.plist @@ -0,0 +1,32 @@ + + + + + API_KEY + AIzaSyAOMvZoqR3wLy75ETMsPuJd_rjrhOoRfEk + GCM_SENDER_ID + 637451244049 + PLIST_VERSION + 1 + BUNDLE_ID + com.iterable.swift-sample-app + PROJECT_ID + iterable-firebase-test + STORAGE_BUCKET + iterable-firebase-test.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:637451244049:ios:5d196ab0b47b42640457b0 + DATABASE_URL + https://iterable-firebase-test.firebaseio.com + + \ No newline at end of file diff --git a/swift-sdk/Core/Constants.swift b/swift-sdk/Core/Constants.swift index 7b2797ba2..1a4215345 100644 --- a/swift-sdk/Core/Constants.swift +++ b/swift-sdk/Core/Constants.swift @@ -280,6 +280,8 @@ enum JsonValue { static let applicationJson = "application/json" static let apnsSandbox = "APNS_SANDBOX" static let apnsProduction = "APNS" + static let gcmSandbox = "GCM" + static let gcmProduction = "GCM" static let iOS = "iOS" static let bearer = "Bearer" @@ -366,6 +368,12 @@ extension String: JsonValueRepresentable { } } +extension String { + func toJsonDict() -> [AnyHashable: Any] { + try! JSONSerialization.jsonObject(with: data(using: .utf8)!, options: []) as! [AnyHashable: Any] + } +} + extension Bool: JsonValueRepresentable { public var jsonValue: Any { self diff --git a/swift-sdk/Internal/InternalIterableAPI.swift b/swift-sdk/Internal/InternalIterableAPI.swift index 9c6aca25f..deb8d9587 100644 --- a/swift-sdk/Internal/InternalIterableAPI.swift +++ b/swift-sdk/Internal/InternalIterableAPI.swift @@ -199,8 +199,10 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider { deviceAttributes: deviceAttributes, sdkVersion: localStorage.sdkVersion, mobileFrameworkInfo: mobileFrameworkInfo) + requestHandler.register(registerTokenInfo: registerTokenInfo, notificationStateProvider: notificationStateProvider, + fcmEnabled: config.useFirebaseMessaging, onSuccess: { (_ data: [AnyHashable: Any]?) in self._successCallback?(data) onSuccess?(data) diff --git a/swift-sdk/Internal/InternalIterableAppIntegration.swift b/swift-sdk/Internal/InternalIterableAppIntegration.swift index fb5280b96..42aad86d1 100644 --- a/swift-sdk/Internal/InternalIterableAppIntegration.swift +++ b/swift-sdk/Internal/InternalIterableAppIntegration.swift @@ -315,7 +315,14 @@ struct InternalIterableAppIntegration { // Normally itblValue would be the value stored in "itbl" key inside of userInfo. // But it is possible to save them at root level for debugging purpose. private static func itblValue(fromUserInfo userInfo: [AnyHashable: Any]) -> [AnyHashable: Any]? { - let itbl = userInfo[JsonKey.Payload.metadata] as? [AnyHashable: Any] + var itbl: [AnyHashable: Any]? = nil + if let itblData = userInfo[JsonKey.Payload.metadata] as? [AnyHashable: Any] { + itbl = itblData + } else if let itblString = userInfo[JsonKey.Payload.metadata] as? String { + itbl = itblString.toJsonDict() + } else { + return nil + } #if DEBUG guard let value = itbl else { diff --git a/swift-sdk/Internal/RequestHandlerProtocol.swift b/swift-sdk/Internal/RequestHandlerProtocol.swift index a904bf3be..832d3368d 100644 --- a/swift-sdk/Internal/RequestHandlerProtocol.swift +++ b/swift-sdk/Internal/RequestHandlerProtocol.swift @@ -14,6 +14,7 @@ protocol RequestHandlerProtocol: AnyObject { func register(registerTokenInfo: RegisterTokenInfo, notificationStateProvider: NotificationStateProviderProtocol, + fcmEnabled: Bool, onSuccess: OnSuccessHandler?, onFailure: OnFailureHandler?) diff --git a/swift-sdk/Internal/api-client/ApiClient.swift b/swift-sdk/Internal/api-client/ApiClient.swift index 26aebf1d9..7c4ae0d63 100644 --- a/swift-sdk/Internal/api-client/ApiClient.swift +++ b/swift-sdk/Internal/api-client/ApiClient.swift @@ -96,9 +96,9 @@ class ApiClient { // MARK: - API REQUEST CALLS extension ApiClient: ApiClientProtocol { - func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool) -> Pending { + func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool, fcmEnabled: Bool) -> Pending { let result = createRequestCreator().flatMap { $0.createRegisterTokenRequest(registerTokenInfo: registerTokenInfo, - notificationsEnabled: notificationsEnabled) } + notificationsEnabled: notificationsEnabled, fcmEnabled: fcmEnabled) } return send(iterableRequestResult: result) } diff --git a/swift-sdk/Internal/api-client/ApiClientProtocol.swift b/swift-sdk/Internal/api-client/ApiClientProtocol.swift index ce3f377a6..3549006e0 100644 --- a/swift-sdk/Internal/api-client/ApiClientProtocol.swift +++ b/swift-sdk/Internal/api-client/ApiClientProtocol.swift @@ -5,7 +5,7 @@ import Foundation protocol ApiClientProtocol: AnyObject { - func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool) -> Pending + func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool, fcmEnabled: Bool) -> Pending func updateUser(_ dataFields: [AnyHashable: Any], mergeNestedObjects: Bool) -> Pending diff --git a/swift-sdk/Internal/api-client/Request/OnlineRequestProcessor.swift b/swift-sdk/Internal/api-client/Request/OnlineRequestProcessor.swift index af0a1d8c7..16402d7ca 100644 --- a/swift-sdk/Internal/api-client/Request/OnlineRequestProcessor.swift +++ b/swift-sdk/Internal/api-client/Request/OnlineRequestProcessor.swift @@ -24,11 +24,13 @@ struct OnlineRequestProcessor: RequestProcessorProtocol { func register(registerTokenInfo: RegisterTokenInfo, notificationStateProvider: NotificationStateProviderProtocol, + fcmEnabled: Bool, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) { notificationStateProvider.isNotificationsEnabled { enabled in self.register(registerTokenInfo: registerTokenInfo, notificationsEnabled: enabled, + fcmEnabled: fcmEnabled, onSuccess: onSuccess, onFailure: onFailure) } @@ -293,10 +295,11 @@ struct OnlineRequestProcessor: RequestProcessorProtocol { @discardableResult private func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool, + fcmEnabled: Bool, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) -> Pending { sendRequest(requestProvider: { apiClient.register(registerTokenInfo: registerTokenInfo, - notificationsEnabled: notificationsEnabled) }, + notificationsEnabled: notificationsEnabled, fcmEnabled: fcmEnabled) }, successHandler: onSuccess, failureHandler: onFailure, requestIdentifier: "registerToken") diff --git a/swift-sdk/Internal/api-client/Request/RequestCreator.swift b/swift-sdk/Internal/api-client/Request/RequestCreator.swift index 9a14fba24..3b0bcb218 100644 --- a/swift-sdk/Internal/api-client/Request/RequestCreator.swift +++ b/swift-sdk/Internal/api-client/Request/RequestCreator.swift @@ -34,7 +34,7 @@ struct RequestCreator { } func createRegisterTokenRequest(registerTokenInfo: RegisterTokenInfo, - notificationsEnabled: Bool) -> Result { + notificationsEnabled: Bool, fcmEnabled: Bool) -> Result { if case .none = auth.emailOrUserId { ITBError(Self.authMissingMessage) return .failure(IterableError.general(description: Self.authMissingMessage)) @@ -51,7 +51,7 @@ struct RequestCreator { let deviceDictionary: [String: Any] = [ JsonKey.token: registerTokenInfo.hexToken, JsonKey.platform: RequestCreator.pushServicePlatformToString(registerTokenInfo.pushServicePlatform, - apnsType: registerTokenInfo.apnsType), + apnsType: registerTokenInfo.apnsType, fcmEnabled: fcmEnabled), JsonKey.applicationName: registerTokenInfo.appName, JsonKey.dataFields: dataFields ] @@ -595,14 +595,18 @@ struct RequestCreator { args: args) } - private static func pushServicePlatformToString(_ pushServicePlatform: PushServicePlatform, apnsType: APNSType) -> String { + private static func pushServicePlatformToString(_ pushServicePlatform: PushServicePlatform, apnsType: APNSType, fcmEnabled: Bool) -> String { switch pushServicePlatform { case .production: - return JsonValue.apnsProduction + return fcmEnabled ? JsonValue.gcmProduction : JsonValue.apnsProduction case .sandbox: - return JsonValue.apnsSandbox + return fcmEnabled ? JsonValue.gcmSandbox : JsonValue.apnsSandbox case .auto: - return apnsType == .sandbox ? JsonValue.apnsSandbox : JsonValue.apnsProduction + if apnsType == .sandbox { + return fcmEnabled ? JsonValue.gcmSandbox : JsonValue.apnsSandbox + } else { + return fcmEnabled ? JsonValue.gcmProduction : JsonValue.apnsProduction + } } } diff --git a/swift-sdk/Internal/api-client/Request/RequestHandler.swift b/swift-sdk/Internal/api-client/Request/RequestHandler.swift index 913844cef..3d35cf3c1 100644 --- a/swift-sdk/Internal/api-client/Request/RequestHandler.swift +++ b/swift-sdk/Internal/api-client/Request/RequestHandler.swift @@ -39,10 +39,12 @@ class RequestHandler: RequestHandlerProtocol { func register(registerTokenInfo: RegisterTokenInfo, notificationStateProvider: NotificationStateProviderProtocol, + fcmEnabled: Bool, onSuccess: OnSuccessHandler?, onFailure: OnFailureHandler?) { onlineProcessor.register(registerTokenInfo: registerTokenInfo, notificationStateProvider: notificationStateProvider, + fcmEnabled: fcmEnabled, onSuccess: onSuccess, onFailure: onFailure) } diff --git a/swift-sdk/SDK/IterableAPI.swift b/swift-sdk/SDK/IterableAPI.swift index 380a1c1eb..a338ed155 100644 --- a/swift-sdk/SDK/IterableAPI.swift +++ b/swift-sdk/SDK/IterableAPI.swift @@ -238,6 +238,11 @@ import UIKit implementation?.register(token: token) } + @objc(registerFCMToken:) + public static func registerFCM(token: String) { + implementation?.register(token: token) + } + /// Register this device's token with Iterable /// /// Push integration name and platform are read from `IterableConfig`. If platform is set to `auto`, it will @@ -256,6 +261,12 @@ import UIKit implementation?.register(token: token, onSuccess: onSuccess, onFailure: onFailure) } + @objc(registerFCMToken:onSuccess:OnFailure:) + public static func registerFCM(token: String, onSuccess: OnSuccessHandler? = nil, onFailure: OnFailureHandler? = nil) { + guard let implementation, implementation.isSDKInitialized() else { return } + implementation.register(token: token, onSuccess: onSuccess, onFailure: onFailure) + } + @objc(pauseAuthRetries:) public static func pauseAuthRetries(_ pauseRetry: Bool) { implementation?.authManager.pauseAuthRetries(pauseRetry) diff --git a/swift-sdk/SDK/IterableConfig.swift b/swift-sdk/SDK/IterableConfig.swift index 62f89c14e..f18ce4513 100644 --- a/swift-sdk/SDK/IterableConfig.swift +++ b/swift-sdk/SDK/IterableConfig.swift @@ -152,5 +152,8 @@ public class IterableConfig: NSObject { /// The type of mobile framework we are using. public var mobileFrameworkInfo: IterableAPIMobileFrameworkInfo? + + /// Sets whether firebase messaging is used + public var useFirebaseMessaging = false } diff --git a/tests/offline-events-tests/RequestHandlerTests.swift b/tests/offline-events-tests/RequestHandlerTests.swift index 4b4d7122d..072973bc4 100644 --- a/tests/offline-events-tests/RequestHandlerTests.swift +++ b/tests/offline-events-tests/RequestHandlerTests.swift @@ -70,6 +70,7 @@ class RequestHandlerTests: XCTestCase { selectOffline: false) requestHandler.register(registerTokenInfo: registerTokenInfo, notificationStateProvider: MockNotificationStateProvider(enabled: true), + fcmEnabled: false, onSuccess: nil, onFailure: nil) diff --git a/tests/unit-tests/BlankApiClient.swift b/tests/unit-tests/BlankApiClient.swift index 5ce30d227..4ef9fe220 100644 --- a/tests/unit-tests/BlankApiClient.swift +++ b/tests/unit-tests/BlankApiClient.swift @@ -7,7 +7,7 @@ import Foundation @testable import IterableSDK class BlankApiClient: ApiClientProtocol { - func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool) -> Pending { + func register(registerTokenInfo: RegisterTokenInfo, notificationsEnabled: Bool, fcmEnabled: Bool) -> Pending { Pending() } diff --git a/tests/unit-tests/RequestCreatorTests.swift b/tests/unit-tests/RequestCreatorTests.swift index c9b53dcf2..279e1cd92 100644 --- a/tests/unit-tests/RequestCreatorTests.swift +++ b/tests/unit-tests/RequestCreatorTests.swift @@ -334,7 +334,7 @@ class RequestCreatorTests: XCTestCase { mobileFrameworkInfo: IterableAPIMobileFrameworkInfo(frameworkType: .native, iterableSdkVersion: testSdkVersion)) let urlRequest = convertToUrlRequest(userIdRequestCreator.createRegisterTokenRequest(registerTokenInfo: registerTokenInfo, - notificationsEnabled: true)) + notificationsEnabled: true, fcmEnabled: false)) TestUtils.validateHeader(urlRequest, apiKey) TestUtils.validate(request: urlRequest, requestType: .post, apiEndPoint: Endpoint.api, path: Const.Path.registerDeviceToken)