简体   繁体   English

我如何重写此函数,以便它使用SwiftyJSON而不是JSON.swift?

[英]How can I rewrite this function so that it uses SwiftyJSON instead of JSON.swift?

I'm looking at the Ray Wenderlich tutorial http://www.raywenderlich.com/90971/introduction-mapkit-swift-tutorial and he is using there this function: 我正在看Ray Wenderlich教程http://www.raywenderlich.com/90971/introduction-mapkit-swift-tutorial ,他在那里使用此功能:

class func fromJSON(json: [JSONValue]) -> Artwork? {
  // 1
  var title: String
  if let titleOrNil = json[16].string {
    title = titleOrNil
  } else {
    title = ""
  }
  let locationName = json[12].string
  let discipline = json[15].string

  // 2
  let latitude = (json[18].string! as NSString).doubleValue
  let longitude = (json[19].string! as NSString).doubleValue
  let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)

  // 3
  return Artwork(title: title, locationName: locationName!, discipline: discipline!, coordinate: coordinate)
}

Since I'm using SwiftyJSON in my project I would like to stay with that, so I thought about rewriting this function based on that. 由于我在项目中使用SwiftyJSON,因此我希望继续这样做,因此我考虑基于此重写此函数。

If I understand correctly, this function takes one json node and creates Artwork object from it. 如果我理解正确,此函数将使用一个json节点并从中创建Artwork对象。

So how can I refer to a single json node with SwiftyJSON? 那么如何用SwiftyJSON引用单个json节点呢?

I tried doing: 我试着做:

class func fromJSON(JSON_: (data: dataFromNetworking))->Artwork?{

}

but it causes error use of undeclared type dataFromNetworking . 但这会导致错误use of undeclared type dataFromNetworking On the other hand that's exactly how they use it in the documentation https://github.com/SwiftyJSON/SwiftyJSON 另一方面,这正是他们在文档https://github.com/SwiftyJSON/SwiftyJSON中的使用方式

Could you help me with rewriting it? 您能帮我改写吗?

My suggestion: separate the model layer from the presentation layer . 我的建议:将model layerpresentation layer分开。

ArtworkModel 艺术品模型

First of all you need a way to represent the data. 首先,您需要一种表示数据的方法。 A struct is perfect for this. 一个结构是完美的。

struct ArtworkModel {
    let title: String
    let locationName: String
    let discipline: String
    let coordinate: CLLocationCoordinate2D

    init?(json:JSON) {
        guard let
            locationName = json[12].string,
            discipline = json[15].string,
            latitudeString = json[18].string,
            latitude = Double(latitudeString),
            longitueString = json[19].string,
            longitude = Double(longitueString) else { return nil }
        self.title = json[16].string ?? ""
        self.locationName = locationName
        self.discipline = discipline
        self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

As you can see ArtworkModel is capable to initialize itself from a json. 如您所见,ArtworkModel能够从json初始化自身。

The presentation layer 表示层

Now the Artwork (conform to MKAnnotation ) becomes much easier. 现在, Artwork (符合MKAnnotation )变得容易得多。

class Artwork: NSObject, MKAnnotation {
    private let artworkModel: ArtworkModel

    init(artworkModel: ArtworkModel) {
        self.artworkModel = artworkModel
        super.init()
    }

    var title: String? { return artworkModel.title }
    var subtitle: String? { return artworkModel.locationName }
    var coordinate: CLLocationCoordinate2D { return artworkModel.coordinate }
}

Usage 用法

You function now becomes 您的职能现在变为

class func fromJSON(json: JSON) -> Artwork? {
    guard let model = ArtworkModel(json: json) else { return nil }
    return Artwork(artworkModel: model)
}

To use SwiftyJSON in this project first you have to change the method to retrieve the data from the property list file. SwiftyJSON在此项目中使用SwiftyJSON ,您必须更改从属性列表文件检索数据的方法。

Note: This replacement is for Swift 2. 注意:此替换用于Swift 2。

Replace the method loadInitialData() in ViewController with ViewController loadInitialData()方法替换为

  func loadInitialData() {

    do {
      let fileName = NSBundle.mainBundle().pathForResource("PublicArt", ofType: "json")
      let data = try NSData(contentsOfFile: fileName!, options: NSDataReadingOptions())

      let jsonObject = JSON(data:data)
      if let jsonData = jsonObject["data"].array {
        for artworkJSON in jsonData {
          if let artworkJSONArray = artworkJSON.array, artwork = Artwork.fromJSON(artworkJSONArray) {
            artworks.append(artwork)
          }
        }
      }
    } catch let error as NSError {
      print(error)
    }
  }

And then just exchange [JSONValue] in the method 然后只需在方法中交换[JSONValue]

class func fromJSON(json: [JSONValue]) -> Artwork? {

of the Artwork class with [JSON] , so it's now 具有[JSON]Artwork类的[JSON] ,现在

class func fromJSON(json: [JSON]) -> Artwork? {

That's it. 而已。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM