diff --git a/.package.resolved b/.package.resolved new file mode 100644 index 0000000..dd6758d --- /dev/null +++ b/.package.resolved @@ -0,0 +1,122 @@ +{ + "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c", + "version" : "1.2022062300.0" + } + }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "5746b2d35c91c50581590ed97abe4c06b5037274", + "version" : "10.18.0" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk.git", + "state" : { + "revision" : "5de0369ee79ad096c164eb3afeb7921d92a43b58", + "version" : "10.18.0" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "6b332152355c372ace9966d8ee76ed191f97025e", + "version" : "10.17.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "a732a4b47f59e4f725a2ea10f0c77e93a7131117", + "version" : "9.3.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "bc27fad73504f3d4af235de451f02ee22586ebd3", + "version" : "7.12.1" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "a673bc2937fbe886dd1f99c401b01b6d977a9c98", + "version" : "1.49.1" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "115f75e43851774934d695449a4836123c3246e1", + "version" : "3.2.0" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "9d108e9112aa1d65ce508facf804674546116d9c", + "version" : "1.22.3" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692", + "version" : "2.30909.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "e70e889c0196c76d22759eb50d6a0270ca9f1d9e", + "version" : "2.3.1" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8", + "version" : "1.25.2" + } + } + ], + "version" : 2 +} diff --git a/Application/GoogleService-Info.plist b/Application/GoogleService-Info.plist new file mode 100644 index 0000000..7d3e351 --- /dev/null +++ b/Application/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyATZppwDY1GHvots-hPpx9mIUK9yRg_oOY + GCM_SENDER_ID + 486766481885 + PLIST_VERSION + 1 + BUNDLE_ID + com.Sharing.iOS.app + PROJECT_ID + sharing-f3952 + STORAGE_BUCKET + sharing-f3952.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:486766481885:ios:a4c5eedbc5c67b32e16634 + + \ No newline at end of file diff --git a/Application/Project.swift b/Application/Project.swift index ebe048a..7fc6c16 100644 --- a/Application/Project.swift +++ b/Application/Project.swift @@ -10,7 +10,7 @@ let project = Project( name: "Sharing-iOS", platform: .iOS, product: .app, - bundleId: "\(SharingOrganizationName).iOS.app", + bundleId: "\(SharingOrganizationName).iOS.application", deploymentTarget: .iOS( targetVersion: "16.0", devices: [.iphone, .ipad] @@ -18,8 +18,10 @@ let project = Project( infoPlist: .file(path: "SuportingFile/Info.plist"), sources: ["Sources/**"], resources: ["Resources/**"], + entitlements: Path("SuportingFile/Sharing-iOS.entitlements"), dependencies: [ - .Project.appFlow + .Project.appFlow, + .SPM.FCM ] ) ] diff --git a/Application/Resources/GoogleService-Info.plist b/Application/Resources/GoogleService-Info.plist new file mode 100644 index 0000000..67b93f7 --- /dev/null +++ b/Application/Resources/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyAjsWhMl6Xgf3isTff2Gb73ru5Wr6AZOhA + GCM_SENDER_ID + 62697569879 + PLIST_VERSION + 1 + BUNDLE_ID + com.Sharing.iOS.application + PROJECT_ID + sharing-9d490 + STORAGE_BUCKET + sharing-9d490.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:62697569879:ios:9ebc870511d5ca5a9ced12 + + \ No newline at end of file diff --git a/Application/Sources/Application/AppDelegate.swift b/Application/Sources/Application/AppDelegate.swift index 76443e7..8b4f59b 100644 --- a/Application/Sources/Application/AppDelegate.swift +++ b/Application/Sources/Application/AppDelegate.swift @@ -1,15 +1,65 @@ import UIKit +import FirebaseCore +import FirebaseMessaging @main -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + FirebaseApp.configure() + self.setFCM(application) + return true } + func setFCM(_ application: UIApplication) { + if #available(iOS 12.0, *) { + UNUserNotificationCenter.current().requestAuthorization( + options: [.alert, .sound, .badge, .providesAppNotificationSettings], completionHandler: { didAllow,Error in + }) + } else { + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: { didAllow,Error in + }) + } + UNUserNotificationCenter.current().delegate = self + Messaging.messaging().delegate = self + application.registerForRemoteNotifications() + } + + func application( + _ application: UIApplication, + didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data + ) { + Messaging.messaging().apnsToken = deviceToken + } + + public func messaging( + _ messaging: Messaging, + didReceiveRegistrationToken fcmToken: String? + ) { + let firebaseToken = fcmToken ?? "" + UserDefaults.standard.set(firebaseToken, forKey: "firebaseToken") + } + + public func userNotificationCenter( + _ center: UNUserNotificationCenter, + willPresent notification: UNNotification, + withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void + ) { + completionHandler([.badge, .sound, .banner, .list]) + } + + public func userNotificationCenter( + _ center: UNUserNotificationCenter, + didReceive response: UNNotificationResponse, + withCompletionHandler completionHandler: @escaping () -> Void + ) { + completionHandler() + } + // MARK: UISceneSession Lifecycle func application( diff --git a/Application/SuportingFile/GoogleService-Info.plist b/Application/SuportingFile/GoogleService-Info.plist new file mode 100644 index 0000000..7d3e351 --- /dev/null +++ b/Application/SuportingFile/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyATZppwDY1GHvots-hPpx9mIUK9yRg_oOY + GCM_SENDER_ID + 486766481885 + PLIST_VERSION + 1 + BUNDLE_ID + com.Sharing.iOS.app + PROJECT_ID + sharing-f3952 + STORAGE_BUCKET + sharing-f3952.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:486766481885:ios:a4c5eedbc5c67b32e16634 + + \ No newline at end of file diff --git a/Application/SuportingFile/Info.plist b/Application/SuportingFile/Info.plist index b661e4b..d798307 100644 --- a/Application/SuportingFile/Info.plist +++ b/Application/SuportingFile/Info.plist @@ -2,6 +2,8 @@ + FirebaseAppDelegateProxyEnabled + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable @@ -52,6 +54,10 @@ UIApplicationSupportsIndirectInputEvents + UIBackgroundModes + + remote-notification + UILaunchStoryboardName Launch Screen.storyboard UIRequiredDeviceCapabilities diff --git a/Application/SuportingFile/Sharing-iOS.entitlements b/Application/SuportingFile/Sharing-iOS.entitlements new file mode 100644 index 0000000..903def2 --- /dev/null +++ b/Application/SuportingFile/Sharing-iOS.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/Modules/AppNetwork/Sources/Auth/Remote/API/AuthAPI.swift b/Modules/AppNetwork/Sources/Auth/Remote/API/AuthAPI.swift index 0e82c34..89c260e 100644 --- a/Modules/AppNetwork/Sources/Auth/Remote/API/AuthAPI.swift +++ b/Modules/AppNetwork/Sources/Auth/Remote/API/AuthAPI.swift @@ -3,7 +3,7 @@ import Moya import Core public enum AuthAPI { - case login(accountID: String, password: String) + case login(accountID: String, password: String, deviceToken: String) case signup(accountID: String, password: String, name: String, age: Int) } @@ -30,15 +30,16 @@ extension AuthAPI: TargetType { public var task: Moya.Task { switch self { - case .login(let accountID, let password): + case let .login(accountID, password, deviceToken): return .requestParameters( parameters: [ "account_id": accountID, - "password": password + "password": password, + "device_token": deviceToken ], encoding: JSONEncoding.default) - case .signup(let accountID, let password, let name, let age): + case let .signup(accountID, password, name, age): return .requestParameters( parameters: [ "account_id": accountID, diff --git a/Plugins/DependencyHelper/ProjectDescriptionHelpers/Dependency+SPM.swift b/Plugins/DependencyHelper/ProjectDescriptionHelpers/Dependency+SPM.swift index 376ec5b..8ca2a3b 100644 --- a/Plugins/DependencyHelper/ProjectDescriptionHelpers/Dependency+SPM.swift +++ b/Plugins/DependencyHelper/ProjectDescriptionHelpers/Dependency+SPM.swift @@ -16,4 +16,5 @@ public extension TargetDependency.SPM { static let Kingfisher = TargetDependency.external(name: "Kingfisher") static let SocketIO = TargetDependency.external(name: "SocketIO") static let FloatingPanel = TargetDependency.external(name: "FloatingPanel") + static let FCM = TargetDependency.external(name: "FirebaseMessaging") } diff --git a/Projects/Data/Sources/Auth/DataSource/AuthDataSource.swift b/Projects/Data/Sources/Auth/DataSource/AuthDataSource.swift index 117a2e3..7473083 100644 --- a/Projects/Data/Sources/Auth/DataSource/AuthDataSource.swift +++ b/Projects/Data/Sources/Auth/DataSource/AuthDataSource.swift @@ -12,8 +12,8 @@ class AuthDataSource { static let shared = AuthDataSource() private init() {} - func login(accountID: String, password: String) -> Single { - return provider.rx.request(.login(accountID: accountID, password: password)) + func login(accountID: String, password: String, deviceToken: String) -> Single { + return provider.rx.request(.login(accountID: accountID, password: password, deviceToken: deviceToken)) .filterSuccessfulStatusCodes() .map(TokenDTO.self) .catch { .error($0.toError(AuthError.self)) } diff --git a/Projects/Data/Sources/Auth/Repository/AuthRepositoryImpl.swift b/Projects/Data/Sources/Auth/Repository/AuthRepositoryImpl.swift index 3f30ced..00a5bef 100644 --- a/Projects/Data/Sources/Auth/Repository/AuthRepositoryImpl.swift +++ b/Projects/Data/Sources/Auth/Repository/AuthRepositoryImpl.swift @@ -4,6 +4,7 @@ import Domain import AppNetwork import Core import Moya +import FirebaseMessaging class AuthRepositoryImpl: AuthRepository { @@ -11,11 +12,13 @@ class AuthRepositoryImpl: AuthRepository { private var disposeBag = DisposeBag() func login(accountID: String, password: String) -> Completable { + return Completable.create { [weak self] completable in guard let self = self else { return Disposables.create {} } + let fcmToken = self.fetchDeviceToken() - self.authDataSource.login(accountID: accountID, password: password) + self.authDataSource.login(accountID: accountID, password: password, deviceToken: fcmToken) .subscribe(onSuccess: { tokenData in TokenStorage.shared.accessToken = tokenData.accessToken TokenStorage.shared.refreshToken = tokenData.refreshToken @@ -34,3 +37,9 @@ class AuthRepositoryImpl: AuthRepository { .asCompletable() } } + +extension AuthRepositoryImpl { + func fetchDeviceToken() -> String { + return UserDefaults.standard.string(forKey: "firebaseToken") ?? "" + } +} diff --git a/Tuist/Dependencies.swift b/Tuist/Dependencies.swift index d8411a1..1ac2d40 100644 --- a/Tuist/Dependencies.swift +++ b/Tuist/Dependencies.swift @@ -44,6 +44,11 @@ let dependencies = Dependencies.init( .remote( url: "https://github.com/scenee/FloatingPanel.git", requirement: .upToNextMajor(from: "2.8.0") + ), + // Firebase-iOS-sdk + .remote( + url: "https://github.com/firebase/firebase-ios-sdk.git", + requirement: .upToNextMajor(from: "10.3.0") ) ]), platforms: [.iOS]