Swift Language
पढ़ना और लिखना JSON
खोज…
वाक्य - विन्यास
- NSJSONSerialization.JSONObjectWithData (jsonData, विकल्प: NSJSONReadingOptions) // jsonData से एक ऑब्जेक्ट लौटाता है। यह विधि विफलता पर फेंकता है।
- NSJSONSerialization.dataWithJSONObject (jsonObject, विकल्प: NSJSONWritingOptions) // JSON ऑब्जेक्ट से NSData लौटाता है। NSJSONWritingOptions.PrettyPrinted में ऐसे आउटपुट के विकल्प में पास करें जो अधिक पठनीय हो।
JSON Serialization, Encoding और Decoding के साथ Apple Foundation और Swift Standard Library
JSONSerialization क्लास को Apple के फाउंडेशन फ्रेमवर्क में बनाया गया है।
JSON पढ़ें
JSONObjectWithData
फ़ंक्शन NSData
लेता है, और AnyObject
लौटाता है। आप के as?
उपयोग कर सकते हैं as?
परिणाम को अपने अपेक्षित प्रकार में बदलने के लिए।
do {
guard let jsonData = "[\"Hello\", \"JSON\"]".dataUsingEncoding(NSUTF8StringEncoding) else {
fatalError("couldn't encode string as UTF-8")
}
// Convert JSON from NSData to AnyObject
let jsonObject = try NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
// Try to convert AnyObject to array of strings
if let stringArray = jsonObject as? [String] {
print("Got array of strings: \(stringArray.joinWithSeparator(", "))")
}
} catch {
print("error reading JSON: \(error)")
}
आप options: .AllowFragments
पास कर सकते हैं options: .AllowFragments
बजाय options: .AllowFragments
options: []
JSON को पढ़ने की अनुमति देने के लिए जब शीर्ष-स्तरीय ऑब्जेक्ट एक सरणी या शब्दकोश नहीं है।
JSON लिखें
dataWithJSONObject
कॉल dataWithJSONObject
एक JSON- संगत ऑब्जेक्ट (नेस्टेड सरणियों या स्ट्रिंग्स, नंबरों, और NSNull
) के साथ कच्चे NSData
को UTF-8 के रूप में एन्कोड किया गया है।
do {
// Convert object to JSON as NSData
let jsonData = try NSJSONSerialization.dataWithJSONObject(jsonObject, options: [])
print("JSON data: \(jsonData)")
// Convert NSData to String
let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding)!
print("JSON string: \(jsonString)")
} catch {
print("error writing JSON: \(error)")
}
आप options: .PrettyPrinted
पास कर सकते हैं options: .PrettyPrinted
बजाय options: .PrettyPrinted
options: []
सुंदर-मुद्रण के लिए।
स्विफ्ट 3 में समान व्यवहार लेकिन एक अलग वाक्यविन्यास के साथ।
do {
guard let jsonData = "[\"Hello\", \"JSON\"]".data(using: String.Encoding.utf8) else {
fatalError("couldn't encode string as UTF-8")
}
// Convert JSON from NSData to AnyObject
let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
// Try to convert AnyObject to array of strings
if let stringArray = jsonObject as? [String] {
print("Got array of strings: \(stringArray.joined(separator: ", "))")
}
} catch {
print("error reading JSON: \(error)")
}
do {
// Convert object to JSON as NSData
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
print("JSON data: \(jsonData)")
// Convert NSData to String
let jsonString = String(data: jsonData, encoding: .utf8)!
print("JSON string: \(jsonString)")
} catch {
print("error writing JSON: \(error)")
}
नोट: निम्नलिखित वर्तमान में केवल स्विफ्ट 4.0 और बाद में उपलब्ध है।
स्विफ्ट 4.0 के रूप में, स्विफ्ट मानक पुस्तकालय में डेटा एन्कोडिंग और डिकोडिंग के लिए मानकीकृत दृष्टिकोण को परिभाषित करने के लिए प्रोटोकॉल Encodable
और Decodable
शामिल हैं। इन प्रोटोकॉलों को अपनाने से Encoder
और Decoder
प्रोटोकॉल के कार्यान्वयन आपके डेटा को ले लेंगे और इसे JSON जैसे बाहरी प्रतिनिधित्व से एन्कोड या डिकोड कर सकते हैं। Codable
प्रोटोकॉल के Encodable
और Decodable
प्रोटोकॉल दोनों को जोड़ती है। यह अब आपके प्रोग्राम में JSON को संभालने के लिए अनुशंसित साधन है।
सांकेतिक शब्दों में बदलना और डिकोड करना
एक प्रकार का कोडेबल बनाने का सबसे आसान तरीका है कि इसके गुणों को उन प्रकारों के रूप में घोषित किया जाए जो पहले से ही Codable
। इन प्रकारों में मानक पुस्तकालय प्रकार जैसे String
, Int
, और Double
; और फ़ाउंडेशन प्रकार जैसे Date
, Data
और URL
। यदि किसी प्रकार के गुण Codable
होते हैं, तो टाइप स्वयं ही केवल अनुरूपता घोषित करके Codable
अनुरूप हो जाएगा।
निम्नलिखित उदाहरण पर विचार करें, जिसमें Book
संरचना Codable
अनुरूप है।
struct Book: Codable {
let title: String
let authors: [String]
let publicationDate: Date
}
ध्यान दें कि
Array
औरDictionary
जैसे मानक संग्रहCodable
अनुरूप होते हैं यदि उनमेंCodable
प्रकार होते हैं।
Codable
को अपनाने से, Book
संरचना को अब JSON से Apple फाउंडेशन कक्षाओं JSONEncoder
और JSONDecoder
का उपयोग करके इनकोडिंग और डीकोड किया जा सकता है, भले ही Book
खुद को विशेष रूप से JSON को संभालने के लिए कोई कोड न हो। कस्टम Encoder
और Decoder
क्रमशः Encoder
और Decoder
प्रोटोकॉल के अनुरूप लिख सकते हैं।
JSON डेटा को एन्कोड करें
// Create an instance of Book called book
let encoder = JSONEncoder()
let data = try! encoder.encode(book) // Do not use try! in production code
print(data)
encoder.outputFormatting = .prettyPrinted
सेट करें। आसान पढ़ने के लिएencoder.outputFormatting = .prettyPrinted
। JSON डेटा से ## डिकोड
JSON डेटा से डीकोड
// Retrieve JSON string from some source
let jsonData = jsonString.data(encoding: .utf8)!
let decoder = JSONDecoder()
let book = try! decoder.decode(Book.self, for: jsonData) // Do not use try! in production code
print(book)
उपरोक्त उदाहरण में,
Book.self
को उस प्रकार के डिकोडर को सूचित करता है, जिस पर JSON को डिकोड किया जाना चाहिए।
एन्कोडिंग या डिकोडिंग विशेष रूप से
कभी-कभी आपको एन्कोडेबल और डिकोडेबल दोनों होने के लिए डेटा की आवश्यकता नहीं हो सकती है, जैसे कि जब आपको केवल JSON डेटा को API से पढ़ने की आवश्यकता होती है, या यदि आपका प्रोग्राम केवल JSON डेटा को API में सबमिट करता है।
यदि आप केवल JSON डेटा लिखने का इरादा रखते हैं, तो अपने प्रकार को Encodable
अनुरूप Encodable
।
struct Book: Encodable {
let title: String
let authors: [String]
let publicationDate: Date
}
यदि आप केवल JSON डेटा पढ़ने का इरादा रखते हैं, तो अपने प्रकार को Decodable
अनुरूप Decodable
।
struct Book: Decodable {
let title: String
let authors: [String]
let publicationDate: Date
}
कस्टम कुंजी नामों का उपयोग करना
एपीआई अक्सर स्विफ्ट-मानक ऊंट मामले के अलावा अन्य नामकरण सम्मेलनों का उपयोग करते हैं, जैसे कि सांप का मामला। जब JSON को डिकोड करने की बात आती है, तो यह एक मुद्दा बन सकता है, क्योंकि डिफ़ॉल्ट रूप से JSON कुंजियाँ आपके प्रकार के संपत्ति नामों के साथ बिल्कुल संरेखित होनी चाहिए। इन परिदृश्यों को संभालने के लिए आप CodingKey
प्रोटोकॉल का उपयोग करके अपने प्रकार के लिए कस्टम कुंजी बना सकते हैं।
struct Book: Codable {
// ...
enum CodingKeys: String, CodingKey {
case title
case authors
case publicationDate = "publication_date"
}
}
CodingKeys
प्रकार जो अपनाने के लिए स्वचालित रूप से उत्पन्न कर रहे हैं Codable
प्रोटोकॉल है, लेकिन हम कर रहे हैं ऊपर के उदाहरण में हमारे अपने कार्यान्वयन बनाने के द्वारा हमारे विकोडक स्थानीय ऊंट मामले से मिलान करने के लिए अनुमति देते हैं publicationDate
साँप मामले से publication_date
के रूप में यह एपीआई द्वारा दिया गया है।
SwiftyJSON
स्विफ्टजसन एक स्विफ्ट फ्रेमवर्क है जिसे सामान्य JSON सीरियललाइज़ेशन में वैकल्पिक चैनिंग की आवश्यकता को दूर करने के लिए बनाया गया है।
आप इसे यहाँ डाउनलोड कर सकते हैं: https://github.com/SwiftyJSON/SwiftyJSON
SwiftyJSON के बिना, JSON ऑब्जेक्ट में पहली पुस्तक का नाम खोजने के लिए आपका कोड इस तरह दिखेगा:
if let jsonObject = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [[String: AnyObject]],
let bookName = (jsonObject[0]["book"] as? [String: AnyObject])?["name"] as? String {
//We can now use the book name
}
SwiftyJSON में, यह बेहद सरल है:
let json = JSON(data: data)
if let bookName = json[0]["book"]["name"].string {
//We can now use the book name
}
यह हर क्षेत्र की जांच करने की आवश्यकता को हटा देता है, क्योंकि यह शून्य हो जाएगा यदि उनमें से कोई भी अमान्य है।
SwiftyJSON का उपयोग करने के लिए, Git रिपॉजिटरी से सही संस्करण डाउनलोड करें - Swift 3. के लिए एक शाखा है। बस अपनी परियोजना में "SwiftyJSON.swift" खींचें और अपनी कक्षा में आयात करें:
import SwiftyJSON
आप निम्नलिखित दो इनिशियलाइज़र का उपयोग करके अपनी JSON ऑब्जेक्ट बना सकते हैं:
let jsonObject = JSON(data: dataObject)
या
let jsonObject = JSON(jsonObject) //This could be a string in a JSON format for example
अपने डेटा तक पहुंचने के लिए, सदस्यता का उपयोग करें:
let firstObjectInAnArray = jsonObject[0]
let nameOfFirstObject = jsonObject[0]["name"]
आप एक निश्चित डेटा प्रकार के लिए अपने मूल्य को पार्स कर सकते हैं, जो एक वैकल्पिक मूल्य लौटाएगा:
let nameOfFirstObject = jsonObject[0]["name"].string //This will return the name as a string
let nameOfFirstObject = jsonObject[0]["name"].double //This will return null
आप अपने रास्तों को एक त्वरित ऐरे में भी संकलित कर सकते हैं:
let convolutedPath = jsonObject[0]["name"][2]["lastName"]["firstLetter"].string
के समान है:
let convolutedPath = jsonObject[0, "name", 2, "lastName", "firstLetter"].string
SwiftyJSON में भी अपनी त्रुटियों को मुद्रित करने के लिए कार्यक्षमता है:
if let name = json[1337].string {
//You can use the value - it is valid
} else {
print(json[1337].error) // "Array[1337] is out of bounds" - You cant use the value
}
यदि आपको अपनी JSON ऑब्जेक्ट पर लिखने की आवश्यकता है, तो आप फिर से सदस्यता का उपयोग कर सकते हैं:
var originalJSON:JSON = ["name": "Jack", "age": 18]
originalJSON["age"] = 25 //This changes the age to 25
originalJSON["surname"] = "Smith" //This creates a new field called "surname" and adds the value to it
क्या आपको JSON के लिए मूल स्ट्रिंग की आवश्यकता है, उदाहरण के लिए यदि आपको इसे किसी फ़ाइल में लिखने की आवश्यकता है, तो आप कच्चा मान प्राप्त कर सकते हैं:
if let string = json.rawString() { //This is a String object
//Write the string to a file if you like
}
if let data = json.rawData() { //This is an NSData object
//Send the data to your server if you like
}
फ्रेडी
फ्रेडी बिग नर्ड रेंच द्वारा बनाए गए एक JSON पार्सिंग लाइब्रेरी है। इसके तीन प्रमुख लाभ हैं:
टाइप सेफ्टी: JSON को एक तरह से भेजने और प्राप्त करने में आपकी मदद करता है जो रनटाइम क्रैश को रोकता है।
मुहावरेदार: जटिल प्रलेखन या जादुई कस्टम ऑपरेटरों के बिना स्विफ्ट की जेनेरिक, एनुमरेशंस और कार्यात्मक सुविधाओं का लाभ उठाता है।
त्रुटि हैंडलिंग: आमतौर पर होने वाली JSON त्रुटियों के लिए सूचनात्मक त्रुटि जानकारी प्रदान करता है।
उदाहरण JSON डेटा
आइए इन उदाहरणों के साथ उपयोग के लिए कुछ उदाहरण JSON डेटा को परिभाषित करते हैं।
{ "success": true, "people": [ { "name": "Matt Mathias", "age": 32, "spouse": true }, { "name": "Sergeant Pepper", "age": 25, "spouse": false } ], "jobs": [ "teacher", "judge" ], "states": { "Georgia": [ 30301, 30302, 30303 ], "Wisconsin": [ 53000, 53001 ] } }
let jsonString = "{\"success\": true, \"people\": [{\"name\": \"Matt Mathias\",\"age\": 32,\"spouse\": true},{\"name\": \"Sergeant Pepper\",\"age\": 25,\"spouse\": false}],\"jobs\": [\"teacher\",\"judge\"],\"states\": {\"Georgia\": [30301,30302,30303],\"Wisconsin\": [53000,53001]}}" let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)!
कच्चे डेटा का वर्णन करना
डेटा को डिसेर्बलाइज़ करने के लिए, हम एक JSON
ऑब्जेक्ट को इनिशियलाइज़ करते हैं फिर किसी विशेष कुंजी को एक्सेस करते हैं।
do { let json = try JSON(data: jsonData) let success = try json.bool("success") } catch { // do something with the error }
हम यहां try
हैं क्योंकि कुंजी "success"
लिए json
तक पहुंचना विफल हो सकता है - यह मौजूद नहीं हो सकता है, या मूल्य एक बूलियन नहीं हो सकता है।
हम JSON संरचना में निहित तत्वों तक पहुंचने के लिए एक पथ भी निर्दिष्ट कर सकते हैं। मार्ग कुंजियों और सूचकांकों की एक अल्पविराम से अलग की गई सूची है जो ब्याज के मूल्य के लिए मार्ग का वर्णन करता है।
do { let json = try JSON(data: jsonData) let georgiaZipCodes = try json.array("states", "Georgia") let firstPersonName = try json.string("people", 0, "name") } catch { // do something with the error }
प्रत्यक्ष रूप से मॉडल का वर्णन करना
JSON को सीधे मॉडल वर्ग पर रखा जा सकता है जो JSONDecodable
प्रोटोकॉल को लागू करता है।
public struct Person { public let name: String public let age: Int public let spouse: Bool } extension Person: JSONDecodable { public init(json: JSON) throws { name = try json.string("name") age = try json.int("age") spouse = try json.bool("spouse") } } do { let json = try JSON(data: jsonData) let people = try json.arrayOf("people", type: Person.self) } catch { // do something with the error }
कच्चे डेटा को सीरियल करना
किसी भी JSON
मूल्य को सीधे NSData
क्रमबद्ध किया जा सकता है।
let success = JSON.Bool(false) let data: NSData = try success.serialize()
मॉडल को सीधे सीरियलाइज़ करना
कोई भी मॉडल वर्ग जो JSONEncodable
प्रोटोकॉल को लागू करता है, JSONEncodable
सीधे NSData
क्रमबद्ध किया जा सकता है।
extension Person: JSONEncodable { public func toJSON() -> JSON { return .Dictionary([ "name": .String(name), "age": .Int(age), "spouse": .Bool(spouse) ]) } } let newPerson = Person(name: "Glenn", age: 23, spouse: true) let data: NSData = try newPerson.toJSON().serialize()
तीर
एरो स्विफ्ट में एक खूबसूरत JSON पार्सिंग लाइब्रेरी है।
यह JSON को पार्स करने और <--
ऑपरेटर की मदद से इसे कस्टम मॉडल कक्षाओं में मैप करने की अनुमति देता है:
identifier <-- json["id"]
name <-- json["name"]
stats <-- json["stats"]
उदाहरण:
स्विफ्ट मॉडल
struct Profile {
var identifier = 0
var name = ""
var link: NSURL?
var weekday: WeekDay = .Monday
var stats = Stats()
var phoneNumbers = [PhoneNumber]()
}
JSON फ़ाइल
{
"id": 15678,
"name": "John Doe",
"link": "https://apple.com/steve",
"weekdayInt" : 3,
"stats": {
"numberOfFriends": 163,
"numberOfFans": 10987
},
"phoneNumbers": [{
"label": "house",
"number": "9809876545"
}, {
"label": "cell",
"number": "0908070656"
}, {
"label": "work",
"number": "0916570656"
}]
}
मानचित्रण
extension Profile: ArrowParsable {
mutating func deserialize(json: JSON) {
identifier <-- json["id"]
link <-- json["link"]
name <-- json["name"]
weekday <-- json["weekdayInt"]
stats <- json["stats"]
phoneNumbers <-- json["phoneNumbers"]
}
}
प्रयोग
let profile = Profile()
profile.deserialize(json)
स्थापना:
कार्थेज
github "s4cha/Arrow"
CocoaPods
pod 'Arrow'
use_frameworks!
मैन्युअल
बस अपने एक्सकोड प्रोजेक्ट में Arrow.swift को कॉपी और पेस्ट करें
https://github.com/s4cha/Arrow
ए फ्रेमवर्क के रूप में
GitHub रिपॉजिटरी से एरो डाउनलोड करें और उदाहरण परियोजना पर फ्रेमवर्क लक्ष्य बनाएं । फिर इस ढांचे के खिलाफ लिंक।
सरल JSON कस्टम ऑब्जेक्ट्स में पार्स करना
भले ही थर्ड-पार्टी लाइब्रेरी अच्छी हो, JSON को पार्स करने का एक सरल तरीका प्रोटोकॉल द्वारा प्रदान किया गया है आप कल्पना कर सकते हैं कि आपको एक वस्तु Todo
मिल गई है
struct Todo {
let comment: String
}
जब भी आप JSON प्राप्त करते हैं, तो आप सादे NSData
को हैंडल कर सकते हैं जैसा कि NSJSONSerialization
ऑब्जेक्ट का उपयोग करके दूसरे उदाहरण में दिखाया गया है।
उसके बाद, एक साधारण प्रोटोकॉल JSONDecodable
का उपयोग JSONDecodable
typealias JSONDictionary = [String:AnyObject]
protocol JSONDecodable {
associatedtype Element
static func from(json json: JSONDictionary) -> Element?
}
और JSONDecodable
अनुरूप अपनी Todo
संरचना JSONDecodable
extension Todo: JSONDecodable {
static func from(json json: JSONDictionary) -> Todo? {
guard let comment = json["comment"] as? String else { return nil }
return Todo(comment: comment)
}
}
आप इसे इस json कोड के साथ आज़मा सकते हैं:
{
"todos": [
{
"comment" : "The todo comment"
}
]
}
जब आप इसे एपीआई से प्राप्त करते हैं, तो आप इसे AnyObject
उदाहरण में दिखाए गए पिछले उदाहरणों के रूप में AnyObject
। उसके बाद, आप जाँच सकते हैं कि क्या उदाहरण एक JSONDictionary
उदाहरण है
guard let jsonDictionary = dictionary as? JSONDictionary else { return }
इस मामले के लिए जाँच करने के लिए दूसरी बात, क्योंकि आपके पास JSON में Todo
की एक सरणी है, todos
शब्दकोश है
guard let todosDictionary = jsonDictionary["todos"] as? [JSONDictionary] else { return }
अब जब आपको शब्दकोशों का सरणी मिल गया है, तो आप उनमें से प्रत्येक को Todo
ऑब्जेक्ट में flatMap
का उपयोग करके flatMap
कर flatMap
(यह स्वचालित रूप से सरणी से nil
मान हटा देगा)
let todos: [Todo] = todosDictionary.flatMap { Todo.from(json: $0) }
JSON पार्सिंग स्विफ्ट 3
यहाँ JSON फ़ाइल है जिसका उपयोग हम animals.json
नाम से करेंगे। animals.json
{
"Sea Animals": [
{
"name": "Fish",
"question": "How many species of fish are there?" },
{
"name": "Sharks",
"question": "How long do sharks live?"
},
{
"name": "Squid",
"question": "Do squids have brains?"
},
{
"name": "Octopus",
"question": "How big do octopus get?"
},
{
"name": "Star Fish",
"question": "How long do star fish live?"
}
],
"mammals": [
{
"name": "Dog",
"question": "How long do dogs live?"
},
{
"name": "Elephant",
"question": "How much do baby elephants weigh?"
},
{
"name": "Cats",
"question": "Do cats really have 9 lives?"
},
{
"name": "Tigers",
"question": "Where do tigers live?"
},
{
"name": "Pandas",
"question": "WHat do pandas eat?"
} ] }
अपनी JSON फ़ाइल को अपनी परियोजना में आयात करें
आप अपनी JSON फाइल को प्रिंट करने के लिए यह सरल कार्य कर सकते हैं
func jsonParsingMethod() {
//get the file
let filePath = Bundle.main.path(forResource: "animals", ofType: "json")
let content = try! String(contentsOfFile: filePath!)
let data: Data = content.data(using: String.Encoding.utf8)!
let json: NSDictionary = try! JSONSerialization.jsonObject(with: data as Data, options:.mutableContainers) as! NSDictionary
//Call which part of the file you'd like to pare
if let results = json["mammals"] as? [[String: AnyObject]] {
for res in results {
//this will print out the names of the mammals from out file.
if let rates = res["name"] as? String {
print(rates)
}
}
}
}
यदि आप इसे किसी तालिका दृश्य में रखना चाहते हैं, तो मैं पहले एक NSObject के साथ एक शब्दकोश बनाऊंगा।
ParsingObject
नामक एक नई स्विफ्ट फ़ाइल बनाएँ और अपने स्ट्रिंग चर बनाएँ।
सुनिश्चित करें कि चर नाम JSON फ़ाइल के समान है
। उदाहरण के लिए, हमारी परियोजना में हमारा name
और question
तो हमारी नई स्विफ्ट फ़ाइल में, हम उपयोग करेंगे
var name: String?
var question: String?
NSObject को आरम्भ करें हमने अपने ViewController.swift var array = ParsingObject में वापस बनाया फिर हम उसी विधि का प्रदर्शन करेंगे जो हमने पहले मामूली संशोधन के साथ किया था।
func jsonParsingMethod() {
//get the file
let filePath = Bundle.main.path(forResource: "animals", ofType: "json")
let content = try! String(contentsOfFile: filePath!)
let data: Data = content.data(using: String.Encoding.utf8)!
let json: NSDictionary = try! JSONSerialization.jsonObject(with: data as Data, options:.mutableContainers) as! NSDictionary
//This time let's get Sea Animals
let results = json["Sea Animals"] as? [[String: AnyObject]]
//Get all the stuff using a for-loop
for i in 0 ..< results!.count {
//get the value
let dict = results?[i]
let resultsArray = ParsingObject()
//append the value to our NSObject file
resultsArray.setValuesForKeys(dict!)
array.append(resultsArray)
}
}
फिर हम ऐसा करके अपने टेबलव्यू में दिखाते हैं,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
//This is where our values are stored
let object = array[indexPath.row]
cell.textLabel?.text = object.name
cell.detailTextLabel?.text = object.question
return cell
}