Saya memiliki file JSON, ingin mengurai dan menggunakan daftar objek dalam tampilan tabel. Adakah yang bisa membagikan kode untuk mengurai file JSON dengan cepat.
Saya memiliki file JSON, ingin mengurai dan menggunakan daftar objek dalam tampilan tabel. Adakah yang bisa membagikan kode untuk mengurai file JSON dengan cepat.
Jawaban:
Tidak bisa lebih sederhana:
import Foundation
let jsonData: Data = /* get your json data */
let jsonDict = try JSONSerialization.jsonObject(with: jsonData) as? NSDictionary
Karena itu, saya sangat menyarankan menggunakan Codable API yang diperkenalkan di Swift 4.
let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
NSData(contentsOfFile: path). Lihat developer.apple.com/library/ios/documentation/Cocoa/Reference/… :
Membuat Permintaan API
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Mempersiapkan respons
Deklarasikan sebuah array seperti di bawah ini
var data: NSMutableData = NSMutableData()
Menerima tanggapan
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()
}
}
Saat NSURLConnectionmenerima tanggapan, kita dapat mengharapkan didReceiveResponsemetode tersebut dipanggil atas nama kita. Pada titik ini kami hanya mengatur ulang data kami dengan mengatakan self.data = NSMutableData(), membuat objek data kosong baru.
Setelah koneksi dibuat, kami akan mulai menerima data dalam metode tersebut didReceiveData. Argumen data yang disampaikan di sini adalah dari mana semua informasi menarik kami berasal. Kita perlu mempertahankan setiap bagian yang masuk, jadi kita menambahkannya ke objek self.data yang kita bersihkan sebelumnya.
Akhirnya, ketika koneksi selesai dan semua data telah diterima, connectionDidFinishLoadingdipanggil dan kami siap menggunakan data di aplikasi kami. Hore!
The connectionDidFinishLoadingMetode sini menggunakan NSJSONSerializationkelas untuk mengkonversi data mentah kami ke berguna Dictionaryobjek dengan deserializing hasil dari Url Anda.
Saya baru saja menulis kelas yang disebut JSON, yang membuat penanganan JSON di Swift semudah objek JSON di ES5.
Ubah objek swift Anda ke JSON seperti ini:
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()
... atau string ...
let json = JSON.parse("{\"array\":[...}")
... atau URL.
let json = JSON.fromURL("http://api.dan.co.jp/jsonenv")
Tree Traversal
Hanya melintasi elemen melalui subskrip:
json["object"]["null"].asNull // NSNull()
// ...
json["object"]["string"].asString // "a α\t弾\n𪚲"
json["array"][0].asNull // NSNull()
json["array"][1].asBool // false
// ...
Sama seperti SwiftyJSON Anda tidak perlu khawatir jika entri yang dilanggan tidak ada.
if let b = json["noexistent"][1234567890]["entry"].asBool {
// ....
} else {
let e = json["noexistent"][1234567890]["entry"].asError
println(e)
}
Jika Anda bosan dengan langganan, tambahkan skema Anda seperti ini:
//// 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 }
}
Dan Anda pergi:
let myjson = MyJSON(obj)
myjson.object.null
myjson.object.bool
myjson.object.int
myjson.object.double
myjson.object.string
// ...
Harap Anda menyukainya.
Dengan xCode 7.3+ yang baru, penting untuk menambahkan domain Anda ke daftar pengecualian ( Bagaimana cara menambahkan NSAppTransportSecurity ke file info.plist saya? ), Lihat posting ini untuk mendapatkan petunjuk, jika tidak, Anda akan mendapatkan kesalahan otoritas transportasi.
Berikut adalah kode untuk membuat konversi antara JSON dan NSData di 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;
}
Di Swift 4+ sangat disarankan untuk digunakan Codablesebagai pengganti JSONSerialization.
Ini Codablemencakup dua protokol: Decodabledan Encodable. DecodableProtokol ini memungkinkan Anda mendekode Datadalam format JSON ke struct / class khusus yang sesuai dengan protokol ini.
Misalnya bayangkan situasi yang kita miliki ini sederhana Data(array dua objek)
let data = Data("""
[
{"name":"Steve","age":56},
{"name":"iPhone","age":11}
]
""".utf8)
kemudian mengikuti structdan mengimplementasikan protokolDecodable
struct Person: Decodable {
let name: String
let age: Int
}
sekarang Anda dapat memecahkan kode Anda Datake array Anda Personmenggunakan di JSONDecodermana parameter pertama adalah tipe yang sesuai Decodabledan untuk jenis ini harus Dataditerjemahkan
do {
let people = try JSONDecoder().decode([Person].self, from: data)
} catch { print(error) }
... perhatikan bahwa decoding harus ditandai dengan trykata kunci karena misalnya Anda dapat membuat kesalahan dengan penamaan dan kemudian model Anda tidak dapat didekode dengan benar ... jadi Anda harus memasukkannya ke dalam blok do-try-catch
Kasus yang kunci di json berbeda dari nama properti:
Jika kunci dalam nama menggunakan snake_case, Anda dapat mengatur decoder ini keyDecodingStrategyuntuk convertFromSnakeCaseyang berubah kunci dari property_nameke CamelCasepropertyName
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let people = try decoder.decode([Person].self, from: data)
Jika Anda membutuhkan nama unik, Anda dapat menggunakan kunci pengkodean di dalam struct / class tempat Anda mendeklarasikan nama kunci
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
}
}
Saya juga menulis perpustakaan kecil yang dikhususkan untuk pemetaan respon json ke dalam struktur objek. Saya secara internal menggunakan perpustakaan json-swift dari David Owens. Mungkin berguna untuk orang lain.
https://github.com/prine/ROJSONParser
Contoh Employees.json
{
"employees": [
{
"firstName": "John",
"lastName": "Doe",
"age": 26
},
{
"firstName": "Anna",
"lastName": "Smith",
"age": 30
},
{
"firstName": "Peter",
"lastName": "Jones",
"age": 45
}]
}
Sebagai langkah selanjutnya Anda harus membuat model data Anda (EmplyoeeContainer dan Karyawan).
Karyawan. Cepat
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]
}()
}
Kemudian untuk benar-benar memetakan objek dari respons JSON, Anda hanya perlu meneruskan data ke kelas EmployeeContainer sebagai param di konstruktor. Itu secara otomatis membuat model data Anda.
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)
Keluaran konsol terlihat seperti berikut:
Firstname: John Lastname: Doe age: 26
Firstname: Anna Lastname: Smith age: 30
Firstname: Peter Lastname: Jones age: 45
Sangat sederhana dan mudah dibaca!
"mrap"dari nicknamessebagai String dari respons JSON ini{
"other": {
"nicknames": ["mrap", "Mikee"]
}
Data json Anda diambil NSDatasebagaimana adanya, tidak perlu diproses sebelumnya.
let parser = JSONParser(jsonData)
if let handle = parser.getString("other.nicknames[0]") {
// that's it!
}
Penafian: Saya membuat ini dan saya harap ini membantu semua orang. Jangan ragu untuk memperbaikinya!
Parsing JSON di Swift adalah pekerjaan yang sangat baik untuk pembuatan kode. Saya telah membuat alat di http://www.guideluxe.com/JsonToSwift untuk melakukan hal itu.
Anda memberikan contoh objek JSON dengan nama kelas dan alat tersebut akan menghasilkan kelas Swift yang sesuai, serta kelas Swift anak perusahaan yang diperlukan, untuk mewakili struktur yang diimplikasikan oleh sampel JSON. Juga disertakan metode kelas yang digunakan untuk mengisi objek Swift, termasuk yang menggunakan metode NSJSONSerialization.JSONObjectWithData. Pemetaan yang diperlukan dari objek NSArray dan NSDictionary disediakan.
Dari kode yang dihasilkan, Anda hanya perlu menyediakan objek NSData yang berisi JSON yang cocok dengan sampel yang diberikan ke alat.
Selain Foundation, tidak ada dependensi.
Pekerjaan saya terinspirasi oleh http://json2csharp.com/ , yang sangat berguna untuk proyek .NET.
Berikut cara membuat objek NSData dari file JSON.
let fileUrl: NSURL = NSBundle.mainBundle().URLForResource("JsonFile", withExtension: "json")!
let jsonData: NSData = NSData(contentsOfURL: fileUrl)!
Catatan: jika Anda mencari ini, kemungkinan besar Anda juga tidak tahu cara menginstalnya swifty. Ikuti instruksinya di sini .
sudo gem install cocoapods
cd ~/Path/To/Folder/Containing/ShowTracker
Selanjutnya masukkan perintah ini:
pod init
Ini akan membuat default Podfileuntuk proyek Anda. ItuPodfile sinilah Anda menentukan ketergantungan proyek Anda.
Ketik perintah ini untuk membuka Podfilemenggunakan Xcodeuntuk pengeditan:
open -a Xcode Podfile
Tambahkan Swiftyke dalam podfile
platform :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!")
}
}
})
Seluruh viewcontroller yang menampilkan data dalam tampilan koleksi menggunakan dua metode 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)")
} }
Menggunakan kerangka 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.")
}
Sebelum Anda harus menyiapkan set yang sesuai: Objek yang dapat dipetakan untuk diurai
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"]
}}
Cepat 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
}
data - itu Jenis data (Struktur) (yaitu dikembalikan oleh beberapa respons server)
Parser ini menggunakan generik untuk mentransmisikan JSON ke jenis Swift yang mengurangi kode yang perlu Anda ketik.
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()
)
Di bawah ini adalah contoh 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")
}
Cepat 4
Buat Proyek
Desain Papan Cerita Dengan Tombol dan Tampilan UITable
Buat TableViewCell VC
Dalam Tindakan Tombol Masukkan Kode berikut
Ingat Kode Ini untuk Mengambil Array Data dalam 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
}
}
Ini untuk Pengambilan data Kamus
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
}
}
Menggunakan JSONDecoder().decode
Lihat video ini mengurai JSON dengan 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()
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)
}