Logo Pastebin.fr
Pastebin

Retrouvez, créez et partagez vos snippets en temps réel.

Cd

import Foundation
import Expo
import FirebaseCore
import PushKit
import React
import ReactAppDependencyProvider

@UIApplicationMain
public class AppDelegate: ExpoAppDelegate {
  var window: UIWindow?

  var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
  var reactNativeFactory: RCTReactNativeFactory?
  private var voipRegistry: PKPushRegistry?
  private var voipTokenHandler: ((String) -> Void)?
  private var voipPayloadHandler: (([String: Any]) -> Void)?
  private let voipTokenStorageKey = "voip_push_token"
  private var voipToken: String?
  private var callKeepConfigured = false

  public override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    let delegate = ReactNativeDelegate()
    let factory = ExpoReactNativeFactory(delegate: delegate)
    delegate.dependencyProvider = RCTAppDependencyProvider()

    reactNativeDelegate = delegate
    reactNativeFactory = factory
    bindReactNativeFactory(factory)

#if os(iOS) || os(tvOS)
    window = UIWindow(frame: UIScreen.main.bounds)
// @generated begin @react-native-firebase/app-didFinishLaunchingWithOptions - expo prebuild (DO NOT MODIFY) sync-10e8520570672fd76b2403b7e1e27f5198a6349a
FirebaseApp.configure()
// @generated end @react-native-firebase/app-didFinishLaunchingWithOptions
    factory.startReactNative(
      withModuleName: "main",
      in: window,
      launchOptions: launchOptions)
#endif

    let result = super.application(application, didFinishLaunchingWithOptions: launchOptions)
    setupCallKeepIfNeeded()
    startVoipPushRegistry()
    return result
  }

  // Linking API
  public override func application(
    _ app: UIApplication,
    open url: URL,
    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
  ) -> Bool {
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
// @generated begin @react-native-firebase/auth-openURL - expo prebuild (DO NOT MODIFY)
    if url.host?.lowercased() == "firebaseauth" {
      // invocations for Firebase Auth are handled elsewhere and should not be forwarded to Expo Router
      return false
    }
// @generated end @react-native-firebase/auth-openURL
    return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
  }

  // Universal Links
  public override func application(
    _ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
  ) -> Bool {
    let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
  }

  func startVoipPushRegistry() {
    if voipRegistry != nil { return }
    print("[VoipPush] startVoipPushRegistry")
    let registry = PKPushRegistry(queue: DispatchQueue.main)
    registry.delegate = self
    registry.desiredPushTypes = [.voIP]
    voipRegistry = registry
  }

  func setVoipTokenHandler(_ handler: @escaping (String) -> Void) {
    voipTokenHandler = handler
  }

  func setVoipPayloadHandler(_ handler: @escaping ([String: Any]) -> Void) {
    voipPayloadHandler = handler
  }

  func stopVoipPushRegistry(clearToken: Bool = false) {
    print("[VoipPush] stopVoipPushRegistry clearToken=\(clearToken)")
    voipRegistry?.desiredPushTypes = []
    voipRegistry?.delegate = nil
    voipRegistry = nil
    voipTokenHandler = nil
    if clearToken { clearVoipToken() }
  }

  func getVoipToken() -> String? {
    return voipToken ?? UserDefaults.standard.string(forKey: voipTokenStorageKey)
  }

  private func storeVoipToken(_ token: String) {
    voipToken = token
    UserDefaults.standard.set(token, forKey: voipTokenStorageKey)
  }

  private func clearVoipToken() {
    voipToken = nil
    UserDefaults.standard.removeObject(forKey: voipTokenStorageKey)
  }

  private func setupCallKeepIfNeeded() {
    if callKeepConfigured { return }
    callKeepConfigured = true
    let appName = (Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String)
      ?? (Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String)
      ?? "Deafiline"
    RNCallKeep.setup([
      "appName": appName,
    ])
    print("[CallKeep] native setup done (\(appName))")
  }
}

class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
  // Extension point for config-plugins

  override func sourceURL(for bridge: RCTBridge) -> URL? {
    // needed to return the correct URL for expo-dev-client.
    bridge.bundleURL ?? bundleURL()
  }

  override func bundleURL() -> URL? {
#if DEBUG
    return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
#else
    return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
  }
}

extension AppDelegate: PKPushRegistryDelegate {
  public func pushRegistry(
    _ registry: PKPushRegistry,
    didUpdate pushCredentials: PKPushCredentials,
    for type: PKPushType
  ) {
    guard type == .voIP else { return }

    let token = pushCredentials.token.map { String(format: "%02x", $0) }.joined()
    print("VoIP token: \(token)")
    storeVoipToken(token)
    voipTokenHandler?(token)
  }

  public func pushRegistry(
    _ registry: PKPushRegistry,
    didInvalidatePushTokenFor type: PKPushType
  ) {
    guard type == .voIP else { return }
    print("VoIP token invalidated")
    clearVoipToken()
  }

  public func pushRegistry(
    _ registry: PKPushRegistry,
    didReceiveIncomingPushWith payload: PKPushPayload,
    for type: PKPushType,
    completion: @escaping () -> Void
  ) {
    guard type == .voIP else {
      completion()
      return
    }

    let payloadDict = payload.dictionaryPayload
    if let handler = voipPayloadHandler {
      handler(payloadDict as? [String: Any] ?? [:])
    }
    let callUUID = (payloadDict["callUUID"] as? String) ?? UUID().uuidString.lowercased()
    let handle = (payloadDict["handle"] as? String) ?? "Unknown"
    let callerName = (payloadDict["callerName"] as? String) ?? "Incoming Call"
    let hasVideo = (payloadDict["hasVideo"] as? Bool) ?? false

    RNCallKeep.reportNewIncomingCall(
      callUUID,
      handle: handle,
      handleType: "generic",
      hasVideo: hasVideo,
      localizedCallerName: callerName,
      supportsHolding: true,
      supportsDTMF: true,
      supportsGrouping: false,
      supportsUngrouping: false,
      fromPushKit: true,
      payload: payloadDict,
      withCompletionHandler: completion
    )
  }
}

Créé il y a 2 semaines.

Rechercher un Pastebin

Aucun paste trouvé.