Mam plik JSON, chcę przeanalizować i użyć listy obiektów w widoku tabeli. Czy każdy może udostępnić kod, aby przeanalizować plik JSON w szybkim tempie.
Na przykładlet jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
Caroline
4
Problem z tym podejściem polega na tym, że otrzymujesz kilka obiektów fundamentowych. Mianowicie NSString, NSNumber, NSArray, NSDictionary lub NSNull. Co stwarza ogromne obciążenie rzutowania, jeśli chcesz poradzić sobie z natywnym językiem Swift wpisanym później w kodzie. Zwłaszcza jeśli masz zagnieżdżone słowniki i tablice. Czy ktoś wie, jak sobie z tym poradzić?
@bubakazouba: Szkoda, że nie mogę odrzucić komentarza. Kilka rzeczy: 1. Caroline dostarczyła już fragment kodu do ładowania danych z pliku (czego chciał OP). 2. Twój kod używa kodowania ASCII, które powoduje utratę wszystkich symboli Unicode, w tym obsługi języków spoza języka angielskiego.
akashivskyy
43
Wykonanie żądania API
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Przygotowanie do odpowiedzi
Zadeklaruj tablicę jak poniżej
var data: NSMutableData = NSMutableData()
Otrzymanie odpowiedzi
1.
funcconnection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
// Received a new request, clear out the data objectself.data = NSMutableData()
}
2.
funcconnection(connection: NSURLConnection!, didReceiveData data: NSData!) {
// Append the received chunk of data to our data objectself.data.appendData(data)
}
3.
funcconnectionDidFinishLoading(connection: NSURLConnection!) {
// Request complete, self.data should now hold the resulting info// Convert the retrieved data in to an object through JSON deserializationvar 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()
}
}
Po NSURLConnectionotrzymaniu odpowiedzi możemy spodziewać didReceiveResponsesię wywołania metody w naszym imieniu. W tym momencie po prostu resetujemy nasze dane, mówiąc self.data = NSMutableData(), tworząc nowy pusty obiekt danych.
Po nawiązaniu połączenia zaczniemy odbierać dane w metodzie didReceiveData. Argument danych, który jest tutaj przekazywany, jest źródłem wszystkich naszych soczystych informacji. Musimy trzymać się każdego przychodzącego fragmentu, więc dołączamy go do obiektu self.data, który wyczyściliśmy wcześniej.
Na koniec, gdy połączenie jest zakończone i wszystkie dane zostały odebrane, connectionDidFinishLoadingzostaje wywołany i jesteśmy gotowi do użycia danych w naszej aplikacji. Brawo!
Ta connectionDidFinishLoadingmetoda używa NSJSONSerializationklasy do konwersji naszych surowych danych na przydatne Dictionaryobiekty poprzez deserializację wyników z adresu URL.
Pytanie dotyczące repozytorium Github: jak właściwie wykonujesz plik main.swift? Mam problem z wykonaniem go z poziomu placu zabaw, ponieważ nie możesz odwoływać się do klas zdefiniowanych we własnym projekcie z placu zabaw (?!) Dzięki!
Janos
W najnowszym repozytorium zaznaczyłem metody jako publiczne. To stanowi minimalne wymaganie dla Beta4, więc nie zapomnij zaktualizować Xcode przed wypróbowaniem
dankogai
Ok, dzięki, naprawdę szukałem, jak dokładnie wykonać przykładowy kod. Próbowałem playgroung, ale nie zadziałało, ponieważ nie mogłem odwołać się do klasy JSON (jest to znany problem, którego nie możesz odwołać się do klas w swoim projekcie)
Janos
Nie mogę sprawić, żeby to zadziałało :( Tym razem nie próbuję go używać na placu zabaw, dodałem twój json.swift do mojego projektu iw innej klasie próbuję go użyć. Nie działa. Wypróbowałem najprostszy JSON: {"id": "Janos"}, utworzyłem obiekt JSON, nazwałam jego metodę toString, poprawnie wypluwa zawartość pliku, jednak kiedy wywołuję myJson ["id"]. AsString otrzymuję zero. Czego mi brakuje?
Janos
Próbowałem skonstruować obiekt JSON przekazujący String w konstruktorze ... Zmieniłem sposób, w jaki robisz to w przykładzie, teraz działa to super. Pytanie tylko, którego użyć teraz, twojego czy SwiftyJSon :)
Janos
4
Oto kod umożliwiający konwersję między JSON i NSData w Swift 2.0
// Convert from NSData to json objectfuncnsdataToJSON(data: NSData) -> AnyObject? {
do {
returntryNSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
} catchlet myJSONError {
print(myJSONError)
}
returnnil
}
// Convert from JSON to nsdatafuncjsonToNSData(json: AnyObject) -> NSData?{
do {
returntryNSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted)
} catchlet myJSONError {
print(myJSONError)
}
returnnil;
}
W Swift 4+ zdecydowanie zaleca się używanie Codablezamiast JSONSerialization.
Obejmuje Codableto dwa protokoły: Decodablei Encodable. Ten Decodableprotokół umożliwia dekodowanie Dataw formacie JSON do niestandardowej struktury / klasy zgodnej z tym protokołem.
Na przykład wyobraź sobie sytuację, w której mamy to proste Data(tablica dwóch obiektów)
let data = Data("""
[
{"name":"Steve","age":56},
{"name":"iPhone","age":11}
]
""".utf8)
następnie wykonaj następujące czynności structi zastosuj protokółDecodable
structPerson: Decodable{
let name: Stringlet age: Int
}
teraz możesz zdekodować swoją Datatablicę Personużywając JSONDecodergdzie pierwszy parametr jest zgodny z typem Decodablei do tego typu powinien Databyć dekodowany
do {
let people = tryJSONDecoder().decode([Person].self, from: data)
} catch { print(error) }
... zwróć uwagę, że dekodowanie musi być oznaczone trysłowem kluczowym, ponieważ możesz na przykład popełnić błąd w nazewnictwie i wtedy twój model nie może zostać poprawnie zdekodowany ... więc powinieneś umieścić go w bloku do-try-catch
Przypadki, w których klucz w json różni się od nazwy właściwości:
Jeśli klucz jest nazwany przy użyciu snake_case, możesz ustawić dekoder, keyDecodingStrategydo convertFromSnakeCasektórego zmienia klucz z property_namena camelCasepropertyName
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let people = try decoder.decode([Person].self, from: data)
Jeśli potrzebujesz unikalnej nazwy, możesz użyć kluczy kodowania wewnątrz struktury / klasy, w której deklarujesz nazwę klucza
let data = Data("""
{ "userName":"Codable", "age": 1 }
""".utf8)
structPerson: Decodable{
let name: Stringlet age: IntenumCodingKeys: String, CodingKey{
case name = "userName"case age
}
}
Napisałem również małą bibliotekę, która specjalizuje się w mapowaniu odpowiedzi json na strukturę obiektu. Używam wewnętrznie biblioteki json-swift od Davida Owensa. Może przyda się komuś innemu.
Następnie, aby faktycznie zmapować obiekty z odpowiedzi JSON, wystarczy przekazać dane do klasy EmployeeContainer jako parametr w konstruktorze. Automatycznie tworzy model danych.
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)
Wynik konsoli wygląda wtedy następująco:
Firstname: JohnLastname: Doe age: 26Firstname: AnnaLastname: Smith age: 30Firstname: PeterLastname: Jones age: 45
Wybacz moją ignorancję. Jakie są zalety korzystania z biblioteki w porównaniu z taką jak SwiftyJSON?
Levi Roberts
6
Początkowo zbudowałem to, ponieważ nie podobał mi się pomysł hakowania operatorów / symboli w języku. Zbudowałem go także, aby zapoznać się ze Swiftem. Z ciekawości przeprowadziłem test porównawczy i stwierdziłem, że SwiftyJSON ma wyższą prędkość (~ 2-7 razy szybciej). Zaktualizowałem README repozytorium, aby to przyznać.
Mike Rapadas
Dzięki za odpowiedź.
Levi Roberts
Czy możesz pokazać przykład, jak ładowałbyś tablicę danych z JSON (wiele elementów zasadniczo z pętlą itp.)
Dostarczasz przykładowy obiekt JSON z nazwą klasy, a narzędzie wygeneruje odpowiednią klasę Swift, a także wszelkie potrzebne dodatkowe klasy Swift, aby przedstawić strukturę implikowaną przez przykładowy JSON. Dołączone są również metody klas używane do wypełniania obiektów Swift, w tym metoda wykorzystująca metodę NSJSONSerialization.JSONObjectWithData. Zapewnione są niezbędne mapowania z obiektów NSArray i NSDictionary.
Z wygenerowanego kodu wystarczy dostarczyć obiekt NSData zawierający JSON, który pasuje do przykładu dostarczonego do narzędzia.
Poza Foundation nie ma żadnych zależności.
Moja praca została zainspirowana http://json2csharp.com/ , co jest bardzo przydatne w projektach .NET.
Oto jak utworzyć obiekt NSData z pliku JSON.
let fileUrl: NSURL = NSBundle.mainBundle().URLForResource("JsonFile", withExtension: "json")!
let jsonData: NSData = NSData(contentsOfURL: fileUrl)!
Przepraszam za to, wklejałem bezpośrednio adres URL JSON, działa dobrze, wklejając odpowiedź JSON. Byłoby wspaniale, gdyby adres URL został wklejony bezpośrednio. Ale świetna robota dla tego narzędzia. Dzięki.
ioopl
Stworzone przez ciebie narzędzie jest po prostu niesamowite. Używam tego narzędzia od ostatnich 6 miesięcy. Ale nagle od ostatnich 3 dni Twoja witryna jest nieosiągalna, a przeglądarka odpowiada komunikatem „Ta witryna nie jest dostępna”. Więc jaki jest tego powód?
Odpowiedzi:
Nie może być prostsze:
import Foundation let jsonData: Data = /* get your json data */ let jsonDict = try JSONSerialization.jsonObject(with: jsonData) as? NSDictionary
Biorąc to pod uwagę, zdecydowanie zalecam używanie Codable API wprowadzonych w Swift 4.
źródło
let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
NSData(contentsOfFile: path)
. Zobacz developer.apple.com/library/ios/documentation/Cocoa/Reference/… :Wykonanie żądania API
var request: NSURLRequest = NSURLRequest(URL: url) var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Przygotowanie do odpowiedzi
Zadeklaruj tablicę jak poniżej
var data: NSMutableData = NSMutableData()
Otrzymanie odpowiedzi
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: NSError var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary if jsonResult.count>0 && jsonResult["results"].count>0 { var results: NSArray = jsonResult["results"] as NSArray self.tableData = results self.appsTableView.reloadData() } }
Po
NSURLConnection
otrzymaniu odpowiedzi możemy spodziewaćdidReceiveResponse
się wywołania metody w naszym imieniu. W tym momencie po prostu resetujemy nasze dane, mówiącself.data = NSMutableData()
, tworząc nowy pusty obiekt danych.Po nawiązaniu połączenia zaczniemy odbierać dane w metodzie
didReceiveData
. Argument danych, który jest tutaj przekazywany, jest źródłem wszystkich naszych soczystych informacji. Musimy trzymać się każdego przychodzącego fragmentu, więc dołączamy go do obiektu self.data, który wyczyściliśmy wcześniej.Na koniec, gdy połączenie jest zakończone i wszystkie dane zostały odebrane,
connectionDidFinishLoading
zostaje wywołany i jesteśmy gotowi do użycia danych w naszej aplikacji. Brawo!Ta
connectionDidFinishLoading
metoda używaNSJSONSerialization
klasy do konwersji naszych surowych danych na przydatneDictionary
obiekty poprzez deserializację wyników z adresu URL.źródło
Właśnie napisałem klasę o nazwie JSON, która sprawia, że obsługa JSON w Swift jest tak łatwa jak obiekt JSON w ES5.
Zmień swój szybki obiekt na JSON w ten sposób:
let obj:[String:AnyObject] = [ "array": [JSON.null, false, 0, "",[],[:]], "object":[ "null": JSON.null, "bool": true, "int": 42, "double": 3.141592653589793, "string": "a α\t弾\n𪚲", "array": [], "object": [:] ], "url":"http://blog.livedoor.com/dankogai/" ] let json = JSON(obj) json.toString()
... lub sznurek ...
let json = JSON.parse("{\"array\":[...}")
... lub URL.
let json = JSON.fromURL("http://api.dan.co.jp/jsonenv") Tree Traversal
Po prostu przejdź przez elementy za pomocą indeksu dolnego:
json["object"]["null"].asNull // NSNull() // ... json["object"]["string"].asString // "a α\t弾\n𪚲" json["array"][0].asNull // NSNull() json["array"][1].asBool // false // ...
Podobnie jak SwiftyJSON , nie martwisz się, jeśli wpis z indeksem nie istnieje.
if let b = json["noexistent"][1234567890]["entry"].asBool { // .... } else { let e = json["noexistent"][1234567890]["entry"].asError println(e) }
Jeśli masz dość indeksów dolnych, dodaj swój schemat w następujący sposób:
//// schema by subclassing class MyJSON : JSON { init(_ obj:AnyObject){ super.init(obj) } init(_ json:JSON) { super.init(json) } var null :NSNull? { return self["null"].asNull } var bool :Bool? { return self["bool"].asBool } var int :Int? { return self["int"].asInt } var double:Double? { return self["double"].asDouble } var string:String? { return self["string"].asString } }
I idziesz:
let myjson = MyJSON(obj) myjson.object.null myjson.object.bool myjson.object.int myjson.object.double myjson.object.string // ...
Mam nadzieję że ci się spodoba.
Wraz z nowym xCode 7.3+ ważne jest, aby dodać swoją domenę do listy wyjątków ( Jak mogę dodać NSAppTransportSecurity do mojego pliku info.plist? ), Zapoznaj się z tym wpisem , aby uzyskać instrukcje, w przeciwnym razie otrzymasz błąd organu transportu.
źródło
Oto kod umożliwiający konwersję między JSON i NSData w Swift 2.0
// Convert from NSData to json object func nsdataToJSON(data: NSData) -> AnyObject? { do { return try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) } catch let myJSONError { print(myJSONError) } return nil } // Convert from JSON to nsdata func jsonToNSData(json: AnyObject) -> NSData?{ do { return try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted) } catch let myJSONError { print(myJSONError) } return nil; }
źródło
Kodowane
W Swift 4+ zdecydowanie zaleca się używanie
Codable
zamiastJSONSerialization
.Obejmuje
Codable
to dwa protokoły:Decodable
iEncodable
. TenDecodable
protokół umożliwia dekodowanieData
w formacie JSON do niestandardowej struktury / klasy zgodnej z tym protokołem.Na przykład wyobraź sobie sytuację, w której mamy to proste
Data
(tablica dwóch obiektów)let data = Data(""" [ {"name":"Steve","age":56}, {"name":"iPhone","age":11} ] """.utf8)
następnie wykonaj następujące czynności
struct
i zastosuj protokółDecodable
struct Person: Decodable { let name: String let age: Int }
teraz możesz zdekodować swoją
Data
tablicęPerson
używającJSONDecoder
gdzie pierwszy parametr jest zgodny z typemDecodable
i do tego typu powinienData
być dekodowanydo { let people = try JSONDecoder().decode([Person].self, from: data) } catch { print(error) }
... zwróć uwagę, że dekodowanie musi być oznaczone
try
słowem kluczowym, ponieważ możesz na przykład popełnić błąd w nazewnictwie i wtedy twój model nie może zostać poprawnie zdekodowany ... więc powinieneś umieścić go w bloku do-try-catchPrzypadki, w których klucz w json różni się od nazwy właściwości:
Jeśli klucz jest nazwany przy użyciu snake_case, możesz ustawić dekoder,
keyDecodingStrategy
doconvertFromSnakeCase
którego zmienia klucz zproperty_name
na camelCasepropertyName
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase let people = try decoder.decode([Person].self, from: data)
Jeśli potrzebujesz unikalnej nazwy, możesz użyć kluczy kodowania wewnątrz struktury / klasy, w której deklarujesz nazwę klucza
let data = Data(""" { "userName":"Codable", "age": 1 } """.utf8) struct Person: Decodable { let name: String let age: Int enum CodingKeys: String, CodingKey { case name = "userName" case age } }
źródło
Napisałem również małą bibliotekę, która specjalizuje się w mapowaniu odpowiedzi json na strukturę obiektu. Używam wewnętrznie biblioteki json-swift od Davida Owensa. Może przyda się komuś innemu.
https://github.com/prine/ROJSONParser
Przykład Employees.json
{ "employees": [ { "firstName": "John", "lastName": "Doe", "age": 26 }, { "firstName": "Anna", "lastName": "Smith", "age": 30 }, { "firstName": "Peter", "lastName": "Jones", "age": 45 }] }
W kolejnym kroku musisz stworzyć swój model danych (EmplyoeeContainer i Employee).
Employee.swift
class Employee : ROJSONObject { required init() { super.init(); } required init(jsonData:AnyObject) { super.init(jsonData: jsonData) } var firstname:String { return Value<String>.get(self, key: "firstName") } var lastname:String { return Value<String>.get(self, key: "lastName") } var age:Int { return Value<Int>.get(self, key: "age") } }
EmployeeContainer.swift
class EmployeeContainer : ROJSONObject { required init() { super.init(); } required init(jsonData:AnyObject) { super.init(jsonData: jsonData) } lazy var employees:[Employee] = { return Value<[Employee]>.getArray(self, key: "employees") as [Employee] }() }
Następnie, aby faktycznie zmapować obiekty z odpowiedzi JSON, wystarczy przekazać dane do klasy EmployeeContainer jako parametr w konstruktorze. Automatycznie tworzy model danych.
var baseWebservice:BaseWebservice = BaseWebservice(); var urlToJSON = "http://prine.ch/employees.json" var callbackJSON = {(status:Int, employeeContainer:EmployeeContainer) -> () in for employee in employeeContainer.employees { println("Firstname: \(employee.firstname) Lastname: \(employee.lastname) age: \(employee.age)") } } baseWebservice.get(urlToJSON, callback:callbackJSON)
Wynik konsoli wygląda wtedy następująco:
Firstname: John Lastname: Doe age: 26 Firstname: Anna Lastname: Smith age: 30 Firstname: Peter Lastname: Jones age: 45
źródło
SwiftJSONParse : Analizuj JSON jak badass
Śmiertelnie proste i łatwe do odczytania!
Przykład: pobierz wartość
"mrap"
znicknames
jako String z tej odpowiedzi JSON{ "other": { "nicknames": ["mrap", "Mikee"] }
Zajmuje dane json
NSData
takie, jakie są, nie ma potrzeby wstępnego przetwarzania.let parser = JSONParser(jsonData) if let handle = parser.getString("other.nicknames[0]") { // that's it! }
Zastrzeżenie: zrobiłem to i mam nadzieję, że pomoże to wszystkim. Zapraszam do ulepszania go!
źródło
Parsowanie JSON w Swift to doskonała praca do generowania kodu. Stworzyłem narzędzie pod adresem http://www.guideluxe.com/JsonToSwift, aby to zrobić.
Dostarczasz przykładowy obiekt JSON z nazwą klasy, a narzędzie wygeneruje odpowiednią klasę Swift, a także wszelkie potrzebne dodatkowe klasy Swift, aby przedstawić strukturę implikowaną przez przykładowy JSON. Dołączone są również metody klas używane do wypełniania obiektów Swift, w tym metoda wykorzystująca metodę NSJSONSerialization.JSONObjectWithData. Zapewnione są niezbędne mapowania z obiektów NSArray i NSDictionary.
Z wygenerowanego kodu wystarczy dostarczyć obiekt NSData zawierający JSON, który pasuje do przykładu dostarczonego do narzędzia.
Poza Foundation nie ma żadnych zależności.
Moja praca została zainspirowana http://json2csharp.com/ , co jest bardzo przydatne w projektach .NET.
Oto jak utworzyć obiekt NSData z pliku JSON.
let fileUrl: NSURL = NSBundle.mainBundle().URLForResource("JsonFile", withExtension: "json")! let jsonData: NSData = NSData(contentsOfURL: fileUrl)!
źródło
Uwaga: jeśli tego szukasz, istnieje również duża szansa, że nie wiesz, jak zainstalować
swifty
. Postępuj zgodnie z instrukcjami tutaj .sudo gem install cocoapods cd ~/Path/To/Folder/Containing/ShowTracker
Następnie wprowadź to polecenie:
pod init
Spowoduje to utworzenie domyślnego
Podfile
projektu. To miejsce, wPodfile
którym definiujesz zależności, na których opiera się Twój projekt.Wpisz to polecenie, aby otworzyć
Podfile
za pomocąXcode
do edycji:open -a Xcode Podfile
Dodaj
Swifty
do pliku podfileplatform :ios, '8.0' use_frameworks! target 'MyApp' do pod 'SwiftyJSON', '~> X.X.X' end
var mURL = NSURL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&units=metric") if mURL == nil{ println("You are stupid") return } var request = NSURLRequest(URL: mURL!) NSURLConnection.sendAsynchronousRequest( request, queue: NSOperationQueue.mainQueue(), completionHandler:{ ( response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in if data != nil { var mJSON = JSON(data: data!) if let current_conditions = mJSON["weather"][0]["description"].string { println("Current conditions: " + current_conditions) } else { println("MORON!") } if let current_temperature = mJSON["main"]["temp"].double { println("Temperature: "+ String(format:"%.f", current_temperature) + "°C" } else { println("MORON!") } } })
źródło
Cały kontroler widoku, który wyświetla dane w widoku kolekcji przy użyciu dwóch metod json parsig
@IBOutlet weak var imagecollectionview: UICollectionView! lazy var data = NSMutableData() var dictdata : NSMutableDictionary = NSMutableDictionary() override func viewDidLoad() { super.viewDidLoad() startConnection() startNewConnection() // Do any additional setup after loading the view, typically from a nib. } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return dictdata.count } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CustomcellCollectionViewCell", forIndexPath: indexPath) as! CustomcellCollectionViewCell cell.name.text = dictdata.valueForKey("Data")?.valueForKey("location") as? String let url = NSURL(string: (dictdata.valueForKey("Data")?.valueForKey("avatar_url") as? String)! ) LazyImage.showForImageView(cell.image, url:"URL return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let kWhateverHeightYouWant = 100 return CGSizeMake(self.view.bounds.size.width/2, CGFloat(kWhateverHeightYouWant)) } func startNewConnection() { let url: URL = URL(string: "YOUR URL" as String)! let session = URLSession.shared let request = NSMutableURLRequest(url: url as URL) request.httpMethod = "GET" //set the get or post according to your request // request.cachePolicy = NSURLRequest.CachePolicy.ReloadIgnoringCacheData request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData let task = session.dataTask(with: request as URLRequest) { ( data, response, error) in guard let _:NSData = data as NSData?, let _:URLResponse = response, error == nil else { print("error") return } let jsonString = NSString(data: data!, encoding:String.Encoding.utf8.rawValue) as! String } task.resume() } func startConnection(){ let urlPath: String = "your URL" let url: NSURL = NSURL(string: urlPath)! var request: NSURLRequest = NSURLRequest(URL: url) var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)! connection.start() } func connection(connection: NSURLConnection!, didReceiveData data: NSData!){ self.data.appendData(data) } func buttonAction(sender: UIButton!){ startConnection() } func connectionDidFinishLoading(connection: NSURLConnection!) { do { let JSON = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions(rawValue: 0)) guard let JSONDictionary :NSDictionary = JSON as? NSDictionary else { print("Not a Dictionary") // put in function return } print("JSONDictionary! \(JSONDictionary)") dictdata.setObject(JSONDictionary, forKey: "Data") imagecollectionview.reloadData() } catch let JSONError as NSError { print("\(JSONError)") } }
źródło
Korzystanie z platformy ObjectMapper
if let path = Bundle(for: BPPView.self).path(forResource: jsonFileName, ofType: "json") { do { let data = try Data(contentsOf: URL(fileURLWithPath: path), options: NSData.ReadingOptions.mappedIfSafe) let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) self.levels = Mapper<Level>().mapArray(JSONArray: (json as! [[String : Any]]))! print(levels.count) } catch let error as NSError { print(error.localizedDescription) } } else { print("Invalid filename/path.") }
Wcześniej należy przygotować zestaw odpowiednich: Mapowalnych obiektów do parsowania
import UIKit import ObjectMapper class Level: Mappable { var levelName = "" var levelItems = [LevelItem]() required init?(map: Map) { } // Mappable func mapping(map: Map) { levelName <- map["levelName"] levelItems <- map["levelItems"] }
import UIKit import ObjectMapper class LevelItem: Mappable { var frontBackSide = BPPFrontBack.Undefined var fullImageName = "" var fullImageSelectedName = "" var bodyParts = [BodyPart]() required init?(map: Map) { } // Mappable func mapping(map: Map) { frontBackSide <- map["frontBackSide"] fullImageName <- map["fullImageName"] fullImageSelectedName <- map["fullImageSelectedName"] bodyParts <- map["bodyParts"] }}
źródło
Szybki 3
let parsedResult: [String: AnyObject] do { parsedResult = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:AnyObject] } catch { // Display an error or return or whatever }
dane - to typ danych (struktura) (tj. zwracane przez odpowiedź serwera)
źródło
Ten parser używa typów ogólnych do rzutowania JSON na typy Swift, co ogranicza kod, który musisz wpisać.
https://github.com/evgenyneu/JsonSwiftson
struct Person { let name: String? let age: Int? } let mapper = JsonSwiftson(json: "{ \"name\": \"Peter\", \"age\": 41 }") let person: Person? = Person( name: mapper["name"].map(), age: mapper["age"].map() )
źródło
Poniżej znajduje się przykład Swift Playground:
import UIKit let jsonString = "{\"name\": \"John Doe\", \"phone\":123456}" let data = jsonString.data(using: .utf8) var jsonObject: Any do { jsonObject = try JSONSerialization.jsonObject(with: data!) as Any if let obj = jsonObject as? NSDictionary { print(obj["name"]) } } catch { print("error") }
źródło
Szybki 4
Utwórz projekt
Zaprojektuj StoryBoard za pomocą przycisku i widoku UITableview
Utwórz TableViewCell VC
W akcji przycisku Wstaw następujące kody
Zapamiętaj ten kod, aby pobrać tablicę danych w interfejsie API
import UIKit class ViewController3: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet var tableView: UITableView! var displayDatasssss = [displyDataClass]() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return displayDatasssss.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1") as! TableViewCell1 cell.label1.text = displayDatasssss[indexPath.row].email return cell } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func gettt(_ sender: Any) { let url = "http://jsonplaceholder.typicode.com/users" var request = URLRequest(url: URL(string: url)!) request.httpMethod = "GET" let configuration = URLSessionConfiguration.default let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) let task = session.dataTask(with: request){(data, response,error)in if (error != nil){ print("Error") } else{ do{ // Array of Data let fetchData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! NSArray for eachData in fetchData { let eachdataitem = eachData as! [String : Any] let name = eachdataitem["name"]as! String let username = eachdataitem["username"]as! String let email = eachdataitem["email"]as! String self.displayDatasssss.append(displyDataClass(name: name, username: username,email : email)) } self.tableView.reloadData() } catch{ print("Error 2") } } } task.resume() } } class displyDataClass { var name : String var username : String var email : String init(name : String,username : String,email :String) { self.name = name self.username = username self.email = email } }
Dotyczy to pobierania danych ze słownika
import UIKit class ViewController3: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet var tableView: UITableView! var displayDatasssss = [displyDataClass]() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return displayDatasssss.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1") as! TableViewCell1 cell.label1.text = displayDatasssss[indexPath.row].email return cell } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func gettt(_ sender: Any) { let url = "http://jsonplaceholder.typicode.com/users/1" var request = URLRequest(url: URL(string: url)!) request.httpMethod = "GET" let configuration = URLSessionConfiguration.default let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main) let task = session.dataTask(with: request){(data, response,error)in if (error != nil){ print("Error") } else{ do{ //Dictionary data Fetching let fetchData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String: AnyObject] let name = fetchData["name"]as! String let username = fetchData["username"]as! String let email = fetchData["email"]as! String self.displayDatasssss.append(displyDataClass(name: name, username: username,email : email)) self.tableView.reloadData() } catch{ print("Error 2") } } } task.resume() } } class displyDataClass { var name : String var username : String var email : String init(name : String,username : String,email :String) { self.name = name self.username = username self.email = email } }
źródło
Przykład żądania interfejsu API Swift 4
Zrobić użytek z
JSONDecoder().decode
Zobacz ten film o parsowaniu JSON w Swift 4
struct Post: Codable { let userId: Int let id: Int let title: String let body: String }
URLSession.shared.dataTask(with: URL(string: "https://jsonplaceholder.typicode.com/posts")!) { (data, response, error) in guard let response = response as? HTTPURLResponse else { print("HTTPURLResponse error") return } guard 200 ... 299 ~= response.statusCode else { print("Status Code error \(response.statusCode)") return } guard let data = data else { print("No Data") return } let posts = try! JSONDecoder().decode([Post].self, from: data) print(posts) }.resume()
źródło
Swift 2 iOS 9
let miadata = NSData(contentsOfURL: NSURL(string: "https://myWeb....php")!) do{ let MyData = try NSJSONSerialization.JSONObjectWithData(miadata!, options: NSJSONReadingOptions.MutableContainers) as? NSArray print(".........\(MyData)") } catch let error as NSError{ // error.description print(error.description) }
źródło