最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - ## Live Activity Update Problem in React Native *Title:* Live Activity Sometimes Updates Sometimes dosen't updates

programmeradmin1浏览0评论

I'm developing a React Native iOS application that uses Live Activities. I've implemented the Live Activities functionality using native modules (Objective-C/Swift) to interact with the underlying iOS APIs. Updates to the Live Activity are triggered via APNs push notifications.

The problem I'm encountering is that the Live Activity updates are intermittent. Sometimes, when I send a push notification, the Live Activity updates correctly and displays the new information. Other times, the notification arrives (I can see it in the console logs or using a push notification testing tool), but the Live Activity remains unchanged. There's no consistent pattern to when the updates succeed or fail.

I've tried the following:

  • Verifying APNs Setup: I've double-checked my APNs setup, including the provisioning profiles, certificates, and the push notification payload. The payload includes the necessary aps dictionary with the content-available key set to 1, and I'm also including the alert key for testing (though I understand it's not strictly required for background updates). I've confirmed that the device receives the push notification reliably.

  • Native Module Code Review: I've thoroughly reviewed the native module code that handles the Live Activity updates. I'm using Activity.update to update the activity's attributes. I've added logging to the native module to confirm that the update function is being called when a push notification is received. The logs show that the function is being called even when the Live Activity doesn't update, suggesting the issue might be with the Activity.update call itself or something related to the timing of the update.

  • Background Modes: I've enabled the "Background Modes" capability in Xcode for my app, specifically the "Background fetch" and "Remote notifications" options.

  • Testing with Different Devices/iOS Versions: I've tested on both physical devices and simulators running different iOS versions, but the intermittent behavior persists.

    messaging().setBackgroundMessageHandler(async (remoteMessage) => {
      console.log('Notification.js: Your message was handled in background');
      if (DynamicIslandModule && Platform.OS === "ios" && Platform.Version >= 16.1) {
        console.log("Notification.js true", remoteMessage);
        console.log(DynamicIslandModule, 'DynamicIslandModule');
        console.log(remoteMessage?.data?.order, 'order id from background notification');
    
        if (["void", "cancel", "bad", "complete"].includes(remoteMessage?.data?.title.toLowerCase())) {
          await DynamicIslandModule.endNotificationActivity();
        } else {
          await DynamicIslandModule.updateNotificationActivityWithOrderStatus(
            remoteMessage?.data?.message,
            remoteMessage?.data?.order
          );
        }
      }
      if (remoteMessage?.data?.notificationId) {
        console.log('Your message was handled in background');
        let notificationId = remoteMessage?.data?.notificationId;
        await store.getLastSavedToken();
        await singleton.markNotificationReceived({ _id: notificationId });
        console.log(
          'Message handled in the background!',
          remoteMessage?.data?.notificationId
        );
      }
    });
    
  • //DynamicIslandModule.swift
    
    @objc(updateNotificationActivityWithOrderStatus:withOrderID:withOrderMessage:withTitle:withResolve:withReject:)
    func updateNotificationActivity(
        orderStatus: NSString,
        orderID: NSString,
        orderMessage: NSString,
        title: NSString,
        resolve: @escaping RCTPromiseResolveBlock,
        reject: @escaping RCTPromiseRejectBlock
    ) {
        let status = orderStatus as String
        let orderIDString = orderID as String
    
        guard let storedIDs = UserDefaults.standard.array(forKey: "liveActivityIDs") as? [String],
              storedIDs.contains(orderIDString) else {
            print("ERROR: Live Activity ID not found in UserDefaults")
            return
        }
    
        guard let liveActivity = Activity<NotificationAttributes>.activities.first(where: { activity in
            if let contentState = activity.contentState as? NotificationAttributes.ContentState {
                return contentState.orderID == orderIDString
            }
            return false
        }) else {
            print("ERROR: Live Activity not found for ID: \(orderIDString)")
            return
        }
    
        guard let currentContentState = liveActivity.contentState as? NotificationAttributes.ContentState else {
            print("ERROR: Failed to retrieve current content state")
            return
        }
    
        let updatedContentState = NotificationAttributes.ContentState(
            orderStatus: status,
            orderID: orderIDString,
            pickupLocation: currentContentState.pickupLocation,
            dropoffLocation: currentContentState.dropoffLocation,
            serviceMethod: currentContentState.serviceMethod,
            orderMessage: orderMessage as String,
            title: title as String
        )
    
        if #available(iOS 16.1, *) {
            print("Updating Live Activity...")
            Task {
                do {
                    try await liveActivity.update(using: updatedContentState)
                    resolve("Live Activity updated successfully for order #\(orderIDString)")
                    print("Live Activity updated successfully for order #\(orderIDString) status:\(status)")
                } catch let error {
                    reject("ERROR", "Failed to update live activity", error)
                    print("Error updating live activity: \(error.localizedDescription)")
                }
            }
        } else {
            reject("ERROR", "iOS version not supported", nil)
        }
    }
    
  • //AppDelegate.mm
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        if (@available(iOS 16.1, *)) {
            NSString *orderID = userInfo[@"data"][@"order"];
            NSString *orderMessage = userInfo[@"data"][@"message"];
            NSString *orderStatus = userInfo[@"data"][@"status"];
            NSString *orderTitle = userInfo[@"data"][@"title"];
            NSLog(@"didReceiveRemoteNotification triggered");
    
            NSArray *endTitles = @[@"complete", @"void", @"bad", @"cancel"];
    
            if ([endTitles containsObject:orderStatus.lowercaseString]) {
                [LiveActivityHelper endActivityWithIdWithOrderID:orderID];
            } else {
                [LiveActivityHelper updateActivityWithOrderID:orderID orderStatus:orderStatus orderMessage:orderMessage title:orderTitle];
            }
    
            completionHandler(UIBackgroundFetchResultNewData);
        } else {
            completionHandler(UIBackgroundFetchResultNewData);
        }
    }
    

Question:

What could be causing these intermittent Live Activity updates? Are there any specific considerations regarding timing, background execution, or APNs payload structure that I might be missing? Any suggestions for debugging this further would be greatly appreciated.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论