Swift JSON 解码器错误:缺少某些内容

发布于 2025-01-11 09:54:03 字数 1713 浏览 0 评论 0原文

我正在使用 JSON 编码器和解码器来将自定义对象保存到我的用户默认值。我尝试编码和解码的对象是 Mapbox Directions Route Object(请参阅此处的文档:Mapbox 路线

我已成功在我的应用程序中使用了 JSON 编码器和解码器,但由于某种原因,我无法让它与 Route 对象一起使用。以下是我的 JSON 编码器:

//Encode route response Object to pass it to Defaults
do {
     // Create JSON Encoder
     let encoder = JSONEncoder()
     // Encode Note
     let encodedRoute = try encoder.encode(route)
     // Write/Set Data
     UserDefaults.standard.set(encodedRoute, forKey: "routeObject")
     print("Encoded route Object.")
     } catch {
          print("Unable to Encode route (\(error))")
     }

请注意,控制台打印“编码的路由对象”。应该意味着它有效。

现在是我的解码器,它不起作用并抛出我添加到 catch 语句中的错误:

//Read/Get response Object
if let encodedRoute = UserDefaults.standard.data(forKey: "routeObject") {
     do {
          // Create JSON Decoder
          let decoder = JSONDecoder()

          // Decode Note
          myRoute = try decoder.decode(MapboxDirections.Route.self, from: encodedRoute)
          print("Successfully decoded route Object!")
          } catch {
               print("Unable to Decode route. Error: \(error)")
          }
}

我得到的错误是:“无法解码路由。错误:missingOptions” “。 自从RouteOptions 是 Route 对象的一部分,我猜测编码或解码时出现问题,导致对象丢失。我尝试编码和解码 RouteResponse (包含多个路由),这返回了“missingCredentials”。同样,Credentials 是 RouteResponse 的一部分。我可能做错了什么?这两个类都工作得很好,并且都已经使用了许多其他 Mapbox 函数,因此它不能是带有导入等的东西。

如果有一种解决方法可以将对象传递给另一个类而不使用 getter 和 setter(这也是错误),我会很高兴听到它。

I am using a JSON encoder and decoder to be able to save a custom object to my user defaults. The object I am trying to encode and decode is a Mapbox Directions Route Object (See their documentation here: Mapbox Route

I have successfully used a JSON Encoder and Decoder for many things in my app. But for some reason, I can't get it to work with the Route object. Following is my JSON Encoder:

//Encode route response Object to pass it to Defaults
do {
     // Create JSON Encoder
     let encoder = JSONEncoder()
     // Encode Note
     let encodedRoute = try encoder.encode(route)
     // Write/Set Data
     UserDefaults.standard.set(encodedRoute, forKey: "routeObject")
     print("Encoded route Object.")
     } catch {
          print("Unable to Encode route (\(error))")
     }

Note that the console prints "Encoded route Object.", which should mean it worked.

Following now is my Decoder, which does not work and throws me the error I added to the catch statement:

//Read/Get response Object
if let encodedRoute = UserDefaults.standard.data(forKey: "routeObject") {
     do {
          // Create JSON Decoder
          let decoder = JSONDecoder()

          // Decode Note
          myRoute = try decoder.decode(MapboxDirections.Route.self, from: encodedRoute)
          print("Successfully decoded route Object!")
          } catch {
               print("Unable to Decode route. Error: \(error)")
          }
}

The error which I get is: "Unable to Decode route. Error: missingOptions". Since RouteOptions is part of the Route object, I am guessing that something went wrong while encoding or decoding, leading to a missing piece of the object. I tried encoding and decoding a RouteResponse (which contains multiple Routes), which returned me "missingCredentials". Again, Credentials is part of RouteResponse. What could I have done wrong? Both classes are working well otherwise and both already use many other Mapbox functions, so it cannot be something with the imports or such.

If there is a workaround to pass an object to another class without using getter and setters (which bugs also), I'd be happy to hear it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生生不灭 2025-01-18 09:54:03

这是 MapBox API 引发的自定义错误。

他们的代码

/**
 An error that occurs when encoding or decoding a type defined by the MapboxDirections framework.
 */
public enum DirectionsCodingError: Error {
    /**
     Decoding this type requires the `Decoder.userInfo` dictionary to contain the `CodingUserInfoKey.options` key.
     */
    case missingOptions
...
}

来自 一个href="https://github.com/mapbox/mapbox-directions-swift/blob/f852eb8520b616dd0082b163e6e59bba7a069633/Sources/MapboxDirections/Route.swift" rel="nofollow noreferrer">路线,我们可以看到评论init(from Decoder:),即在幕后调用by decoder.decode(_:from:)

/**
 Initializes a route from a decoder.
 
 - precondition: If the decoder is decoding JSON data from an API response, the `Decoder.userInfo` dictionary must contain a `RouteOptions` or `MatchOptions` object in the `CodingUserInfoKey.options` key. If it does not, a `DirectionsCodingError.missingOptions` error is thrown.
 - parameter decoder: The decoder of JSON-formatted API response data or a previously encoded `Route` object.
 */
public required init(from decoder: Decoder) throws {
    try super.init(from: decoder)
}

所以你需要输入类似:

let decoder = JSONDecoder()
decoder.underInfo = [CodingUserInfoKey.options: someRouteOptions]
// or
decoder.underInfo = [CodingUserInfoKey.options: someMatchOptions]

我不使用该框架,但我猜为什么应该使用哪个框架的用法他们的文档或 git repo 代码。您可以在那里搜索 RouteOptions/MatchOptions

It's a custom error thrown by the MapBox API.

From their code:

/**
 An error that occurs when encoding or decoding a type defined by the MapboxDirections framework.
 */
public enum DirectionsCodingError: Error {
    /**
     Decoding this type requires the `Decoder.userInfo` dictionary to contain the `CodingUserInfoKey.options` key.
     */
    case missingOptions
...
}

In Route, we can see the comments on init(from decoder:), which is, under the hood called by decoder.decode(_:from:):

/**
 Initializes a route from a decoder.
 
 - precondition: If the decoder is decoding JSON data from an API response, the `Decoder.userInfo` dictionary must contain a `RouteOptions` or `MatchOptions` object in the `CodingUserInfoKey.options` key. If it does not, a `DirectionsCodingError.missingOptions` error is thrown.
 - parameter decoder: The decoder of JSON-formatted API response data or a previously encoded `Route` object.
 */
public required init(from decoder: Decoder) throws {
    try super.init(from: decoder)
}

So you need to put, something like:

let decoder = JSONDecoder()
decoder.underInfo = [CodingUserInfoKey.options: someRouteOptions]
// or
decoder.underInfo = [CodingUserInfoKey.options: someMatchOptions]

I don't use that framework, but I guess that the usage on why which one to use should appear on their documentation or the git repo code. You can search maybe for RouteOptions/MatchOptions there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文