У мене є файл JSON, я хочу проаналізувати та використовувати список об’єктів у поданні таблиці. Чи може хтось поділитися кодом для швидкого аналізу файлу JSON.
У мене є файл JSON, я хочу проаналізувати та використовувати список об’єктів у поданні таблиці. Чи може хтось поділитися кодом для швидкого аналізу файлу JSON.
Відповіді:
Не може бути простіше:
import Foundation
let jsonData: Data = /* get your json data */
let jsonDict = try JSONSerialization.jsonObject(with: jsonData) as? NSDictionary
З огляду на це, я настійно рекомендую використовувати API Codable, представлений у Swift 4.
let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
NSData(contentsOfFile: path)
. Див. Developer.apple.com/library/ios/documentation/Cocoa/Reference/… :
Подання запиту на API
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Підготовка до відповіді
Оголосіть масив, як показано нижче
var data: NSMutableData = NSMutableData()
Отримання відповіді
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()
}
}
Отримавши NSURLConnection
відповідь, ми можемо очікувати, що didReceiveResponse
метод буде викликаний від нашого імені. На цьому етапі ми просто скидаємо наші дані, кажучи self.data = NSMutableData()
, створюючи новий порожній об’єкт даних.
Після встановлення з'єднання ми почнемо отримувати дані методу didReceiveData
. Тут передається аргумент даних, звідки береться вся наша соковита інформація. Нам потрібно триматися за кожен шматок, що надходить, тому ми додаємо його до об’єкта self.data, який ми очистили раніше.
Нарешті, коли з'єднання завершено і всі дані отримані, connectionDidFinishLoading
викликається, і ми готові використовувати дані у нашому додатку. Ура!
Тут connectionDidFinishLoading
метод використовує NSJSONSerialization
клас для перетворення наших необроблених даних у корисні Dictionary
об'єкти шляхом десеріалізації результатів з вашого URL.
Я щойно написав клас під назвою JSON, який робить обробку JSON у Swift настільки ж простою, як об'єкт JSON у ES5.
Перетворіть свій швидкий об'єкт у JSON так:
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()
... або рядок ...
let json = JSON.parse("{\"array\":[...}")
... або URL.
let json = JSON.fromURL("http://api.dan.co.jp/jsonenv")
Tree Traversal
Просто обведіть елементи за допомогою нижнього індексу:
json["object"]["null"].asNull // NSNull()
// ...
json["object"]["string"].asString // "a α\t弾\n𪚲"
json["array"][0].asNull // NSNull()
json["array"][1].asBool // false
// ...
Як і SwiftyJSON, ви не хвилюєтесь, якщо записаний запис не існує.
if let b = json["noexistent"][1234567890]["entry"].asBool {
// ....
} else {
let e = json["noexistent"][1234567890]["entry"].asError
println(e)
}
Якщо ви втомилися від індексів, додайте свою схему так:
//// 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 }
}
І ви йдете:
let myjson = MyJSON(obj)
myjson.object.null
myjson.object.bool
myjson.object.int
myjson.object.double
myjson.object.string
// ...
Сподіваюся, вам сподобається.
З новим xCode 7.3+ важливо додати свій домен до списку винятків ( Як я можу додати NSAppTransportSecurity до мого файлу info.plist? ), Зверніться до цього повідомлення, щоб отримати інструкції, інакше ви отримаєте помилку транспортного органу.
Ось код для перетворення між JSON та NSData в 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;
}
У Swift 4+ настійно рекомендується використовувати Codable
замістьJSONSerialization
.
Це Codable
включає два протоколи: Decodable
і Encodable
. Цей Decodable
протокол дозволяє декодуватиData
у форматі JSON до власної структури / класу, що відповідає цьому протоколу.
Наприклад, уявімо ситуацію, що у нас є така проста Data
(масив з двох об'єктів)
let data = Data("""
[
{"name":"Steve","age":56},
{"name":"iPhone","age":11}
]
""".utf8)
тоді мати наступний struct
і реалізувати протоколDecodable
struct Person: Decodable {
let name: String
let age: Int
}
тепер ви можете розшифрувати ваш Data
масив Person
використання, JSONDecoder
де перший параметр відповідає типу, Decodable
і до цього типу слід Data
декодувати
do {
let people = try JSONDecoder().decode([Person].self, from: data)
} catch { print(error) }
... зауважте, що декодування має бути позначене try
ключовим словом, оскільки, наприклад, ви можете помилитися з іменуванням, і тоді ваша модель не може бути декодована правильно ... тому вам слід помістити її в блок do-try-catch
Випадки, що ключ в JSON відрізняється від назви властивості:
Якщо ключ названий за допомогою snake_case, ви можете встановити декодери, keyDecodingStrategy
на convertFromSnakeCase
які змінюється ключ з property_name
camelCasepropertyName
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let people = try decoder.decode([Person].self, from: data)
Якщо вам потрібно унікальне ім'я, ви можете використовувати ключі кодування всередині struct / class, де ви оголошуєте ім'я ключа
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
}
}
Я також написав невелику бібліотеку, яка спеціалізується на відображенні відповіді json у структуру об'єкта. Я внутрішньо використовую бібліотеку json-swift від David Owens. Можливо, це корисно для когось іншого.
https://github.com/prine/ROJSONParser
Приклад Employees.json
{
"employees": [
{
"firstName": "John",
"lastName": "Doe",
"age": 26
},
{
"firstName": "Anna",
"lastName": "Smith",
"age": 30
},
{
"firstName": "Peter",
"lastName": "Jones",
"age": 45
}]
}
Як наступний крок вам потрібно створити свою модель даних (EmplyoeeContainer та 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]
}()
}
Тоді, щоб насправді зіставити об'єкти з відповіді JSON, вам потрібно лише передати дані в клас EmployeeContainer як параметр у конструкторі. Це автоматично створює вашу модель даних.
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)
Тоді вивід консолі виглядає так:
Firstname: John Lastname: Doe age: 26
Firstname: Anna Lastname: Smith age: 30
Firstname: Peter Lastname: Jones age: 45
Мертво-простий і легкий для читання!
"mrap"
з nicknames
у вигляді рядка з цієї відповіді JSON{
"other": {
"nicknames": ["mrap", "Mikee"]
}
Дані json приймаються NSData
такими, якими вони є, не потрібно попередньо обробляти.
let parser = JSONParser(jsonData)
if let handle = parser.getString("other.nicknames[0]") {
// that's it!
}
Застереження: Я зробив це, і сподіваюся, це допоможе всім. Не соромтеся вдосконалювати це!
Розбір JSON у Swift - відмінна робота для генерації коду. Я створив інструмент на http://www.guideluxe.com/JsonToSwift, щоб зробити саме це.
Ви надаєте зразок об’єкта JSON з іменем класу, і інструмент генерує відповідний клас Swift, а також будь-які необхідні допоміжні класи Swift, щоб представити структуру, передбачену зразком JSON. Також включені методи класу, що використовуються для заповнення об'єктів Swift, включаючи той, що використовує метод NSJSONSerialization.JSONObjectWithData. Надано необхідні зіставлення з об’єктів NSArray та NSDictionary.
Із згенерованого коду потрібно лише надати об’єкт NSData, що містить JSON, який відповідає зразку, наданому інструменту.
Окрім Foundation, ніяких залежностей немає.
Мою роботу надихнув http://json2csharp.com/ , що дуже зручно для .NET-проектів.
Ось як створити об’єкт NSData з файлу JSON.
let fileUrl: NSURL = NSBundle.mainBundle().URLForResource("JsonFile", withExtension: "json")!
let jsonData: NSData = NSData(contentsOfURL: fileUrl)!
Примітка: якщо ви шукаєте це, існує також висока ймовірність, що ви не знаєте, як встановити swifty
. Дотримуйтесь інструкцій тут .
sudo gem install cocoapods
cd ~/Path/To/Folder/Containing/ShowTracker
Далі введіть цю команду:
pod init
Це створить за замовчуванням Podfile
для вашого проекту. Тут Podfile
ви визначаєте залежності, на які покладається ваш проект.
Введіть цю команду, щоб відкрити, Podfile
використовуючи Xcode
для редагування:
open -a Xcode Podfile
Додайте Swifty
файл у підфайл
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!")
}
}
})
Весь контролер подання, який відображає дані у поданні колекції, використовуючи два методи 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)")
} }
Використання фреймворка 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.")
}
Перш ніж вам слід підготувати набір відповідних об'єктів, що відображаються для аналізу
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"]
}}
Стрімкий 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 - це тип даних (структура) (тобто повертається якоюсь відповіддю сервера)
Цей синтаксичний аналізатор використовує загальні засоби для перетворення JSON на типи Swift, що зменшує код, який потрібно ввести.
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()
)
Нижче наведено приклад швидкого майданчика:
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")
}
Стрімкий 4
Створіть проект
Дизайн StoryBoard із кнопкою та зручним переглядом
Створіть TableViewCell VC
У кнопці Дія вставте наступні коди
Запам’ятайте цей код для отримання масиву даних у 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
}
}
Це для отримання даних словника
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
}
}
Використовувати JSONDecoder().decode
Дивіться це відео, аналіз JSON за допомогою 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()
Свіфт 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)
}