【问题标题】:My API request code produces a bug I can't debug or understand我的 API 请求代码产生了一个我无法调试或理解的错误
【发布时间】:2019-05-28 12:05:13
【问题描述】:

我不确定在这段代码中哪里发现了问题

var events = [Events]()

    let URL_GET_DATA = "http://192.168.100.4/PrototypeWebService/api/getevents.php"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        Alamofire.request(URL_GET_DATA).responseJSON{ response in
            if let json = response.result.value {
                print(json)
                let swiftvar = JSON(json).array
                for i in 0..<(swiftvar?.count)! {
                    let jsonObject = swiftvar?[i].object
                    self.events.append(jsonObject as! Events)
                }
                self.EventTable.reloadData()
            }
        }
    } 

我希望它创建一个事件类型的对象数组,但它会产生这个错误:

线程 1:EXC_BREAKPOINT(代码=1,子代码=0x102ca0f4c

【问题讨论】:

  • 代码很不安全,你应该将swiftvar不可变值的初始化包装到if let子句中。此外,jsonObject as! Events 强制转换是一个可能的失败点,我真的怀疑这甚至是可向下转换的。请尝试编写代码以避免强制转换。

标签: swift alamofire swifty-json


【解决方案1】:

首先,我们鼓励您放弃SwiftyJSON,转而使用Codable

发生错误是因为 (Swifty)JSON 对象无法转换为自定义结构或类。

您必须将 JSON 值传递给自定义结构的初始化程序。

struct Event { // it's highly recommended to name this kind of object in singular form
   let varA : String
   let varB : Int

   init(json: JSON) {
      self.varA = json["varA"].string ?? ""
      self.varB = json["varB"].int ?? 0
   }
}

如果您实际上根本不需要索引,请永远不要使用基于索引的循环。从JSON 对象创建一个Event 实例并附加它

guard let swiftvar = JSON(json).array else { return }
for item in swiftvar {
     let event = Event(json: item)
     self.events.append(event)
}

甚至更简单

guard let swiftvar = JSON(json).array else { return }
self.events = swiftvar.map{ Event(json: $0) } 

【讨论】:

  • 非常感谢 .. 实际上我是 swift 的初学者,所以可编码和可解码的概念对我来说仍然很陌生
  • 如果你能帮我提供一个示例教程
  • 我遇到一个运行时错误,提示 Extra argument 'json' in call 两个选项
  • 在哪一行?
  • 这里:让 event = Events(json: item)
【解决方案2】:

您的代码使 SwiftJSON API 出错。罪魁祸首是线路

jsonObject as! Events

如果您实际上是使用 as? 动态向下转换运算符以安全的方式编写代码,编译器会很高兴地向您说明 Events 类型和 jsonObject 类型是不同类型层次结构的一部分,因此向下转换总是会失败。

根据可在https://github.com/SwiftyJSON/SwiftyJSON 找到的 SwiftJSON 文档,该框架确实管理反序列化,但其基本 API 不提供任何对象填充设施,因此这是程序员的任务。

比如说,Events 类型有 2 个存储属性,let string: Stringlet int: Int。 为了从解析的 JSON 对象创建 Events 对象,您需要手动提取值

let string = jsonObject["name"].string
let int = jsonObject["int"].int

然后你应该将这些值传递给你自己的自定义构造函数

let events = Events(string, int)

只有在这一点之后,您才会真正拥有一个可以使用的 Events 对象。

编辑:自 Swift 4 发布以来,还有一个 Codable 协议和一个 JSONDecoder 类型,它们提供了一个强大、灵活和类型安全的工具来解码由 Data 对象和你表示的 json 有效负载应该放弃 SwiftyJSON,因为它是不必要的依赖。

【讨论】:

  • 非常感谢 .. 实际上我是 swift 的初学者,所以可编码和可解码的概念对我来说仍然很陌生
  • 如果你能帮我提供一个示例教程
猜你喜欢
  • 2021-07-04
  • 2015-06-30
  • 2018-06-21
  • 2016-08-22
  • 2020-11-08
  • 1970-01-01
  • 2013-09-26
  • 2018-12-20
  • 2018-12-13
相关资源
最近更新 更多