为推送通知

时间:2016-12-29 00:39:31

标签: ios push-notification swift3 queue cloudkit

我正在为我订阅的每个活动收到最多四个推送通知。我已经浏览了与我的CloudKit订阅和通知注册表相关的所有内容,我确信这是一个Apple问题。相反,无论我收到多少通知,我都会将注意力转向正确处理通知。这是我正在做的简化版本:

func recievePrivatePush(_ pushInfo: [String:NSObject], completion: @escaping ()->Void) {

    let notification = CKNotification(fromRemoteNotificationDictionary: pushInfo)
    let alertBody = notification.alertBody

    if let queryNotification = notification as? CKQueryNotification {
        let recordID = queryNotification.recordID
        guard let body = queryNotification.alertBody else {
            return
        }

        if recordID != nil {
            switch body {
            case "Notification Type":
                let id = queryNotification.recordID
                switch queryNotification.queryNotificationReason {
                case .recordCreated:
                    DataCoordinatorInterface.sharedInstance.fetchDataItem(id!.recordName, completion: {
                        //
                    })
                    break

                default:
                    break
                }
           }
       }
    }
}

提取代码如下所示:

func fetchDataItem(_ id: String, completion: @escaping ()-> Void) {

    if entityExistsInCoreData(id) {return}


    let db = CKContainer.default().privateCloudDatabase
    let recordID = CKRecordID(recordName: id)
    db.fetch(withRecordID: recordID) { (record, error) in
        if let topic = record {
            //Here I create and save the object to core data.
        }
        completion()
    }
}

我的所有代码都有效,我遇到的问题是,当我收到多个通知时,会在创建第一个核心数据实体之前启动多个提取请求,从而产生冗余的核心数据对象。

我想要做的是找到一种方法将获取请求添加到串行队列,以便一次处理一个。我可以将请求调用放在串行队列中,但回调总是异步运行,因此在第一个数据对象持久化之前仍会生成多个获取请求。

我尝试使用信号量和调度组,其模式如下所示:

let semaphore = DispatchSemaphore(value: 1)    

func recievePrivatePush(_ pushInfo: [String:NSObject], completion: @escaping ()->Void) {

    _ = semaphore.wait(timeout: .distantFuture)

    let notification = CKNotification(fromRemoteNotificationDictionary: pushInfo)
    let alertBody = notification.alertBody

    if let queryNotification = notification as? CKQueryNotification {
        let recordID = queryNotification.recordID
        guard let body = queryNotification.alertBody else {
            return
        }

        if recordID != nil {
            switch body {
            case "Notification Type":
                let id = queryNotification.recordID
                switch queryNotification.queryNotificationReason {
                case .recordCreated:
                    DataCoordinatorInterface.sharedInstance.fetchDataItem(id!.recordName, completion: {
                        semaphore.signal()
                    })
                    break

                default:
                    break
                }
           }
       }
    }
}

第二次调用上述函数并调用semaphore.wait后,第一个网络请求的执行暂停,导致应用程序冻结。

同样,我想要实现的目的是将异步网络请求添加到队列中,以便一次只创建一个,即第一个网络调用在第二个请求启动之前完成。

2 个答案:

答案 0 :(得分:0)

卡尔,

也许你会找到你的解决方案,包括调度组,一些关键的表达方式。

let group = DispatchGroup()
group.enter()

...代码......

group.leave
group.wait()

我用它们来限制我批量发送的http请求的数量,等待响应。也许您可以将它们与我的评论中的建议一起使用。观看此视频,在这里发送群组,我想更多。

https://developer.apple.com/videos/play/wwdc2016/720/

答案 1 :(得分:0)

这些简单的课程帮助我解决了这个问题。

class PushQueue {

internal var pushArray: Array<String> = [String]()
internal let pushQueue = DispatchQueue(label: "com.example.pushNotifications")

public func addPush(_ push: Push) {
    pushQueue.sync {
        if pushArray.contains(push.id) {
            return
        } else {
            pushArray.append(push.id)
            processNotification(push: push)
        }
    }
}

internal func processNotification(push: Push) {
    PushInterface.sharedInstance.recievePrivatePush(push.userInfo as! [String: NSObject])
}

}


class CKPush: Equatable {

init(userInfo: [AnyHashable: Any]) {

    let ck = userInfo["ck"] as? NSDictionary
    let id = ck?["nid"] as? String
    self.id = id!
    self.userInfo = userInfo
}

var id: String
var userInfo: [AnyHashable:Any]

public static func ==(lhs: CKPush, rhs: CKPush) -> Bool {
    return lhs.id == rhs.id ? true : false
}

}

请忽略松散的力量展开。他们需要清理。