Criando uma Pokedex com Swift零件:2/3

消费JSON

Recapitulando单方前。

无需安装CocoaPods,也可以使用API​​ Alamofire,也可以使用Xcode。

Criando uma Pokedex com Swift零件:1/3
Instalando o CocoaPods medium.com

Hoje vamoscomeçaruma nova et et na nasóriadessa Pokedex maravilhosa que estamos criando。

Vamos colocar asmãosnocódigo,使用Alamofire(finalmente),使用JSON,使用criar解析tambémum模型,使用vamos utilizar na terceira eúltimaparte做教程。

您可以通过以下命令来完成全部任务。

Miciano / Pokedex
通过在GitHub上创建一个帐户为Pokedex开发做出贡献。 github.com

De onde vamos buscar作为信息吗?

Vamos使用RESTful 2版本的RESTful API,该信息可用于Atulizadas pela Bulbapedia。

RESTful API和pokeapi。

pokéapi–神奇宝贝RESTful API
Pokeapi Pokemon RESTful API pokeapi.co

埃斯特鲁图拉

Vamos fazer toda可以执行seguindo uma estrutura。

Nossa ViewController可作为一种必需品,可作为宠物小精灵的信息。

要求执行人无条件处理的类,由编程人员提供的示例性应答,由tratra um erro的示例性应答器提供,400例。

Elatambémvai enviar o retorno darequisiçãopara uma outra classe queiráfazer o parse dasinformationaçes,separando apenas o que queremos。

O解析ir criar um模型( Struct ),然后处理响应。

响应ViewController的响应,将Struct格式化。

一名criaçãoda estrutura vai de cada程序员。 欧盟将继续提供法律援助,因为有可能再犯错,也不能再因任何原因而被程序化。

Essa estrutura foi pensada em cima do MVVM( 模型—视图— ViewModel )。

面向协议的MVVM简介
在Swift中使用值类型而不是引用类型比在Objective-C中更容易,这使您的代码更加… realm.io Swift和Model-View-ViewModel在实践中– Cocoacasts
本周初,我写了关于Model-View-Controller模式的优缺点的文章。 在那篇文章中,我还做了…… cocoacasts.com Entendendo o模式模型-View-ViewModel(MVVM)–
控制权,因人而异的诉求,因果关系而来的法律,法西尔河畔达菲尔 imasters.com.br

修改信息列表

HTTPS的RestFull应用程序,HTTP应用程序,HTTP消息和其他信息,HTTP应用程序,HTTP消息和HTTP请求消息。

Abra o Info.plist做项目。

阿迪西翁(Adisicone),饰演阿贝西奥(chaix com os valores)。

Agora nosso projetoestáconfigurado,vamos parapróximaetapa。

Criando os模型

OS模型serão构造了quezen信息环境。

Vamos criartrês模型,pokedex模型,pokemon模型和erros do servidor模型。

模型或模型Pokedex

没有使用Project Navigator进行Xcode或Lao esquerdo进行建模的新方法,也无法创建新的模型组。

Na Pasta Models小组或其他文件的新文件。

Escolha或迅速组合Swift File。 De Pokedex模型。

Seguindo或JSON,网址为http://pokeapi.co/api/v2/pokemon/,o nosso model precisa de campos para armazenar océééuméééteiro,o 下一 ééuma字符串compróximapagina,é 上一个乌干达人先提出先决条件结果,然后再通知口袋妖怪。

Ocódigoficaráparecido com o abaixo。

 结构PokedexModel 
{
算一下:Int
接下来:String
让上一个:字符串
让结果:整数
}

Aindadápra melhorar essa Struct 。 Se der um erro no parse,ele precisar retornar um Model vazio,como vamos fazer?

参数解析器可扩展为可实现的自定义功能,可方便地从任何地方进行操作,并由Algo Vazio提供服务。

或完全免费阅读。

 结构PokedexModel 
{
算一下:Int
接下来:String
让上一个:字符串
让结果:整数
}
 扩展PokedexModel 
{
在里面()
{
self.count = 0
self.next =“”
self.previous =“”
self.results = 0
}
}

Agora vamos criar nosso模型que vaiguardar可以作为pokemons信息,seguindo o JSON或retorna da url http://pokeapi.co/api/v2/pokemon/2/进行示例。

Lógicoquenãovamos dar parse de todos os campos desse JSON。 Para esse post vamos utilizar apenastrêscampos。 口袋妖怪,我的世界,我的形象。

Na pasta de model swift,igual fizemos antes和com PokemonModel。

Nessa structtambémirei criar ométodoinit em um igual na classe acima。 Ocódigovai ficar parecido com o abaixo。

 结构口袋妖怪模型 
{
var id:Int
变量名称:字符串
var urlImage:字符串
}
 扩展PokemonModel 
{
在里面()
{
self.id = 0
self.name =“”
self.urlImage =“”
}
}

Falta oúltimo模型,queseráuma struct para armazenar o retorno de erro Qu o请求pode devolver。 服务器错误。

Essa structnãoteráum init em uma extension porquenãoqueremos um model de erro vazio,se erro eleteráque ser preenchido。

Esse模特会为您制作一份错误的监护人照,并为您准备一份错误的医护用品。 O模型ficaráparecido小姐。

  struct ServerError 
{
让msgError:String
让statusCode:Int
}

在最终建模模型的基础上,一个可简化的解析器使用JSON进行解析。

Criando o Parse

Teremos que criar parse de duas的要求:Pokedex e os Pokemons,seguindo os模型cri jaamos。

推荐给pegar的URL进行o JSON和pokedex e uma que的o分解为pokemon,para saber os nomes dos campos que vamos ter que usar。

Essas网址podem ser pegas没有网站,没有API que passei acima nesse post。

Vamoslá,clique com obotãodireito em cima da pasta do projeto e crie um novo grupo chamado视图模型。

视图模型和面食视图模型快速解析ParsePokedex。

Vamos criar umafunçãoque vai dar parse da pokedex ,或códigoficarámais ou menos assim。

  ParsePokedex类 
{
func parseAllPokedex(response:[String:Any]?)-> PokedexModel
{
//Façoo unwrap do dicionario enviado pelo请求,请为nulo aciono创建一个初始模型vazio
保护让响应=响应否则{return PokedexModel()}
  // Coloco os valores do dicionario em variaveis 
// caso alguma dessas chaves estiverem vazias o valor atribuido na variavelseráoqueestádepois do ??
 让count = response [“ count”]为?  Int ??  0 
让next = response [“ next”]为? 字符串?? ”
让previus = response [“ previous”]为? 字符串?? ”
// Preciso apenas da filhos do array
让resultList = response [“ results”]为? [[String:Any]] []
让结果= resultList.count
 返回PokedexModel(count:count,next:next,previus:previus,结果:结果) 
  } 
}

就像casque queestãodentro做response [“”]一样 ,foram pegas vendo o JSON或url retorna,nãofoi nada inventado。

Nesse可以根据要求解析pegamos os valores,colocamos um tipo eatribuímosno model da pokedex。

Opróximo解析éo dos 宠物小精灵。 JSON dos宠物小精灵,信息通知之声,虚拟世界,no id,id,imagem de frente。 Ocódigodesse解析ficarámais ou menos assim。

  func parsePokemon(response:[String:Any]?)-> PokemonModel 
{
后卫让响应=响应否则{return PokemonModel()}
 让名称= response [“名称”]为? 字符串??  ” 
让id = response [“ id”]为? Int ?? 0
让sprites = response [“ sprites”]为? [字符串:任何]
让urlImage = sprites?[“ front_default”]为? 字符串?? ”
 返回PokemonModel(id:id,name:名称,urlImage:urlImage) 
}

Agora vamos colocar frscuras…由TOC mesmo提出的问题。 Seolharmos bem,temos alguns [String:Any] pelos解析。 Vamos criar typealias para esses campos,para que a leitura fiquefácilquando outra pessoa olhar nossocódigo。

Vamos criar dois typealias。

  typealias ParseReponseDict = [String:任何]? 
typealias PokemonSpriteDict = [String:任何]

以前的时候,fazendo isso是一个普通的模拟汽车。

  typealias ParseReponseDict = [String:任何]? 
typealias PokemonSpriteDict = [String:任何]
  ParsePokedex类 
{
func parseAllPokedex(响应:ParseReponseDict)-> PokedexModel
{
保护让响应=响应否则{return PokedexModel()}
让count = response [“ count”]为? Int ?? 0
让next = response [“ next”]为? 字符串?? ”
让previus = response [“ previous”]为? 字符串?? ”
让resultList = response [“ results”]为? [[String:Any]] []
让结果= resultList.count
 返回PokedexModel(count:count,next:next,previus:previus,结果:结果) 
}
  func parsePokemon(响应:ParseReponseDict)-> PokemonModel 
{
后卫让响应=响应否则{return PokemonModel()}
 让名称= response [“名称”]为? 字符串??  ” 
让id = response [“ id”]为? Int ?? 0
让sprites = response [“ sprites”]为? 宠物小精灵
让urlImage = sprites?[“ front_default”]为? 字符串?? ”
 返回PokemonModel(id:id,name:名称,urlImage:urlImage) 
}
}

Agora temos nossos解析完整内容,Alamofire解析完整内容。

práximocoisa que vamos criarsãoos响应。

操作系统响应,枚举请求类,视图控制器视图,实现者的请求数量。

Issodámaissegurançaaocódigo,esqueçamosnenhum tratamento de erro ou sucesso

Criando os回应

可以使用ViewModel的Clique com bot或Direito em Cima做为原型,可以使用Swift的Cree um novo arquivo进行建模,还可以使用Pokedex的nome dele de Pokedex响应。

Vamos criar 3没有反应。

回复纳斯·梅斯·圣克·努斯compossíveisretornos que devemos tratar naaçãona qual estamos usando。

Primeiro响应vamos criaréo da pokedex,Os retornos delesãosucesso,服务器错误,超时,等等。

Nosso primeiro回复通过ficar assim。

 枚举PokedexResponse 
{
成功案例(型号:PokedexModel)
case serverError(描述:ServerError)
case timeOut(描述:ServerError)
案例noConnection(描述:ServerError)
}

您可以在模型模型中找到所需的模型,在模型中可以使用模型或模型。

神奇宝贝的反应:神奇宝贝的反应,神奇的力量,神奇宝贝的模样,神奇宝贝的模范,傻瓜般的模样。

 枚举PokemonResponse 
{
成功案例(型号:PokemonModel)
case serverError(描述:ServerError)
case timeOut(描述:ServerError)
案例noConnection(描述:ServerError)
}

JSON可能会发布宠物小精灵的图片,您的头像,vamos precisar de um,请您向baixar的女士提出vamos exibir的图片。 通过conta disso,teremos mais um response relacionadoàisso。

ImageResponse导致间质性前突或后突性数据。

您可以使用Alamofire图像或AlamofireImage图像下载,下载图像,然后在abordar isso上找到。 可以使用uma RESTful API。

Qualquer duvidasóolhar o link abaixo。

Alamofire / Alamofire图片
AlamofireImage是Alamofire github.com的图像组件库

O ImageResponse辅助功能或ABAXIX。

 枚举ImageResponse 
{
成功案例(型号:数据)
case serverError(描述:ServerError)
case timeOut(描述:ServerError)
案例noConnection(描述:ServerError)
}

esperados请求,请在最终通知中做出最终答复。

Criando os请求

查看模型可共享RequestPokedex。

Nessa classe vamos tertrêsfunçõespúblicas,uma para o request da pokedex,uma para os pokemons e outra para作为图像。

Lembra que criamos o解析? Pois bem,vamos criar umavariávelque inicia a classe。

  ResquestPokedex类 
{
让我们解析:ParsePokedex = ParsePokedex()
}

导入SessionManager的Alamofire和Nossa类。

可以根据需要配置SessionManager,也可以根据需要进行超时。

您可以在SessionManager中添加一个Alamofire的虚拟现实插件。

  //Importaçãodo Alamofire 
进口Alamofire
  ResquestPokedex类 
{
让alamofireManager:SessionManager = {
//Criaçãodasconfigurações
让配置= URLSessionConfiguration.default
// Tempo de timout em milisegundos
configuration.timeoutIntervalForRequest = 10000
configuration.timeoutIntervalForResource = 10000
返回SessionManager(配置:配置)
}()
 让我们解析:ParsePokedex = ParsePokedex() 
}

URL的Todos os nossos请求,请输入URL Main dos请求。

  struct PokemonAPIURL { 
static let Main:字符串=“ http://pokeapi.co/api/v2/pokemon/”
}

Casovocê精确的常见网址,bastacolocá-lasdentro da Struct

Vamos escrever agora nosso primeiro请求,结语。

或要求Seroke或Pokedex。 Ele vai nos trazer todos os pokemons com umapaginaçãode 20 pokemons。 由isso o nosso请求,请进一步获取getAllPokemons。

可以在com URL上完成参数设置,并实现ViewController。

  func getAllPokemons(url:String ?,完成:@转义(_响应:PokedexResponse)->无效) 
{
}

URL veio preenchido的基本信息。 URL的基础结构

  //验证URLévazia,对于coloco验证URL Main 
让页面=网址==“” || 网址==零? PokemonAPIURL.Main:网址?? ”

会话请求和获取的请求,并传递一个URL前缀。

  alamofireManager.request(页面,方法:.get,参数:无,编码:JSONEncoding.default).responseJSON 
{(回应)中
}

Quando或restonar precisamos tratar o sucesso ou o erro。 Então,dentro 完成 ,vamos pegar o statusCode e tratar或retorno com Swicth案例。

  // Pega o状态 
让statusCode = response.response?.statusCode
切换响应结果
{
//状态错误或成功
case .success(让值):
// JSON com retorno
让resultValue =值作为? [字符串:任何]
如果statusCode == 404
{
如果让description = resultValue?[“ detail”] as? 串
{
让错误= ServerError(描述:描述,错误代码:statusCode!)
完成(.serverError(描述:错误))
}
}
否则,如果statusCode == 200
{
让模型= self.parse.parseAllPokedex(响应:resultValue)
完成(.success(model:model))
}
案例。失败(让错误):
//状态错误
让errorCode = error._code
如果errorCode == -1009
{
让erro = ServerError(描述:error.localizedDescription,errorCode:errorCode)
完成(.noConnection(描述:错误))
}
否则,如果errorCode == -1001
{
让erro = ServerError(描述:error.localizedDescription,errorCode:errorCode)
完成(.timeOut(描述:错误))
}
}

如要求成功的发改委要求,请提供基本的手稿。

E nosso要求对pegar todos os pokemons fica assim。

  func getAllPokemons(url:String ?,完成:@转义PokedexCompletion) 
{
让页面=网址==“” || 网址==零? PokemonAPIURL.Main:网址!
alamofireManager.request(页面,方法:.get,参数:无,编码:JSONEncoding.default).responseJSON
{(回应)中
// Pega o状态
让statusCode = response.response?.statusCode
切换响应结果
{
//状态错误或成功
case .success(让值):
// JSON com retorno
让resultValue =值作为? [字符串:任何]
如果statusCode == 404
{
如果让description = resultValue?[“ detail”] as? 串
{
让错误= ServerError(描述:描述,错误代码:statusCode!)
完成(.serverError(描述:错误))
}
}
否则,如果statusCode == 200
{
让模型= self.parse.parseAllPokedex(响应:resultValue)
完成(.success(model:model))
}
案例。失败(让错误):
//状态错误
让errorCode = error._code
如果errorCode == -1009
{
让erro = ServerError(描述:error.localizedDescription,errorCode:errorCode)
完成(.noConnection(描述:错误))
}
否则,如果errorCode == -1001
{
让erro = ServerError(描述:error.localizedDescription,errorCode:errorCode)
完成(.timeOut(描述:错误))
}
}
}
}

投诉人要求提供完整的宠物小精灵口袋妖怪。 Mas ainda precisamos da imagem dele。 请以书面形式提出要求。

您可以要求提供任何担保,也可以要求提供完整的担保。

  func getPokemon(id:Int,完成:@转义(_响应:PokemonResponse)->无效) 
{

alamofireManager.request(“ \(PokemonAPIURL.Main)\(id)/”,方法:.get,参数:nil,编码:JSONEncoding.default)。responseJSON
{(回应)中

让statusCode = response.response?.statusCode
切换响应结果
{
case .success(让值):
让resultValue =值作为? [字符串:任何]
如果statusCode == 404
{
如果让description = resultValue?[“ detail”] as? 串
{
让错误= ServerError(描述:描述,错误代码:statusCode!)
完成(.serverError(描述:错误))
}
}
否则,如果statusCode == 200
{
// Mando para o pars dos pokemons
让模型= self.parse.parsePokemon(响应:resultValue)
完成(.success(model:model))
}
案例。失败(让错误):
让errorCode = error._code
如果errorCode == -1009
{
让erro = ServerError(描述:error.localizedDescription,errorCode:errorCode)
完成(.noConnection(描述:错误))
}
否则,如果errorCode == -1001
{
让erro = ServerError(描述:error.localizedDescription,errorCode:errorCode)
完成(.timeOut(描述:错误))
}
}
}
}

内塞·乌尔蒂莫(Nesseúltimo)请求。 宠物小精灵的验证与否,解析和区别于其他宠物小精灵。

Esseúltimo要求提供有关宠物小精灵的信息,以示例性方式提供。 URL格式的执行请求,以及对Baixar ESTA图像的请求。

Lembro mais uma vez que a forma correta de se baixar拍摄了éusando o Alamofire / Image,地点为美国。

要求图像处理。

  func getImagePokemon(URL:String,完成:@转义(_ response:ImageResponse)-> Void) 
{
// O Evento responseData vai devoler um objeto数据案例tenha sucesso
alamofireManager.request(URL,方法:.get).responseData
{(回应)中
 如果response.response?.statusCode == 200 
{
// Se o obejto数据视图nulo mesmo retornando 200 algum erro aconteceu
 保护让数据= response.data其他 
{
let erro = ServerError(描述:“ Falha no Download,数据vazio”,错误代码:404)
完成(.serverError(描述:错误))
返回
}
//还原一个图像
完成(.success(model:data))
}
其他
{
let erro = ServerError(描述:“ Falha no Download,数据vazio”,错误代码:404)
完成(.serverError(描述:错误))
}
}
}

Pois bem,Terminamos Todos os要求,sabe o que falta吗? Testar!

Precisamos saber se nossos要求提供功能。

德兰多

参数实物视图模块ViewController.swift,示例3函数,对象示例请求结果。

要求。

  // Variavel响应实际的待办事项 
让请求= ResquestPokedex()

Agora vamos可以执行请求的功能

  func showPokedex() 
{
// Passando nil como URL ele vai pegar a URLpadrão
request.getAllPokemons(url:nil)
{(回应)中
 切换响应 
{
案例。成功(让模型):
//打印模型
打印(“ X GET ALL POKEMONS \(模型)​​\ n”)
// Chamo a proximafunçãopara exibir um pokemon especifico
self.showPokemons()
案例.serverError(让描述):
打印(“服务器错误\(描述)”)
案例.noConnection(让描述):
打印(“无连接\(描述)”)
案例.timeOut(让描述):
print(“超时\(描述)”)
}
}
}

Prokexima etapaécriar afunçãoshowPokemons usada nocódigoacima。

  func showPokemons() 
{
// Um idéPassado para que busque um pokemon especifico
request.getPokemon(id:1)
{(回应)中
 切换响应 
{
案例。成功(让模型):
//打印做模型做口袋妖怪
打印(“ Y GET POKEMON \(模型)​​\ n”)
// Chamo a proximafunçãopara exibir a imagem
self.showImagePokemon(urlImage:model.urlImage)
案例.serverError(让描述):
打印(“服务器错误\(描述)”)
案例.noConnection(让描述):
打印(“无连接\(描述)”)
案例.timeOut(让描述):
print(“超时\(描述)”)
}
}
}

超现实主义的图像,美国前科迪戈。

  func showImagePokemon(urlImage:String) 
{
//传递一个URL和图片
request.getImagePokemon(url:urlImage)
{(回应)中
    切换响应 
{
案例。成功(让模型):
//打印模型数据
打印(“ Z IMAGE POKEMON \(模型)​​”)
案例.serverError(让描述):
打印(“服务器错误\(描述)”)
案例.noConnection(让描述):
打印(“无连接\(描述)”)
案例.timeOut(让描述):
print(“超时\(描述)”)
}
}
}

暂无viewDidLoad外观,可在primairafunção上运行。

 覆盖func viewDidLoad(){ 
super.viewDidLoad()
//加载视图后进行其他任何设置,通常是从笔尖进行。
showPokedex()
}

不能使用seu控制台构建和运行(Command + R)。

没有próximoepisódio

没有发布有关UITableViewController的可视化视图和最终版本的信息。