JSON模型建议

时间:2018-05-26 06:45:01

标签: json model-view-controller alamofire swift4 xcode9

我必须创建一个好的模型,将从JSON接收的数据传递给我的其他控制器。你们会怎么做?我需要在项目中的任何地方访问我的struct中的这些属性,以便能够填充UI组件等。

这是我的API响应文件:

import Foundation
import Alamofire

struct Description: Decodable {
    let data: [data]
}

struct data: Decodable {

    let id:Int?
    let descricao:String?
    let urlImagem:String?
}

func callApi(completion: @escaping (String, String) -> Void) {

    guard let _url = URL(string: "https://alodjinha.herokuapp.com/categoria")else{return}
    Alamofire.request(_url).responseJSON { (response) in

        guard let info = response.data else{return}

        do{
            let dataParsed = try JSONDecoder().decode(Description.self, from: info)

            for aData in dataParsed.data {


                completion(aData.descricao!, aData.urlImagem!)
            }

        }catch{
        print("Error serialization: \(error)")


}
}
}

这是我收到的JSON模型:

{
  "data": [
    {
      "id": 1,
      "descricao": "Games",
      "urlImagem": "http:\/\/39ahd9aq5l9101brf3b8dq58.wpengine.netdna-cdn.com\/wp-content\/uploads\/2013\/06\/3D-Gaming.png"
    },
    {
      "id": 2,
      "descricao": "Livros",
      "urlImagem": "http:\/\/4.bp.blogspot.com\/-6Bta1H9d22g\/UJAIJbqcHhI\/AAAAAAAAKi4\/hvgjWrlFc64\/s1600\/resenha-missiologia.png"
    },
    {
      "id": 3,
      "descricao": "Celulares",
      "urlImagem": "http:\/\/pt.seaicons.com\/wp-content\/uploads\/2015\/11\/Mobile-Smartphone-icon.png"
    },
    {
      "id": 4,
      "descricao": "Inform\u00e1tica",
      "urlImagem": "http:\/\/portal.ifrn.edu.br\/campus\/ceara-mirim\/noticias\/ifrn-oferece-curso-de-informatica-basica-para-pais-dos-estudantes\/image_preview"
    },
    {
      "id": 5,
      "descricao": "Eletrodom\u00e9stico",
      "urlImagem": "http:\/\/classificados.folharegiao.com.br\/files\/classificados_categoria\/photo\/8\/sm_4d5ed3beb0f31b61cb9a01e46ecd0cf9.png"
    },
    {
      "id": 6,
      "descricao": "TVs",
      "urlImagem": "http:\/\/i.utdstc.com\/icons\/256\/terrarium-tv-android.png"
    },
    {
      "id": 7,
      "descricao": "Filmes e S\u00e9ries",
      "urlImagem": "https:\/\/pbs.twimg.com\/profile_images\/801033586438733824\/91Y_N91t_reasonably_small.jpg"
    },
    {
      "id": 8,
      "descricao": "M\u00f3veis e Decora\u00e7\u00f5es",
      "urlImagem": "https:\/\/image.flaticon.com\/icons\/png\/128\/148\/148188.png"
    },
    {
      "id": 9,
      "descricao": "Moda, Beleza e Perfumaria",
      "urlImagem": "http:\/\/icon-icons.com\/icons2\/196\/PNG\/128\/fashion_23852.png"
    },
    {
      "id": 10,
      "descricao": "Papelaria",
      "urlImagem": "http:\/\/esen.pt\/in\/images\/stories\/skills_256.png"
    }
  ]
}

非常感谢你!

1 个答案:

答案 0 :(得分:1)

1。模型重构

首先,让我们解决data的型号名称 设为ImageData因为类型名称应该是Pascal Cased(它只是一个很好的编码约定)。例如ClassNameStructNamePascalCase 我们也不希望将其称为Data,因为这会超出Foundation的{​​{1}}类型。

所以我们的模型将是:

Data

2。单

  

我需要在我想要的任何地方访问这些属性   在项目中

在这种情况下,我会使用一个对图像数组有引用的单例。

示例:

struct Description: Decodable {
    let data: [ImageData]
}

struct ImageData: Decodable {
    let id: Int
    let descricao: String
    let urlImagem: String
}

3。服务助手

让我们写一个名为class SharedManager { static let shared = SharedManager() private init() {} var images: [ImageData]? } 的新类,它将扮演服务助手的角色。在这里,我们将拥有APIHelper逻辑,所以我们也可以改进它。

  1. 让我们将Alamofire重命名为更有意义的内容,例如callApi(completion:)
  2. 为方便起见,请将此作为一种类方法。
  3. 此外,请提供getImages(completion:),而不是提供(String, String)的完成时段。即[ImageData]?模型的数组。
    • 以便日后在应用中轻松访问
    • 如果网址无效或请求/解析失败(仅保持简单),此数组是可选的
  4. ImageData

    4。在单例

    中设置数组

    拨打class APIHelper { class func getImages(completion: @escaping ([ImageData]?)->Void) { guard let url = URL(string: "https://alodjinha.herokuapp.com/categoria") else { completion(nil) return } Alamofire .request(url) .responseJSON { (response) in switch response.result { case .success(_): do { let myImages = try JSONDecoder().decode(Description.self, from: response.data!) completion(myImages.data) } catch { print(error) completion(nil) } case .failure(let error): print(error) completion(nil) } } } } 一次设置getImages(completion:),如下所示:

    SharedManager.shared.images

    5。使用

    现在,您应该可以随时随地通过APIHelper.getImages { (imageData) in print(imageData) SharedManager.shared.images = imageData } 访问图像数组(在您的应用范围内)

    只是你的基本数组处理逻辑,但这里有几个例子:

    • 循环播放:

      SharedManager.shared.images
    • 访问特定索引处的图像

      for imageData in SharedManager.shared.images ?? [] {
          print(imageData)
      }
      
    • 查找具有特定ID的图片:

      let imageIndex = 1
      let imageURL = SharedManager.shared.images?[imageIndex].urlImagem
      print(imageURL)