返回

Swift 融云推送 AppData 本地通知获取失效?问题根源与解决方案

IOS

前言

融云作为一款优秀的即时通讯云服务,为开发者提供了强大的推送功能。然而,在使用 Swift 进行开发时,开发者可能会遇到这样一个棘手的问题:融云推送消息后,客户端无法通过本地推送获取 AppData 字段中的数据。这对于需要根据 AppData 进行个性化跳转的应用来说,无疑是一个难题。

问题根源

经过仔细分析,我们发现问题根源在于:融云并没有为本地推送配置 AppData 数据。因此,iOS 客户端无法直接从本地推送中获取 AppData。

解决方案

为了解决这一问题,我们可以采用两种方案:

方案一:拦截融云通知

此方案的关键在于拦截融云推送的远程通知,并从其中提取 AppData 数据。具体步骤如下:

  1. 在 AppDelegate 的 application:didFinishLaunchingWithOptions: 方法中注册本地通知权限。
  2. 在 AppDelegate 的 application:didReceiveRemoteNotification:fetchCompletionHandler: 方法中拦截融云推送的远程通知。
  3. 从远程通知中提取 AppData 数据并存储在本地。
  4. 在本地推送触发时,从本地存储中获取 AppData 数据并进行处理。

方案二:自定义本地推送

此方案无需拦截融云通知,而是通过自定义本地推送来传递 AppData 数据。具体步骤如下:

  1. 在生成本地推送对象时,将 AppData 数据作为 userInfo 字典的一部分进行传递。
  2. 在本地推送触发时,从 userInfo 字典中获取 AppData 数据并进行处理。

示例代码

方案一:拦截融云通知

import UserNotifications
import RongIMLib

class AppDelegate: UIResponder, UIApplicationDelegate, RCIMUserInfoDataSource, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 注册本地通知权限
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                // 权限获取成功
            } else {
                // 权限获取失败
            }
        }
        
        // 设置融云回调
        RCIM.shared().userInfoDataSource = self
        
        return true
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // 拦截融云推送的远程通知
        let object = userInfo["object"] as? [String: Any]
        if let object = object, let appData = object["appData"] as? String {
            // 存储 AppData 数据到本地
            UserDefaults.standard.set(appData, forKey: "融云推送AppData")
        }
        
        completionHandler(.newData)
    }
    
    func getUserInfo(userId: String, completion: ((RCUserInfo?) -> Void)!) {
        // 从本地存储中获取 AppData 数据
        let appData = UserDefaults.standard.string(forKey: "融云推送AppData")
        // 构建 RCUserInfo 对象并设置 AppData 数据
        let userInfo = RCUserInfo(userId: userId)
        userInfo.extra = appData
        completion(userInfo)
    }
}

方案二:自定义本地推送

import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 注册本地通知权限
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            if granted {
                // 权限获取成功
            } else {
                // 权限获取失败
            }
        }
        
        return true
    }
    
    func scheduleLocalNotification(message: String, appData: String) {
        let content = UNMutableNotificationContent()
        content.title = "融云推送"
        content.body = message
        // 将 AppData 数据作为 userInfo 字典的一部分进行传递
        content.userInfo = ["appData": appData]
        
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let request = UNNotificationRequest(identifier: "融云推送", content: content, trigger: trigger)
        
        UNUserNotificationCenter.current().add(request) { error in
            if error != nil {
                // 添加本地推送失败
            }
        }
    }
}

总结

本文针对 Swift 中融云推送 AppData 本地通知无法获取的问题,提供了两种行之有效的解决方案。通过拦截融云通知或自定义本地推送的方式,开发者可以轻松获取 AppData 数据并实现个性化跳转。希望本文能够帮助开发者解决这一问题,提升应用用户体验。