为什么Swift Movesense-API 订阅回调操作会为零?

Why would the Swift Movesense-API Subscription Callback Operation Be Nil?

我正在构建与 Movesense 的 api 的 Swift 集成,如下所示:https://bitbucket.org/suunto/movesense-mobile-lib/src/master/IOS/

按照 Movesense Showcase 应用程序中给出的示例,我订阅了心率通知:

let request = MovesenseRequest(resourceType: .heartRate, method: .subscribe,
    parameters: nil)

    let operation = device.sendRequest(request, observer: self)

我确信我的设备已连接并正常工作,因为我可以使用 .get 方法毫无问题地检索能量和温度信息。

问题是我没有从 Movesense API 收到任何心率响应。单步执行 api,我被困在发送请求方法中,其中 onCompletion 和 onEvent 回调都有一个 nil 操作,因此它没有向我的应用程序发送响应就死了。

internal func sendRequest(_ request: MovesenseRequest, serial: String,
                          observer: Observer) -> MovesenseOperation? {
    guard let mds = self.mdsWrapper,
          let jsonDecoder = self.jsonDecoder else {
        let error = MovesenseError.integrityError("MovesenseConnection::sendRequest error.")
        delegate?.onConnectionError(error)
        return nil
    }

    let resourcePath = "\(serial)/\(request.path)"
    let onCancel = {
        switch request.method {
            case .subscribe: mds.doUnsubscribe(resourcePath)
            default: return
        }
    }

    let operation = MovesenseOperationFactory.create(request: request,
                                                     observer: observer,
                                                     jsonDecoder: jsonDecoder,
                                                     onCancel: onCancel)

    // Decode response with the MovesenseOperation instance
    let onCompletion = { [connectionQueue, weak operation] (_ response: MDSResponse) in
        dump(response)
        guard let operation = operation else { return }
        connectionQueue.async {
            operation.handleResponse(status: response.statusCode, header: response.header,
                                     data: response.bodyData)
        }
    }

    switch request.method {
    case .get: mds.doGet(resourcePath, contract: request.contract, completion: onCompletion)
    case .put: mds.doPut(resourcePath, contract: request.contract, completion: onCompletion)
    case .post: mds.doPost(resourcePath, contract: request.contract, completion: onCompletion)
    case .del: mds.doDelete(resourcePath, contract: request.contract, completion: onCompletion)
    case .unsubscribe: mds.doUnsubscribe(resourcePath)
    case .subscribe:
        let onEvent = { [connectionQueue, weak operation] (_ event: MDSEvent) in
            dump(event)
            guard let operation = operation else {
                mds.doUnsubscribe(resourcePath)
                return
            }

            connectionQueue.async {
                operation.handleEvent(header: event.header,
                                      data: event.bodyData)
            }
        }

        mds.doSubscribe(resourcePath, contract: request.contract,
                        response: onCompletion, onEvent: onEvent)
    }

    return operation
}

我知道 API 有效,因为存储库中的 Movesense Showcase 代码工作得很好,但我不知道我在设置请求时遗漏了什么,所以操作不会每次都为 nil时间。什么可能导致该错误?

我终于找到了自己的答案。问题出在弱引用上。我没有将该操作存储在任何地方,所以当调用回调时,该操作始终为 nil,因为引用已被垃圾回收。解决方案是将订阅请求返回的操作存储在某处,然后在取消订阅时删除引用。我个人使用地图来存储我的引用,但是任何保留引用的方法都可以。