0

我正在构建与 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 回调都有一个为零的操作,所以它在没有向我的应用程序发送响应的情况下死亡。

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 代码工作得很好,但我不知道我在设置请求时错过了什么,因此操作不会每次都为零。什么可能导致该错误?

4

1 回答 1

0

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

于 2020-03-27T00:59:50.313 回答