From 8098ae108e59d3170f88379d8aa51363036ea5eb Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sat, 12 Feb 2022 01:20:35 -0600 Subject: WIP: FCM notifications (not working) --- iosApp/.gitignore | 6 +- iosApp/iosApp.xcodeproj/project.pbxproj | 37 ++++++- .../xcshareddata/swiftpm/Package.resolved | 108 +++++++++++++++++++++ iosApp/iosApp/AppDelegate.swift | 59 +++++++++++ iosApp/iosApp/Info.plist | 4 + iosApp/iosApp/Session/RootView.swift | 10 +- iosApp/iosApp/iOSApp.swift | 1 + iosApp/iosApp/iosApp.entitlements | 8 ++ 8 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 iosApp/iosApp/AppDelegate.swift create mode 100644 iosApp/iosApp/iosApp.entitlements diff --git a/iosApp/.gitignore b/iosApp/.gitignore index 1342544..cfbc7b3 100644 --- a/iosApp/.gitignore +++ b/iosApp/.gitignore @@ -88,4 +88,8 @@ fastlane/test_output # After new code Injection tools there's a generated folder /iOSInjectionProject # https://github.com/johnno1962/injectionforxcode -iOSInjectionProject/ \ No newline at end of file +iOSInjectionProject/ + +# Firebase + +GoogleService-Info.plist diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj index 2be5d57..b3e7b29 100644 --- a/iosApp/iosApp.xcodeproj/project.pbxproj +++ b/iosApp/iosApp.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ E33A237327A7581A00DD647F /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = E33A237227A7581A00DD647F /* Utils.swift */; }; E34A2F4827A7878200AD8AEB /* HyperlinkText.swift in Sources */ = {isa = PBXBuildFile; fileRef = E34A2F4727A7878200AD8AEB /* HyperlinkText.swift */; }; E34A2F4D27A7DB2200AD8AEB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E34A2F4C27A7DB2200AD8AEB /* Localizable.strings */; }; + E36A5A8627B4BFC40070DED5 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = E36A5A8527B4BFC40070DED5 /* FirebaseMessaging */; }; E36DF77B27AB740C003C561C /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E36DF77927AB740C003C561C /* MapViewController.swift */; }; E36DF77C27AB740C003C561C /* MapViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E36DF77A27AB740C003C561C /* MapViewController.xib */; }; E38F241527A242870069FC45 /* Inject.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241427A242870069FC45 /* Inject.swift */; }; @@ -28,6 +29,8 @@ E38F241C27A26DD70069FC45 /* RootViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241B27A26DD70069FC45 /* RootViewModel.swift */; }; E38F241E27A270D50069FC45 /* UnitsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241D27A270D50069FC45 /* UnitsView.swift */; }; E38F242027A27B550069FC45 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E38F241F27A27B550069FC45 /* LoadingView.swift */; }; + E392BE1727B77B7E002698F3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E392BE1627B77B7E002698F3 /* AppDelegate.swift */; }; + E392BE1927B791F0002698F3 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E392BE1827B791F0002698F3 /* GoogleService-Info.plist */; }; E396281D27AF5723005D070E /* WhirlyGlobe.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = E396281B27AF56BA005D070E /* WhirlyGlobe.xcframework */; }; E396281E27AF5723005D070E /* WhirlyGlobe.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E396281B27AF56BA005D070E /* WhirlyGlobe.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E396282027AF59F2005D070E /* DetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E396281F27AF59F2005D070E /* DetailsView.swift */; }; @@ -70,6 +73,7 @@ E33A237227A7581A00DD647F /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; E34A2F4727A7878200AD8AEB /* HyperlinkText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HyperlinkText.swift; sourceTree = ""; }; E34A2F4C27A7DB2200AD8AEB /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; + E36A5A8927B4C8BB0070DED5 /* iosApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = iosApp.entitlements; sourceTree = ""; }; E36DF77927AB740C003C561C /* MapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = ""; }; E36DF77A27AB740C003C561C /* MapViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MapViewController.xib; sourceTree = ""; }; E38F241427A242870069FC45 /* Inject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Inject.swift; sourceTree = ""; }; @@ -77,6 +81,8 @@ E38F241B27A26DD70069FC45 /* RootViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewModel.swift; sourceTree = ""; }; E38F241D27A270D50069FC45 /* UnitsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitsView.swift; sourceTree = ""; }; E38F241F27A27B550069FC45 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = ""; }; + E392BE1627B77B7E002698F3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E392BE1827B791F0002698F3 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; E396281B27AF56BA005D070E /* WhirlyGlobe.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = WhirlyGlobe.xcframework; sourceTree = ""; }; E396281F27AF59F2005D070E /* DetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailsView.swift; sourceTree = ""; }; E396282327AFBD3D005D070E /* UnitInformationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitInformationView.swift; sourceTree = ""; }; @@ -93,6 +99,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E36A5A8627B4BFC40070DED5 /* FirebaseMessaging in Frameworks */, E33A236A27A6898700DD647F /* SwiftUIX in Frameworks */, E396281D27AF5723005D070E /* WhirlyGlobe.xcframework in Frameworks */, ); @@ -129,6 +136,8 @@ 7555FF7D242A565900829871 /* iosApp */ = { isa = PBXGroup; children = ( + E392BE1827B791F0002698F3 /* GoogleService-Info.plist */, + E36A5A8927B4C8BB0070DED5 /* iosApp.entitlements */, E34A2F4C27A7DB2200AD8AEB /* Localizable.strings */, E33A235E27A4FD1C00DD647F /* Map */, E35A078427AB615F00F24D71 /* Details */, @@ -139,6 +148,7 @@ E3E77EE0279D43B400150070 /* Session */, 7555FF8C242A565B00829871 /* Info.plist */, 2152FB032600AC8F00CF470E /* iOSApp.swift */, + E392BE1627B77B7E002698F3 /* AppDelegate.swift */, 058557D7273AAEEB004C7B11 /* Preview Content */, ); path = iosApp; @@ -262,6 +272,7 @@ name = iosApp; packageProductDependencies = ( E33A236927A6898700DD647F /* SwiftUIX */, + E36A5A8527B4BFC40070DED5 /* FirebaseMessaging */, ); productName = iosApp; productReference = 7555FF7B242A565900829871 /* iosApp.app */; @@ -295,6 +306,7 @@ mainGroup = 7555FF72242A565900829871; packageReferences = ( E33A236827A6898700DD647F /* XCRemoteSwiftPackageReference "SwiftUIX" */, + E36A5A8427B4BFC40070DED5 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); productRefGroup = 7555FF7C242A565900829871 /* Products */; projectDirPath = ""; @@ -312,6 +324,7 @@ files = ( 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, E34A2F4D27A7DB2200AD8AEB /* Localizable.strings in Resources */, + E392BE1927B791F0002698F3 /* GoogleService-Info.plist in Resources */, 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, E36DF77C27AB740C003C561C /* MapViewController.xib in Resources */, ); @@ -357,6 +370,7 @@ E396282827AFBD72005D070E /* UnitCommandsView.swift in Sources */, E38F241C27A26DD70069FC45 /* RootViewModel.swift in Sources */, E3385A4F27B0D8A10025311C /* UnitCommandsViewModel.swift in Sources */, + E392BE1727B77B7E002698F3 /* AppDelegate.swift in Sources */, E36DF77B27AB740C003C561C /* MapViewController.swift in Sources */, E33A237327A7581A00DD647F /* Utils.swift in Sources */, E3E77EE6279E6CE400150070 /* FlowCollector.swift in Sources */, @@ -495,6 +509,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = iosApp/iosApp.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; DEVELOPMENT_TEAM = 358YRZ9P3L; @@ -514,8 +530,9 @@ "-framework", shared, ); - PRODUCT_BUNDLE_IDENTIFIER = mx.trackermap.TrackerMap; + PRODUCT_BUNDLE_IDENTIFIER = mx.trackermap.trackermap.ios; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -528,6 +545,8 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = iosApp/iosApp.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; DEVELOPMENT_TEAM = 358YRZ9P3L; @@ -547,8 +566,9 @@ "-framework", shared, ); - PRODUCT_BUNDLE_IDENTIFIER = mx.trackermap.TrackerMap; + PRODUCT_BUNDLE_IDENTIFIER = mx.trackermap.trackermap.ios; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -587,6 +607,14 @@ kind = branch; }; }; + E36A5A8427B4BFC40070DED5 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 8.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -595,6 +623,11 @@ package = E33A236827A6898700DD647F /* XCRemoteSwiftPackageReference "SwiftUIX" */; productName = SwiftUIX; }; + E36A5A8527B4BFC40070DED5 /* FirebaseMessaging */ = { + isa = XCSwiftPackageProductDependency; + package = E36A5A8427B4BFC40070DED5 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseMessaging; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 7555FF73242A565900829871 /* Project object */; diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9e38855..7032494 100644 --- a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,114 @@ { "object": { "pins": [ + { + "package": "abseil", + "repositoryURL": "https://github.com/firebase/abseil-cpp-SwiftPM.git", + "state": { + "branch": null, + "revision": "fffc3c2729be5747390ad02d5100291a0d9ad26a", + "version": "0.20200225.4" + } + }, + { + "package": "BoringSSL-GRPC", + "repositoryURL": "https://github.com/firebase/boringssl-SwiftPM.git", + "state": { + "branch": null, + "revision": "734a8247442fde37df4364c21f6a0085b6a36728", + "version": "0.7.2" + } + }, + { + "package": "Firebase", + "repositoryURL": "https://github.com/firebase/firebase-ios-sdk.git", + "state": { + "branch": null, + "revision": "78f7087fd5d48eb7c36e299f330b6dddccd647b2", + "version": "8.12.1" + } + }, + { + "package": "GoogleAppMeasurement", + "repositoryURL": "https://github.com/google/GoogleAppMeasurement.git", + "state": { + "branch": null, + "revision": "6cc2991c11872510a5314bc112cc7558dd9d046a", + "version": "8.12.0" + } + }, + { + "package": "GoogleDataTransport", + "repositoryURL": "https://github.com/google/GoogleDataTransport.git", + "state": { + "branch": null, + "revision": "15ccdfd25ac55b9239b82809531ff26605e7556e", + "version": "9.1.2" + } + }, + { + "package": "GoogleUtilities", + "repositoryURL": "https://github.com/google/GoogleUtilities.git", + "state": { + "branch": null, + "revision": "b3bb0c5551fb3f80ca939829639ab5b093edd14f", + "version": "7.7.0" + } + }, + { + "package": "gRPC", + "repositoryURL": "https://github.com/firebase/grpc-SwiftPM.git", + "state": { + "branch": null, + "revision": "fb405dd2c7901485f7e158b24e3a0a47e4efd8b5", + "version": "1.28.4" + } + }, + { + "package": "GTMSessionFetcher", + "repositoryURL": "https://github.com/google/gtm-session-fetcher.git", + "state": { + "branch": null, + "revision": "bc6a19702ac76ac4e488b68148710eb815f9bc56", + "version": "1.7.0" + } + }, + { + "package": "leveldb", + "repositoryURL": "https://github.com/firebase/leveldb.git", + "state": { + "branch": null, + "revision": "0706abcc6b0bd9cedfbb015ba840e4a780b5159b", + "version": "1.22.2" + } + }, + { + "package": "nanopb", + "repositoryURL": "https://github.com/firebase/nanopb.git", + "state": { + "branch": null, + "revision": "7ee9ef9f627d85cbe1b8c4f49a3ed26eed216c77", + "version": "2.30908.0" + } + }, + { + "package": "Promises", + "repositoryURL": "https://github.com/google/promises.git", + "state": { + "branch": null, + "revision": "611337c330350c9c1823ad6d671e7f936af5ee13", + "version": "2.0.0" + } + }, + { + "package": "SwiftProtobuf", + "repositoryURL": "https://github.com/apple/swift-protobuf.git", + "state": { + "branch": null, + "revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", + "version": "1.18.0" + } + }, { "package": "SwiftUIX", "repositoryURL": "https://github.com/ivan-avalos/SwiftUIX", diff --git a/iosApp/iosApp/AppDelegate.swift b/iosApp/iosApp/AppDelegate.swift new file mode 100644 index 0000000..ebe88df --- /dev/null +++ b/iosApp/iosApp/AppDelegate.swift @@ -0,0 +1,59 @@ +/** + * TrackerMap + * Copyright (C) 2021-2022 Iván Ávalos , Henoch Ojeda + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import Foundation +import UIKit +import Firebase +import FirebaseMessaging + +class AppDelegate: NSObject, UIApplicationDelegate { + func applicationDidFinishLaunching(_ application: UIApplication) { + FirebaseApp.configure() + Messaging.messaging().delegate = self + + UNUserNotificationCenter.current().delegate = self + let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] + UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { _, _ in } + + application.registerForRemoteNotifications() + } + + func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult { + print(userInfo) + return UIBackgroundFetchResult.newData + } +} + +extension AppDelegate: UNUserNotificationCenterDelegate { + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { + let userInfo = notification.request.content.userInfo + print(userInfo) + return [.banner, .badge, .sound] + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async { + let userInfo = response.notification.request.content.userInfo + print(userInfo) + } +} + +extension AppDelegate: MessagingDelegate { + func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { + print ("didReceiveRegistrationToken fcmToken:\(String(describing: fcmToken))") + UserDefaults.standard.set(fcmToken, forKey: "fcmtoken") + } +} diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist index 237f735..bf9db74 100644 --- a/iosApp/iosApp/Info.plist +++ b/iosApp/iosApp/Info.plist @@ -4,6 +4,10 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + UIBackgroundModes + + remote-notification + CFBundleDisplayName TrackerMap CFBundleExecutable diff --git a/iosApp/iosApp/Session/RootView.swift b/iosApp/iosApp/Session/RootView.swift index 9f2e589..bc8a7d1 100644 --- a/iosApp/iosApp/Session/RootView.swift +++ b/iosApp/iosApp/Session/RootView.swift @@ -46,6 +46,12 @@ struct LoginContentView: View { let onLogin: (SessionBody) -> Void + func getFcmToken() -> String? { + let token = UserDefaults.standard.string(forKey: "fcmtoken") + print("FCM token is \(String(describing: token))") + return token + } + var body: some View { VStack { Spacer() @@ -60,7 +66,7 @@ struct LoginContentView: View { self.onLogin(SessionBody(url: server, email: username, password: password, - fcmToken: nil)) + fcmToken: getFcmToken())) }) { Text("login") .font(.system(size: 18)) @@ -74,6 +80,8 @@ struct LoginContentView: View { } } +// Source: https://github.com/niochat/nio + struct LoginTitleView: View { var body: some View { return VStack { diff --git a/iosApp/iosApp/iOSApp.swift b/iosApp/iosApp/iOSApp.swift index 338c06b..291f2cd 100644 --- a/iosApp/iosApp/iOSApp.swift +++ b/iosApp/iosApp/iOSApp.swift @@ -21,6 +21,7 @@ import shared @main struct iOSApp: App { + @UIApplicationDelegateAdaptor var delegate: AppDelegate init() { /* Dependency injections */ diff --git a/iosApp/iosApp/iosApp.entitlements b/iosApp/iosApp/iosApp.entitlements new file mode 100644 index 0000000..903def2 --- /dev/null +++ b/iosApp/iosApp/iosApp.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + -- cgit v1.2.3