Eu tenho um arquivo JSON, quero analisar e usar a lista de objetos no modo de exibição de tabela. Qualquer um pode compartilhar o código para analisar o arquivo JSON rapidamente.
Por exemplo,let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
Caroline
4
O problema com essa abordagem é que você acaba com um monte de objetos de base. Ou seja, NSString, NSNumber, NSArray, NSDictionary ou NSNull. O que cria uma grande carga de down casting se você quiser lidar com Swift nativo digitado posteriormente em seu código. Especialmente se você tiver dicionários e matrizes aninhados. Alguém sabe como lidar com isso?
@bubakazouba: É uma pena que não posso votar contra um comentário. Algumas coisas: 1. Caroline já forneceu um snippet para carregar dados de um arquivo (que é o que OP queria). 2. Seu código usa codificação ASCII que perde todos os símbolos Unicode, incluindo suporte para idiomas além do inglês.
akashivskyy
43
Fazendo a solicitação de API
var request:NSURLRequest=NSURLRequest(URL: url)var connection:NSURLConnection=NSURLConnection(request: request, delegate:self, startImmediately:false)
Preparando-se para a resposta
Declare uma matriz como abaixo
var data:NSMutableData=NSMutableData()
Recebendo a resposta
1
func connection(didReceiveResponse:NSURLConnection!, didReceiveResponse response:NSURLResponse!){// Received a new request, clear out the data object
self.data =NSMutableData()}
2
func connection(connection:NSURLConnection!, didReceiveData data:NSData!){// Append the received chunk of data to our data object
self.data.appendData(data)}
3 -
func connectionDidFinishLoading(connection:NSURLConnection!){// Request complete, self.data should now hold the resulting info
// Convert the retrieved data in to an object through JSON deserialization
var err:NSErrorvar jsonResult:NSDictionary=NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error:nil)asNSDictionaryif jsonResult.count>0&& jsonResult["results"].count>0{var results:NSArray= jsonResult["results"]asNSArrayself.tableData = results
self.appsTableView.reloadData()}}
Ao NSURLConnectionreceber uma resposta, podemos esperar que o didReceiveResponsemétodo seja chamado em nosso nome. Neste ponto, simplesmente redefinimos nossos dados dizendoself.data = NSMutableData() , criando um novo objeto de dados vazio.
Depois que uma conexão for feita, começaremos a receber dados no método didReceiveData . O argumento de dados transmitido aqui é de onde vêm todas as nossas informações interessantes. Precisamos nos agarrar a cada fragmento que chega, então o acrescentamos ao objeto self.data que limpamos anteriormente.
Por fim, quando a conexão é feita e todos os dados foram recebidos, connectionDidFinishLoadingé chamado e estamos prontos para usar os dados em nosso aplicativo. Hooray!
O connectionDidFinishLoadingmétodo aqui usa oNSJSONSerialization classe para converter nossos dados brutos em Dictionaryobjetos úteis desserializando os resultados de seu Url.
Uma pergunta sobre seu repositório Github: como você realmente executa o main.swift? Estou tendo problemas para executá-lo de dentro do playground, pois você não consegue se referir às classes definidas em seu próprio projeto do playground (?!) Obrigado!
Janos
Eu marquei os métodos públicos no último repo. Isso torna o requisito mínimo para Beta4, então não se esqueça de atualizar o Xcode antes de tentar
dankogai
Ok, obrigado, eu estava realmente procurando como exatamente executar o código de exemplo. Tentei playgroung, mas não funcionou porque não consegui fazer referência à classe JSON (é um problema conhecido que você não pode referir às classes em seu projeto)
Janos
Não consigo fazer funcionar :( Desta vez não estou tentando usá-lo no playground, adicionei seu json.swift ao meu projeto e em outra aula estou tentando usá-lo. Não funciona. Eu tentei o JSON mais simples: {"id": "Janos"}, criei o objeto JSON, chamou seu método toString, ele cospe o conteúdo do arquivo corretamente, no entanto, quando chamo myJson ["id"]. AsString recebo nulo. O que estou perdendo?
Janos
Eu estava tentando construir um objeto JSON passando um String no construtor ... Mudei a forma como você faz no exemplo, agora funciona muito bem. A única questão é qual usar agora, o seu ou o SwiftyJSon :)
Janos
4
Aqui está um código para fazer as conversões entre JSON e NSData em Swift 2.0
// Convert from NSData to json object
func nsdataToJSON(data:NSData)->AnyObject?{do{returntryNSJSONSerialization.JSONObjectWithData(data, options:.MutableContainers)}catchlet myJSONError {
print(myJSONError)}returnnil}// Convert from JSON to nsdata
func jsonToNSData(json:AnyObject)->NSData?{do{returntryNSJSONSerialization.dataWithJSONObject(json, options:NSJSONWritingOptions.PrettyPrinted)}catchlet myJSONError {
print(myJSONError)}returnnil;}
Em Swift 4+ é altamente recomendável usar em Codablevez de JSONSerialization.
Isso Codableinclui dois protocolos: Decodablee Encodable. Este Decodableprotocolo permite que você decodifiqueData no formato JSON para uma estrutura / classe personalizada em conformidade com este protocolo.
Por exemplo, imagine a situação em que temos este simples Data(array de dois objetos)
let data =Data("""
[
{"name":"Steve","age":56},
{"name":"iPhone","age":11}
]
""".utf8)
então siga structe implemente o protocoloDecodable
agora você pode decodificar seu Datapara sua matriz de Personuso JSONDecoderonde o primeiro parâmetro é o tipo em conformidade Decodablee para este tipo deve Dataser decodificado
do{let people =tryJSONDecoder().decode([Person].self, from: data)}catch{ print(error)}
... note que a decodificação deve ser marcada com uma trypalavra - chave já que você pode, por exemplo, cometer algum erro com a nomenclatura e então seu modelo não pode ser decodificado corretamente ... então você deve colocá-lo dentro do bloco do-try-catch
Casos em que a chave em json é diferente do nome da propriedade:
Se a chave for nomeada usando snake_case, você pode definir o decodificador keyDecodingStrategypara o convertFromSnakeCasequal muda a chave de property_namepara camelCasepropertyName
let decoder =JSONDecoder()
decoder.keyDecodingStrategy =.convertFromSnakeCase
let people =try decoder.decode([Person].self, from: data)
Se você precisar de um nome único, você pode usar chaves de codificação dentro de struct / classe onde você declara o nome da chave
let data =Data("""
{ "userName":"Codable", "age": 1 }
""".utf8)structPerson:Decodable{let name:Stringlet age:IntenumCodingKeys:String,CodingKey{case name ="userName"case age
}}
Também escrevi uma pequena biblioteca especializada no mapeamento da resposta json em uma estrutura de objeto. Estou usando internamente a biblioteca json-swift de David Owens. Talvez seja útil para outra pessoa.
Então, para realmente mapear os objetos da resposta JSON, você só precisa passar os dados para a classe EmployeeContainer como parâmetro no construtor. Ele cria automaticamente seu modelo de dados.
var baseWebservice:BaseWebservice=BaseWebservice();var urlToJSON ="http://prine.ch/employees.json"var callbackJSON ={(status:Int, employeeContainer:EmployeeContainer)->()infor employee in employeeContainer.employees {
println("Firstname: \(employee.firstname) Lastname: \(employee.lastname) age: \(employee.age)")}}
baseWebservice.get(urlToJSON, callback:callbackJSON)
Perdoe minha ignorância. Quais são as vantagens de usar sua biblioteca em vez de uma como o SwiftyJSON?
Levi Roberts
6
Inicialmente, eu construí isso porque não gostava da ideia de operadores / símbolos de hackeamento de linguagem. Além disso, eu o construí para me familiarizar com o Swift. Por curiosidade, executei um benchmark e descobri que o SwiftyJSON tem velocidade superior (~ 2 - 7 vezes mais rápido). Eu atualizei o README do repo para admitir isso.
Mike Rapadas
Obrigado pela sua resposta.
Levi Roberts
Você pode mostrar um exemplo de como carregaria uma matriz de dados do JSON (vários itens essencialmente com um loop etc ...)
Joseph Astrahan
2
Analisar JSON em Swift é um excelente trabalho para geração de código. Criei uma ferramenta em http://www.guideluxe.com/JsonToSwift para fazer exatamente isso.
Você fornece um objeto JSON de amostra com um nome de classe e a ferramenta irá gerar uma classe Swift correspondente, bem como quaisquer classes Swift subsidiárias necessárias, para representar a estrutura implícita pelo JSON de amostra. Também estão incluídos métodos de classe usados para preencher objetos Swift, incluindo um que utiliza o método NSJSONSerialization.JSONObjectWithData. Os mapeamentos necessários dos objetos NSArray e NSDictionary são fornecidos.
A partir do código gerado, você só precisa fornecer um objeto NSData contendo JSON que corresponda à amostra fornecida para a ferramenta.
Além da Foundation, não há dependências.
Meu trabalho foi inspirado em http://json2csharp.com/ , que é muito útil para projetos .NET.
Veja como criar um objeto NSData a partir de um arquivo JSON.
let fileUrl: NSURL =NSBundle.mainBundle().URLForResource("JsonFile", withExtension:"json")!let jsonData:NSData=NSData(contentsOfURL: fileUrl)!
Desculpe por isso, eu estava colando o URL JSON diretamente, funciona bem colando a resposta JSON. Seria fabuloso ter um URL colado diretamente. Mas um trabalho brilhante para este utilitário. Obrigado.
ioopl
A ferramenta que você criou é simplesmente incrível. Estou usando essa ferramenta desde os últimos 6 meses. Mas de repente, nos últimos 3 dias, seu site não está acessível e o navegador está respondendo com esta mensagem "Este site não pode ser alcançado". Então, qual é a razão por trás disso?
let parsedResult:[String:AnyObject]do{
parsedResult =tryJSONSerialization.jsonObject(with: data, options:.allowFragments)as![String:AnyObject]}catch{// Display an error or return or whatever
}
dados - é o tipo de dados (estrutura) (ou seja, retornado por alguma resposta do servidor)
Respostas:
Não poderia ser mais simples:
Dito isso, eu recomendo fortemente o uso de APIs codificáveis introduzidas no Swift 4.
fonte
let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
NSData(contentsOfFile: path)
. Consulte developer.apple.com/library/ios/documentation/Cocoa/Reference/… :Fazendo a solicitação de API
Preparando-se para a resposta
Declare uma matriz como abaixo
Recebendo a resposta
1
2
3 -
Ao
NSURLConnection
receber uma resposta, podemos esperar que odidReceiveResponse
método seja chamado em nosso nome. Neste ponto, simplesmente redefinimos nossos dados dizendoself.data = NSMutableData()
, criando um novo objeto de dados vazio.Depois que uma conexão for feita, começaremos a receber dados no método
didReceiveData
. O argumento de dados transmitido aqui é de onde vêm todas as nossas informações interessantes. Precisamos nos agarrar a cada fragmento que chega, então o acrescentamos ao objeto self.data que limpamos anteriormente.Por fim, quando a conexão é feita e todos os dados foram recebidos,
connectionDidFinishLoading
é chamado e estamos prontos para usar os dados em nosso aplicativo. Hooray!O
connectionDidFinishLoading
método aqui usa oNSJSONSerialization
classe para converter nossos dados brutos emDictionary
objetos úteis desserializando os resultados de seu Url.fonte
Acabei de escrever uma classe chamada JSON, que torna o manuseio de JSON no Swift tão fácil quanto o objeto JSON no ES5.
Transforme seu objeto swift em JSON assim:
... ou string ...
... ou URL.
Basta percorrer os elementos por meio do subscrito:
Assim como o SwiftyJSON, você não se preocupe se a entrada subscrita não existir.
Se você está cansado de subscritos, adicione seu esquema assim:
E você vai:
Espero que você goste.
Com o novo xCode 7.3+, é importante adicionar seu domínio à lista de exceções ( como posso adicionar NSAppTransportSecurity ao meu arquivo info.plist? ), Consulte esta postagem para obter instruções, caso contrário, você receberá um erro de autoridade de transporte.
fonte
Aqui está um código para fazer as conversões entre JSON e NSData em Swift 2.0
fonte
Codificável
Em Swift 4+ é altamente recomendável usar em
Codable
vez deJSONSerialization
.Isso
Codable
inclui dois protocolos:Decodable
eEncodable
. EsteDecodable
protocolo permite que você decodifiqueData
no formato JSON para uma estrutura / classe personalizada em conformidade com este protocolo.Por exemplo, imagine a situação em que temos este simples
Data
(array de dois objetos)então siga
struct
e implemente o protocoloDecodable
agora você pode decodificar seu
Data
para sua matriz dePerson
usoJSONDecoder
onde o primeiro parâmetro é o tipo em conformidadeDecodable
e para este tipo deveData
ser decodificado... note que a decodificação deve ser marcada com uma
try
palavra - chave já que você pode, por exemplo, cometer algum erro com a nomenclatura e então seu modelo não pode ser decodificado corretamente ... então você deve colocá-lo dentro do bloco do-try-catchCasos em que a chave em json é diferente do nome da propriedade:
Se a chave for nomeada usando snake_case, você pode definir o decodificador
keyDecodingStrategy
para oconvertFromSnakeCase
qual muda a chave deproperty_name
para camelCasepropertyName
Se você precisar de um nome único, você pode usar chaves de codificação dentro de struct / classe onde você declara o nome da chave
fonte
Também escrevi uma pequena biblioteca especializada no mapeamento da resposta json em uma estrutura de objeto. Estou usando internamente a biblioteca json-swift de David Owens. Talvez seja útil para outra pessoa.
https://github.com/prine/ROJSONParser
Exemplo Employees.json
Na próxima etapa, você deve criar seu modelo de dados (EmplyoeeContainer e Employee).
Employee.swift
EmployeeContainer.swift
Então, para realmente mapear os objetos da resposta JSON, você só precisa passar os dados para a classe EmployeeContainer como parâmetro no construtor. Ele cria automaticamente seu modelo de dados.
A saída do console se parece com o seguinte:
fonte
SwiftJSONParse : Analise JSON como um fodão
Morto simples e fácil de ler!
Exemplo: obtenha o valor
"mrap"
denicknames
como uma String desta resposta JSONLeva seus dados json
NSData
como estão, sem necessidade de pré-processamento.Disclaimer: Eu fiz isso e espero que ajude a todos. Sinta-se à vontade para melhorar!
fonte
Analisar JSON em Swift é um excelente trabalho para geração de código. Criei uma ferramenta em http://www.guideluxe.com/JsonToSwift para fazer exatamente isso.
Você fornece um objeto JSON de amostra com um nome de classe e a ferramenta irá gerar uma classe Swift correspondente, bem como quaisquer classes Swift subsidiárias necessárias, para representar a estrutura implícita pelo JSON de amostra. Também estão incluídos métodos de classe usados para preencher objetos Swift, incluindo um que utiliza o método NSJSONSerialization.JSONObjectWithData. Os mapeamentos necessários dos objetos NSArray e NSDictionary são fornecidos.
A partir do código gerado, você só precisa fornecer um objeto NSData contendo JSON que corresponda à amostra fornecida para a ferramenta.
Além da Foundation, não há dependências.
Meu trabalho foi inspirado em http://json2csharp.com/ , que é muito útil para projetos .NET.
Veja como criar um objeto NSData a partir de um arquivo JSON.
fonte
Nota: se você está procurando por isso, também há uma grande chance de você não saber como instalar
swifty
. Siga as instruções aqui .Em seguida, digite este comando:
Isso criará um padrão
Podfile
para o seu projeto. OPodfile
é onde você define as dependências seu projeto depende.Digite este comando para abrir
Podfile
usandoXcode
para edição:Adicione o
Swifty
ao podfilefonte
Todo o viewcontroller que mostra os dados na visão de coleta usando dois métodos de json parsig
fonte
Usando a estrutura ObjectMapper
Antes de você deve preparar o conjunto apropriado: Objetos mapeáveis para analisar
fonte
Swift 3
dados - é o tipo de dados (estrutura) (ou seja, retornado por alguma resposta do servidor)
fonte
Este analisador usa genéricos para converter JSON em tipos Swift, o que reduz o código que você precisa digitar.
https://github.com/evgenyneu/JsonSwiftson
fonte
Abaixo está um exemplo do Swift Playground:
fonte
Swift 4
Crie um Projeto
Projete StoryBoard com um botão e um UITableview
Criar TableViewCell VC
Na ação do botão, insira os códigos a seguir
Lembre-se deste código para buscar matriz de dados em uma API
Isto é para buscar dados de dicionário
fonte
Exemplo de solicitação de API Swift 4
Fazer uso de
JSONDecoder().decode
Veja este vídeo JSON analisando com Swift 4
fonte
Swift 2 iOS 9
fonte