ios - 如何为包含 JSON 数组的 API 端点创建 Siesta 转换器?

标签 ios json swift siesta-swift

我正在构建一个需要向 API 端点发出 GET 请求的应用 https://thecountedapi.com/api/counted使用 Siesta框架。端点返回一个 JSON 数组,就像 https://api.github.com/users/ebelinski/repos 这样的端点。 ,在 Siesta 示例中使用 Github Browser .因此,我正在尝试让我的应用程序以人们所说的方式使用 Siesta。我创建了一个服务:

let API = Service(baseURL: "https://thecountedapi.com/api")

然后是我在 application:didFinishLaunchingWithOptions 中的端点的转换器:

API.configureTransformer("/counted") {
  ($0.content as JSON).arrayValue.map(Incident.init)
}

其中 Incident 是一个带有接受 JSON 对象的初始化器的结构。

然后在我的 View Controller 中,我创建了一个资源:

let resource = API.resource("/counted")

并在viewDidLoad :

resource.addObserver(self)

并在viewWillAppear :

resource.loadIfNeeded()

然后我在我的 VC 中有以下函数来监听变化:

func resourceChanged(resource: Resource, event: ResourceEvent) {
  print(resource.jsonArray)

  if let error = resource.latestError {
    print(error.userMessage)
    return
  }

  if let content: [Incident] = resource.typedContent() {
    print("content exists")
    incidents = content
  }

  print(incidents.count)
}

但是当我运行我的应用程序时,我得到了不同的结果。 print(resource.jsonArray)只打印 [] ,我有一条错误消息 Cannot parse server response ,如果我设置 Siesta.enabledLogCategories = LogCategory.detailed , 我可以看到错误信息 [Siesta:StateChanges] Siesta.Resource(https://thecountedapi.com/api/counted)[] received error: Error(userMessage: "Cannot parse server response", httpStatusCode: nil, entity: nil, cause: Optional(Siesta.Error.Cause.WrongTypeInTranformerPipeline(expectedType: "JSON", actualType: "__NSCFArray", transformer: Siesta.ResponseContentTransformer<SwiftyJSON.JSON, Swift.Array<TheCountedViewer.Incident… .

如果我注释掉整个变压器,我会在这方面取得一些成功 print(resource.jsonArray)从端点打印出正确的数组。所以我的转换器在某些方面一定是错误的,但我认为我使用的转换器与 Github 浏览器中的转换器基本相同:

service.configureTransformer("/users/*/repos") {
    ($0.content as JSON).arrayValue.map(Repository.init)
}

我错过了什么吗?

最佳答案

你的问题的关键线索隐藏在那个(可能不是理想的有用的)日志消息中:

Siesta.Error.Cause.WrongTypeInTranformerPipeline
  expectedType: "JSON"
  actualType: "__NSCFArray"

它是说你的转换器需要 JSON 的输入类型,这是有道理的——你用 ($0.content as JSON) 说了很多。然而,它得到类型__NSCFArray,这是NSArray 的 secret 内部支持类型。换句话说,它期望一个 SwiftyJSON 值,但它得到的是 NSJSONSerialization 的原始输出。

为什么? GithubBrowser 项目包括一个 NSDict/NSArray → SwiftyJSON transformerconfigures in the parsing stage .该项目中的模型转换器都依赖于它。

要在您的项目中以相同的方式使用 SwiftyJSON,您需要在您的示例项目中包含该转换器:

private let SwiftyJSONTransformer =
  ResponseContentTransformer
    { JSON($0.content as AnyObject) }

然后在设置您的服务时:

service.configure {
  $0.config.pipeline[.parsing].add(SwiftyJSONTransformer, contentTypes: ["*/json"])
}

(请注意,如果您对错误感兴趣,您可能希望使用 transformErrors: true 创建 ResponseContentTransformer。)


另一种使用 SwiftyJSON 的方法虽然不那么漂亮但需要的设置更少,它是在每个单独的响应转换器中手动将内容包装在 JSON 中:

service.configureTransformer("/users/*/repos") {
  JSON($0.content as AnyObject).arrayValue.map(Incident.init)
}

关于ios - 如何为包含 JSON 数组的 API 端点创建 Siesta 转换器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38710117/

相关文章:

Highcharts JSON 调用的 javascript 关联数组、循环和/或范围问题

xcode - 自定义 Tableview 以切换到不同的 View Controller

ios - "Template Rendering is not supported in texture atlases"SpriteKit 和 Xcode

ios - 应用剪切路径后,如何确定点是否位于路径内部?

ios - 如何在iOS中实现Google和Facebook网址处理?

ios - 如何重新加载 UIView?

ios - 从后台删除我的应用程序时如何捕获事件

php - 在 Yii 1.x 中编码未转义的 JSON

java - 改造如何打印响应 JSON

ios - 重新加载表时关闭 UISwipeActionsConfiguration