J'ai un fichier JSON, je veux analyser et utiliser la liste des objets en vue tableau. Quelqu'un peut-il partager le code pour analyser le fichier JSON en swift.
J'ai un fichier JSON, je veux analyser et utiliser la liste des objets en vue tableau. Quelqu'un peut-il partager le code pour analyser le fichier JSON en swift.
Réponses:
Rien de plus simple:
import Foundation
let jsonData: Data = /* get your json data */
let jsonDict = try JSONSerialization.jsonObject(with: jsonData) as? NSDictionary
Cela étant dit, je recommande fortement d'utiliser les API codables introduites dans Swift 4.
let jsonData = NSData.dataWithContentsOfFile(filepath, options: .DataReadingMappedIfSafe, error: nil)
NSData(contentsOfFile: path)
. Voir developer.apple.com/library/ios/documentation/Cocoa/Reference/… :
Faire la demande d'API
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
Préparer la réponse
Déclarez un tableau comme ci-dessous
var data: NSMutableData = NSMutableData()
Recevoir la réponse
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()
}
}
Lorsque NSURLConnection
nous recevons une réponse, nous pouvons nous attendre à ce que la didReceiveResponse
méthode soit appelée en notre nom. À ce stade, nous réinitialisons simplement nos données en disant self.data = NSMutableData()
, créant un nouvel objet de données vide.
Une fois la connexion établie, nous commencerons à recevoir des données dans la méthode didReceiveData
. L'argument de données passé ici est la provenance de toutes nos informations juteuses. Nous devons nous accrocher à chaque morceau qui entre, donc nous l'ajoutons à l'objet self.data que nous avons effacé plus tôt.
Enfin, lorsque la connexion est établie et que toutes les données ont été reçues, connectionDidFinishLoading
est appelée et nous sommes prêts à utiliser les données dans notre application. Hourra!
La connectionDidFinishLoading
méthode ici utilise la NSJSONSerialization
classe pour convertir nos données brutes en Dictionary
objets utiles en désérialisant les résultats de votre URL.
Je viens d'écrire une classe appelée JSON, ce qui rend la gestion JSON dans Swift aussi simple que l'objet JSON dans ES5.
Transformez votre objet Swift en JSON comme ceci:
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()
... ou chaîne ...
let json = JSON.parse("{\"array\":[...}")
... ou URL.
let json = JSON.fromURL("http://api.dan.co.jp/jsonenv")
Tree Traversal
Traversez simplement les éléments via un indice:
json["object"]["null"].asNull // NSNull()
// ...
json["object"]["string"].asString // "a α\t弾\n𪚲"
json["array"][0].asNull // NSNull()
json["array"][1].asBool // false
// ...
Tout comme SwiftyJSON, vous ne vous inquiétez pas si l'entrée en indice n'existe pas.
if let b = json["noexistent"][1234567890]["entry"].asBool {
// ....
} else {
let e = json["noexistent"][1234567890]["entry"].asError
println(e)
}
Si vous êtes fatigué des indices, ajoutez votre schéma comme ceci:
//// 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 }
}
Et vous allez:
let myjson = MyJSON(obj)
myjson.object.null
myjson.object.bool
myjson.object.int
myjson.object.double
myjson.object.string
// ...
J'espère que vous aimez.
Avec le nouveau xCode 7.3+, il est important d'ajouter votre domaine à la liste d'exceptions ( Comment puis-je ajouter NSAppTransportSecurity à mon fichier info.plist? ), Reportez-vous à cette publication pour obtenir des instructions, sinon vous obtiendrez une erreur d'autorité de transport.
Voici un code pour effectuer les conversions entre JSON et NSData dans 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;
}
Dans Swift 4+, il est fortement recommandé d'utiliser à la Codable
place de JSONSerialization
.
Cela Codable
comprend deux protocoles: Decodable
et Encodable
. Ce Decodable
protocole vous permet de décoder Data
au format JSON en structure / classe personnalisée conforme à ce protocole.
Par exemple imaginez la situation que nous avons ce simple Data
(tableau de deux objets)
let data = Data("""
[
{"name":"Steve","age":56},
{"name":"iPhone","age":11}
]
""".utf8)
Ensuite, suivez struct
et implémentez le protocoleDecodable
struct Person: Decodable {
let name: String
let age: Int
}
maintenant vous pouvez décoder votre Data
dans votre tableau d' Person
utilisation JSONDecoder
où le premier paramètre est de type conforme Decodable
et à ce type doit Data
être décodé
do {
let people = try JSONDecoder().decode([Person].self, from: data)
} catch { print(error) }
... notez que le décodage doit être marqué avec un try
mot-clé car vous pourriez par exemple faire une erreur avec le nom et ensuite votre modèle ne peut pas être décodé correctement ... vous devriez donc le mettre dans le bloc do-try-catch
Les cas dont la clé dans json est différent du nom de la propriété:
Si la clé est nommée à l'aide de snake_case, vous pouvez définir le décodeur keyDecodingStrategy
vers convertFromSnakeCase
lequel change la clé de property_name
à camelCasepropertyName
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let people = try decoder.decode([Person].self, from: data)
Si vous avez besoin d'un nom unique, vous pouvez utiliser des clés de codage à l' intérieur de struct / class où vous déclarez le nom de la clé
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
}
}
J'ai également écrit une petite bibliothèque spécialisée pour le mappage de la réponse json dans une structure d'objet. J'utilise en interne la bibliothèque json-swift de David Owens. Peut-être que c'est utile pour quelqu'un d'autre.
https://github.com/prine/ROJSONParser
Exemple Employees.json
{
"employees": [
{
"firstName": "John",
"lastName": "Doe",
"age": 26
},
{
"firstName": "Anna",
"lastName": "Smith",
"age": 30
},
{
"firstName": "Peter",
"lastName": "Jones",
"age": 45
}]
}
À l'étape suivante, vous devez créer votre modèle de données (EmplyoeeContainer et Employee).
Employé.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]
}()
}
Ensuite, pour mapper réellement les objets de la réponse JSON, il vous suffit de transmettre les données dans la classe EmployeeContainer en tant que paramètre dans le constructeur. Il crée automatiquement votre modèle de données.
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)
La sortie de la console ressemble alors à ce qui suit:
Firstname: John Lastname: Doe age: 26
Firstname: Anna Lastname: Smith age: 30
Firstname: Peter Lastname: Jones age: 45
Mort-simple et facile à lire!
"mrap"
de en nicknames
tant que chaîne de cette réponse JSON{
"other": {
"nicknames": ["mrap", "Mikee"]
}
Il prend vos données json telles quelles NSData
, pas besoin de prétraiter.
let parser = JSONParser(jsonData)
if let handle = parser.getString("other.nicknames[0]") {
// that's it!
}
Avertissement: j'ai fait ceci et j'espère que cela aidera tout le monde. N'hésitez pas à l'améliorer!
L'analyse JSON dans Swift est un excellent travail pour la génération de code. J'ai créé un outil sur http://www.guideluxe.com/JsonToSwift pour faire exactement cela.
Vous fournissez un exemple d'objet JSON avec un nom de classe et l'outil générera une classe Swift correspondante, ainsi que toutes les classes Swift subsidiaires nécessaires, pour représenter la structure impliquée par l'exemple JSON. Sont également incluses les méthodes de classe utilisées pour remplir les objets Swift, y compris celle qui utilise la méthode NSJSONSerialization.JSONObjectWithData. Les mappages nécessaires des objets NSArray et NSDictionary sont fournis.
À partir du code généré, il vous suffit de fournir un objet NSData contenant JSON qui correspond à l'exemple fourni à l'outil.
À part Foundation, il n'y a pas de dépendances.
Mon travail a été inspiré par http://json2csharp.com/ , qui est très pratique pour les projets .NET.
Voici comment créer un objet NSData à partir d'un fichier JSON.
let fileUrl: NSURL = NSBundle.mainBundle().URLForResource("JsonFile", withExtension: "json")!
let jsonData: NSData = NSData(contentsOfURL: fileUrl)!
Remarque: si vous recherchez ceci, il y a aussi de fortes chances que vous ne sachiez pas comment installer swifty
. Suivez les instructions ici .
sudo gem install cocoapods
cd ~/Path/To/Folder/Containing/ShowTracker
Entrez ensuite cette commande:
pod init
Cela créera une valeur Podfile
par défaut pour votre projet. C'est Podfile
là que vous définissez les dépendances sur lesquelles repose votre projet.
Tapez cette commande pour ouvrir en Podfile
utilisant Xcode
pour l'édition:
open -a Xcode Podfile
Ajouter le Swifty
dans le fichier pod
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!")
}
}
})
Le viewcontroller entier qui affiche les données dans la vue de collecte en utilisant deux méthodes de 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)")
} }
Utilisation du framework 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.")
}
Avant de préparer l'ensemble des objets: Mappable appropriés à analyser
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"]
}}
Swift 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 - c'est le type de données (structure) (c'est-à-dire retourné par une réponse du serveur)
Cet analyseur utilise des génériques pour convertir JSON en types Swift, ce qui réduit le code à taper.
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()
)
Voici un exemple de 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")
}
Swift 4
Créer un projet
Design StoryBoard avec un bouton et un UITableview
Créer TableViewCell VC
Dans Action du bouton, insérez les codes suivants
Souvenez-vous de ce code pour récupérer un tableau de données dans une 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
}
}
Ceci est pour la récupération des données du dictionnaire
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
}
}
Se servir de JSONDecoder().decode
Voir cette vidéo Analyse JSON avec 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)
}