Модель JSON - PullRequest
       14

Модель JSON

0 голосов
/ 26 мая 2018

Мне нужно создать хорошую модель для передачи данных, полученных из JSON, на другие мои контроллеры.Как бы вы, ребята, сделали это?Мне нужно получить доступ к этим свойствам внутри моей структуры, где бы я ни был в проекте, чтобы иметь возможность заполнять компоненты пользовательского интерфейса и т. Д.

Это мой файл ответов 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 голосов
/ 26 мая 2018

1.Рефакторинг модели

Во-первых, давайте обратимся к названию модели для data.
Сделаем его ImageData, потому что имена типов должны быть в Pascal Cased (это просто хорошее соглашение о кодировании).например, ClassName, StructName, PascalCase.
Мы также не хотим, чтобы он назывался Data, поскольку это приведет к перегрузке Foundation 'Data типа.

Такнаши модели будут:

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

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

2.Синглтон

Мне нужно получить доступ к этим свойствам внутри моей структуры, где бы я ни хотел в проекте

В этом случае я бы использовал синглтон, который имеет ссылку намассив изображений.

Пример:

class SharedManager {        
    static let shared = SharedManager()
    private init() {}

    var images: [ImageData]?
}

3.Service Helper

Позволяет написать новый класс с именем APIHelper, который будет действовать как сервисный помощник.Здесь у нас будет логика Alamofire, поэтому давайте улучшим ее.

  1. Позволяет переименовать callApi(completion:) во что-то более значимое, скажем, getImages(completion:)
  2. Позволяет сделать этометод класса для удобства.
  3. Кроме того, вместо закрытия завершения, обеспечивающего (String, String), позвольте ему предоставить [ImageData]?;то есть массив ImageData моделей.
    • Для более легкого доступа позже в приложении
    • Этот массив является необязательным в случае, если url-адрес недействителен или запрос / синтаксический анализ не удаются (просто он прост)

:

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)
                }
        }
    }

}

4.Установите массив в синглтоне

. Вызовите getImages(completion:) один раз, чтобы установить SharedManager.shared.images следующим образом:

APIHelper.getImages { (imageData) in
    print(imageData)
    SharedManager.shared.images = imageData
}

5.Использование

Теперь у вас должна быть возможность доступа к массиву изображений через SharedManager.shared.images в любое время и в любом месте (в пределах области вашего приложения)

Просто ваша базовая логика обработки массива, но вот несколько примеров:

  • Цикл по ним:

    for imageData in SharedManager.shared.images ?? [] {
        print(imageData)
    }
    
  • Доступ к изображению по определенному индексу

    let imageIndex = 1
    let imageURL = SharedManager.shared.images?[imageIndex].urlImagem
    print(imageURL)
    
  • Найти изображение с определенным идентификатором:

    let imageIDToFind = 7
    let foundImage = SharedManager.shared.images?.first { $0.id == imageIDToFind }
    print(foundImage)
    
...