diff --git a/Dialer/Dialer.xcodeproj/project.pbxproj b/Dialer/Dialer.xcodeproj/project.pbxproj index 76d9391..199b202 100644 --- a/Dialer/Dialer.xcodeproj/project.pbxproj +++ b/Dialer/Dialer.xcodeproj/project.pbxproj @@ -36,7 +36,6 @@ 82D41FBD25D1C1FF00551D22 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 82D41FBC25D1C1FF00551D22 /* Assets.xcassets */; }; 82D41FC025D1C1FF00551D22 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 82D41FBF25D1C1FF00551D22 /* Preview Assets.xcassets */; }; 82D41FC325D1C1FF00551D22 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 82D41FC125D1C1FF00551D22 /* LaunchScreen.storyboard */; }; - 82D7C19B266D2031003E0E0E /* CTCarrierDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D7C19A266D2031003E0E0E /* CTCarrierDetector.swift */; }; 82D7C1A7266D26E7003E0E0E /* Views+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D7C1A6266D26E7003E0E0E /* Views+Extension.swift */; }; 82E8E63B2676A7B300AB1723 /* ContactsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82E8E63A2676A7B300AB1723 /* ContactsListView.swift */; }; 82EEBCED26C12E2500B1720A /* DialerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82EEBCEC26C12E2500B1720A /* DialerTests.swift */; }; @@ -159,7 +158,6 @@ 82D41FBF25D1C1FF00551D22 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 82D41FC225D1C1FF00551D22 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 82D41FC425D1C1FF00551D22 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 82D7C19A266D2031003E0E0E /* CTCarrierDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CTCarrierDetector.swift; sourceTree = ""; }; 82D7C1A6266D26E7003E0E0E /* Views+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Views+Extension.swift"; sourceTree = ""; }; 82E8E63A2676A7B300AB1723 /* ContactsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsListView.swift; sourceTree = ""; }; 82EEBCEA26C12E2500B1720A /* DialerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DialerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -392,7 +390,6 @@ 82EEBCF426C1336000B1720A /* Utilities */ = { isa = PBXGroup; children = ( - 82D7C19A266D2031003E0E0E /* CTCarrierDetector.swift */, CB895D772806FE84002AA0BE /* BiometricAuthenticator.swift */, CB3B81E529ABD0D8001FAFF6 /* FirebaseManager.swift */, CB1CC86B29C4524200FF2116 /* FirebaseCRUD.swift */, @@ -686,7 +683,6 @@ CB18BD4529AE0C3200A7B45C /* FirebaseRemoteConfig.swift in Sources */, CB7426BF2A05C05D00BE76DF /* DeviceAccount.swift in Sources */, 82D41FB925D1C1FE00551D22 /* SceneDelegate.swift in Sources */, - 82D7C19B266D2031003E0E0E /* CTCarrierDetector.swift in Sources */, 825F996626720B46009E4A7B /* ContactsFetcher.swift in Sources */, 82D7C1A7266D26E7003E0E0E /* Views+Extension.swift in Sources */, CB393A2928120A73009CA95E /* Binding+Extension.swift in Sources */, @@ -953,7 +949,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 4.7.2; + MARKETING_VERSION = 4.7.3; PRODUCT_BUNDLE_IDENTIFIER = com.abc.incs.cedricbahirwe.Dialit; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -980,7 +976,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 4.7.2; + MARKETING_VERSION = 4.7.3; PRODUCT_BUNDLE_IDENTIFIER = com.abc.incs.cedricbahirwe.Dialit; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1114,7 +1110,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 4.7.2; + MARKETING_VERSION = 4.7.3; PRODUCT_BUNDLE_IDENTIFIER = com.abc.incs.cedricbahirwe.Dialit.dev; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1240,7 +1236,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 4.7.2; + MARKETING_VERSION = 4.7.3; PRODUCT_BUNDLE_IDENTIFIER = com.abc.incs.cedricbahirwe.Dialit.dev; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Dialer/Dialer/AppDelegate.swift b/Dialer/Dialer/AppDelegate.swift index f241b6c..0c0d77d 100644 --- a/Dialer/Dialer/AppDelegate.swift +++ b/Dialer/Dialer/AppDelegate.swift @@ -23,7 +23,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let filePath = Bundle.main.path(forResource: fileName, ofType: "plist"), let options = FirebaseOptions(contentsOfFile: filePath) else { - debugPrint("Could not find Firebase config file") + Log.debug("Could not find Firebase config file") return } diff --git a/Dialer/Dialer/Extensions/Views+Extension.swift b/Dialer/Dialer/Extensions/Views+Extension.swift index 9da6ac9..85a8ae7 100644 --- a/Dialer/Dialer/Extensions/Views+Extension.swift +++ b/Dialer/Dialer/Extensions/Views+Extension.swift @@ -7,13 +7,6 @@ import SwiftUI -struct MTNDisabling: ViewModifier { - func body(content: Content) -> some View { - content - .disabled(CTCarrierDetector.shared.cellularProvider().status == false) - } -} - struct BiometricsAccessibility: ViewModifier { private let biometrics = BiometricsAuth.shared var onEvaluation: (Bool) -> Void @@ -47,12 +40,6 @@ extension View { ModifiedContent(content: self, modifier: BiometricsAccessibility(onEvaluation: onEvaluation)) } - /// Disable access if `Mtn` sim card is not detected - /// - Returns: a disabled view if mtn card is not detected (no interaction). - func momoDisability() -> some View { - ModifiedContent(content: self, modifier: MTNDisabling()) - } - /// Dismiss keyboard func hideKeyboard() { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) diff --git a/Dialer/Dialer/Services/FirebaseTracker.swift b/Dialer/Dialer/Services/FirebaseTracker.swift index cd6542a..a7c54e9 100644 --- a/Dialer/Dialer/Services/FirebaseTracker.swift +++ b/Dialer/Dialer/Services/FirebaseTracker.swift @@ -55,14 +55,14 @@ class FirebaseTracker { func stopSession(for screen: ScreenName) { /// 1. get the start date of the session guard let start = sessions[screen] else { - debugPrint("could not get start time of the session for given screen: \(screen.rawValue)") + Log.debug("could not get start time of the session for given screen: \(screen.rawValue)") return } /// 2. get the session length and format it as string and miliseconds let interval = start.timeIntervalSinceNow * (-1) let formatted = interval.formattedString() let seconds: Int = Int(interval) - debugPrint("screen session time for: \(screen.rawValue) is \(formatted) seconds: \(seconds)") + Log.debug("screen session time for: \(screen.rawValue) is \(formatted) seconds: \(seconds)") /// 3. log event on firebase // screen_session_length - Name of the Event diff --git a/Dialer/Dialer/Services/Logger.swift b/Dialer/Dialer/Services/Logger.swift index 057d803..c3c5eea 100644 --- a/Dialer/Dialer/Services/Logger.swift +++ b/Dialer/Dialer/Services/Logger.swift @@ -13,17 +13,22 @@ enum Log { static func add(_ message: StaticString, file: String = #file, dso: UnsafeRawPointer? = #dsohandle, log: OSLog = .default, type: OSLogType = .default, _ args: CVarArg...) { // 1. log the message using OSLog os_log(message, dso: dso, log: log, type: type, args) - debugPrint(message, args) let filename = String(file.split(separator: "/").last ?? "") let formatter = DateFormatter(format: "MM/dd/yyyy HH:mm") let logs: [String : Any] = [ "date": formatter.string(from: Date()), "message": "\(message)", - "args:": "\(args)", + "args": "\(args)", "file": filename ] // 2. log an event depending on let logType: LogEvent = type == .error ? .error : .debugInfo Tracker.shared.logEvent(name: logType, parameters: logs) } + + static func debug(_ items: Any...) { + #if DEBUG + debugPrint(items) + #endif + } } diff --git a/Dialer/Dialer/Utilities/CTCarrierDetector.swift b/Dialer/Dialer/Utilities/CTCarrierDetector.swift deleted file mode 100644 index 0a0ef1b..0000000 --- a/Dialer/Dialer/Utilities/CTCarrierDetector.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// CTCarrierDetector.swift -// Dialer -// -// Created by Cédric Bahirwe on 06/06/2021. -// - -import Foundation -import CoreTelephony - -class CTCarrierDetector: NSObject { - static let shared = CTCarrierDetector() - - func cellularProvider() -> (status: Bool, message: String) { - let providers = CTTelephonyNetworkInfo().serviceSubscriberCellularProviders - - if let providers = providers? - .filter({ $0.value.mobileCountryCode != nil }) - .compactMapValues(\.carrierName), - providers.isEmpty == false - { - let provider = providers.first!.value - return (true, provider) - } - return (false, "No SIM found") - } -} diff --git a/Dialer/Dialer/Utilities/DialerLocalNotificationCenter.swift b/Dialer/Dialer/Utilities/DialerLocalNotificationCenter.swift index d52a93b..82c8ad4 100644 --- a/Dialer/Dialer/Utilities/DialerLocalNotificationCenter.swift +++ b/Dialer/Dialer/Utilities/DialerLocalNotificationCenter.swift @@ -44,7 +44,7 @@ final class DialerNotificationCenter: NSObject { try await createNotification(dailyNotification, repeats: true) DialerStorage.shared.setDailyNotificationStatus(to: true) } catch { - debugPrint("Issue with notification", error.localizedDescription) + Log.debug("Issue with notification", error.localizedDescription) } } } @@ -53,7 +53,6 @@ final class DialerNotificationCenter: NSObject { // MARK: - Helper Methods private extension DialerNotificationCenter { func isNotificationAuthorized() async throws -> Bool { - debugPrint(#function) do { return try await notificationCenter.requestAuthorization(options: [.alert, .sound]) } catch { @@ -63,7 +62,6 @@ private extension DialerNotificationCenter { } func createNotification(_ notification: AppNotification, repeats: Bool) async throws { - debugPrint(#function) guard try await isNotificationAuthorized() else { return } let content = UNMutableNotificationContent() @@ -84,7 +82,7 @@ private extension DialerNotificationCenter { do { try await notificationCenter.add(request) } catch { - debugPrint("Unable to add notification: ", error.localizedDescription) + Log.debug("Unable to add notification: ", error.localizedDescription) throw NotificationError.notAdded } } @@ -92,18 +90,16 @@ private extension DialerNotificationCenter { extension DialerNotificationCenter { func deleteNotifications() { - debugPrint(#function) notificationCenter.removeAllPendingNotificationRequests() DialerStorage.shared.setDailyNotificationStatus(to: false) } ///Prints to console schduled notifications func printNotifications() { - debugPrint(#function) Task { let pendingNotifs = await notificationCenter.pendingNotificationRequests() - debugPrint("Pending Notifications Count: ", pendingNotifs.count) + Log.debug("Pending Notifications Count: ", pendingNotifs.count) } } diff --git a/Dialer/Dialer/Utilities/FirebaseCRUD.swift b/Dialer/Dialer/Utilities/FirebaseCRUD.swift index 8bde5bc..0d19334 100644 --- a/Dialer/Dialer/Utilities/FirebaseCRUD.swift +++ b/Dialer/Dialer/Utilities/FirebaseCRUD.swift @@ -44,7 +44,7 @@ extension FirebaseCRUD { } } } catch { - debugPrint("Could not save \(type(of: element)): \(error.localizedDescription).") + Log.debug("Could not save \(type(of: element)): \(error.localizedDescription).") continuation.resume(throwing: error) } } @@ -57,7 +57,7 @@ extension FirebaseCRUD { return await getAllWithQuery(querySnapshot) } catch { - debugPrint("Can not get \(type(of: Merchant.self)) Error: \(error).") + Log.debug("Can not get \(type(of: Merchant.self)) Error: \(error).") return [] } } @@ -67,7 +67,7 @@ extension FirebaseCRUD { do { return try document.data(as: T.self) } catch { - debugPrint("Firestore Decoding error: ", error, querySnapshot.documents.forEach { print($0.data()) } ) + Log.debug("Firestore Decoding error: ", error, querySnapshot.documents.forEach { print($0.data()) } ) return nil } } @@ -85,7 +85,7 @@ extension FirebaseCRUD { return item } catch { - debugPrint("Error getting \(T.self): \(error)") + Log.debug("Error getting \(T.self): \(error)") return nil } } @@ -109,7 +109,7 @@ extension FirebaseCRUD { continuation.resume(returning: true) } catch { - debugPrint("Error updating Merchant: \(error)") + Log.debug("Error updating Merchant: \(error)") continuation.resume(throwing: error) } } diff --git a/Dialer/Dialer/Utilities/FirebaseManager.swift b/Dialer/Dialer/Utilities/FirebaseManager.swift index bc29d7b..2bac20d 100644 --- a/Dialer/Dialer/Utilities/FirebaseManager.swift +++ b/Dialer/Dialer/Utilities/FirebaseManager.swift @@ -50,7 +50,7 @@ extension FirebaseManager: MerchantProtocol { return await getAllWithQuery(querySnapshot) } catch { - debugPrint("Can not get \(type(of: Merchant.self)), Error: \(error).") + Log.debug("Can not get \(type(of: Merchant.self)), Error: \(error).") Tracker.shared.logError(error: error) return [] } diff --git a/Dialer/Dialer/Utilities/FirebaseRemoteConfig.swift b/Dialer/Dialer/Utilities/FirebaseRemoteConfig.swift index 5a56abc..38f951e 100644 --- a/Dialer/Dialer/Utilities/FirebaseRemoteConfig.swift +++ b/Dialer/Dialer/Utilities/FirebaseRemoteConfig.swift @@ -35,16 +35,11 @@ extension FirebaseRemoteConfig: RemoteConfigsProtocol { do { let status = try await firebaseRemoteConfig.fetch(withExpirationDuration: fetchTimeout) if status == .success { - debugPrint("Remote config fetched!") - let isActivated = try await firebaseRemoteConfig.activate() - if isActivated { - debugPrint("Remote Config Activated") - } else { - debugPrint("Remote Config Not Activated") - } + _ = try await firebaseRemoteConfig.activate() + } } catch { - debugPrint("Error occured \(error.localizedDescription)") + Log.debug("Error occured \(error.localizedDescription)") } } diff --git a/Dialer/Dialer/View Models/LocalStorage.swift b/Dialer/Dialer/View Models/LocalStorage.swift index dac1169..b49f899 100644 --- a/Dialer/Dialer/View Models/LocalStorage.swift +++ b/Dialer/Dialer/View Models/LocalStorage.swift @@ -145,7 +145,7 @@ private extension DialerStorage { do { return try JSONDecoder().decode(type, from: data) } catch let error { - debugPrint("Couldn't decode the data of type \(type): ", error.localizedDescription) + Log.debug("Couldn't decode the data of type \(type): ", error.localizedDescription) } return nil } @@ -158,7 +158,7 @@ private extension DialerStorage { do { return try Firestore.Decoder().decode(type, from: dictionary) } catch let error { - debugPrint("Couldn't decode the firebase data of type \(type): ", error) + Log.debug("Couldn't decode the firebase data of type \(type): ", error) } return nil } @@ -171,7 +171,7 @@ private extension DialerStorage { do { return try JSONDecoder().decode(type, from: data) } catch let error { - debugPrint("Couldn't decode the array of type \(type): ", error.localizedDescription) + Log.debug("Couldn't decode the array of type \(type): ", error.localizedDescription) } return [] } diff --git a/Dialer/Dialer/Views/DashBoardView.swift b/Dialer/Dialer/Views/DashBoardView.swift index 133fb63..d13a0c2 100644 --- a/Dialer/Dialer/Views/DashBoardView.swift +++ b/Dialer/Dialer/Views/DashBoardView.swift @@ -19,10 +19,7 @@ struct DashBoardView: View { @State private var presentQuickDial = false @State private var presentTransferView = false @State private var showPurchaseSheet = false - @State private var showMerchantsList = false - - private let checkCellularProvider = CTCarrierDetector.shared.cellularProvider() - + var body: some View { ZStack(alignment: .bottom) { VStack { @@ -31,7 +28,6 @@ struct DashBoardView: View { DashItemView( title: "Buy airtime", icon: "wallet.pass") - .momoDisability() .onTapGesture { withAnimation { showPurchaseSheet = true @@ -79,20 +75,6 @@ struct DashBoardView: View { Spacer() - if checkCellularProvider.status == false { - HStack { - Text("Sim card is required to unlock all the features.") - .font(.system(size: 20, weight: .semibold, design: .rounded)) - .foregroundColor(.red) - .lineLimit(1) - .minimumScaleFactor(0.6) - } - .frame(maxWidth: .infinity) - .padding() - .background(.ultraThickMaterial) - .hidden() - } - bottomBarView } .blur(radius: showPurchaseSheet ? 3 : 0) @@ -169,29 +151,9 @@ extension DashBoardView { } Spacer(minLength: 5) - - Label { - Text(LocalizedStringKey(checkCellularProvider.message)) - .font(.system(.body, design: .rounded) - .weight(.medium)) - .multilineTextAlignment(.leading) - } icon: { - Image(systemName: checkCellularProvider.status ? "chart.bar.fill" : "chart.bar") - } - .foregroundColor(checkCellularProvider.status ? .main : .red) - .padding(10) - .background(Color.white) - .cornerRadius(10) - .onTapGesture(count: 3) { - guard AppConfiguration.isDebug else { return } - showMerchantsList = true - } } .padding(.horizontal) .padding(.bottom, 8) - .fullScreenCover(isPresented: $showMerchantsList) { - MerchantsListView() - } } } diff --git a/Dialer/Dialer/Views/Main/PurchaseDetailView.swift b/Dialer/Dialer/Views/Main/PurchaseDetailView.swift index d8d6c3e..2239565 100644 --- a/Dialer/Dialer/Views/Main/PurchaseDetailView.swift +++ b/Dialer/Dialer/Views/Main/PurchaseDetailView.swift @@ -138,9 +138,9 @@ struct PurchaseDetailView: View { Text("Confirm") .frame(maxWidth: .infinity) .frame(height: 45) - .background(Color.primary.opacity((!validCode || !validAmount) ? 0.5 : 1)) + .background(Color.blue.opacity((!validCode || !validAmount) ? 0.5 : 1)) .cornerRadius(8) - .foregroundColor(Color(.systemBackground)) + .foregroundColor(.white) } .disabled(!validCode || !validAmount) } else {