সুইফট 3-তে সঠিকভাবে JSON পার্স করা হচ্ছে


123

আমি একটি জেএসওএন প্রতিক্রিয়া আনার চেষ্টা করছি এবং ফলাফলগুলিকে ভেরিয়েবলের মধ্যে সঞ্চয় করি। এক্সকোড 8 এর জিএম সংস্করণ প্রকাশ না হওয়া অবধি আমি সুইফটের আগের প্রকাশগুলিতে এই কোডটির সংস্করণগুলি পেয়েছি। আমি Stackoverflow কয়েক অনুরূপ পোস্ট কটাক্ষপাত ছিল: সুইফট 2 পার্সিং তাদেরকে JSON - টাইপ 'AnyObject' এর একটি মান সাবস্ক্রিপ্ট করা যাবে না এবং সুইফট 3 তাদেরকে JSON পার্সিং

তবে, মনে হয় যে সেখানে দেওয়া ধারণাগুলি এই দৃশ্যে প্রয়োগ হয় না।

আমি কীভাবে সুইফট 3 এ জেএসএন পুনঃনির্দেশকে সঠিকভাবে পার্স করব? জেএসএন 3 টি সুইফট 3 তে পড়ার উপায়ে কি কিছু পরিবর্তন হয়েছে?

নীচে প্রশ্নের মধ্যে কোড রয়েছে (এটি কোনও খেলার মাঠে চালানো যেতে পারে):

import Cocoa

let url = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"

if let url = NSURL(string: url) {
    if let data = try? Data(contentsOf: url as URL) {
        do {
            let parsedData = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments)

        //Store response in NSDictionary for easy access
        let dict = parsedData as? NSDictionary

        let currentConditions = "\(dict!["currently"]!)"

        //This produces an error, Type 'Any' has no subscript members
        let currentTemperatureF = ("\(dict!["currently"]!["temperature"]!!)" as NSString).doubleValue

            //Display all current conditions from API
            print(currentConditions)

            //Output the current temperature in Fahrenheit
            print(currentTemperatureF)

        }
        //else throw an error detailing what went wrong
        catch let error as NSError {
            print("Details of JSON parsing error:\n \(error)")
        }
    }
}

সম্পাদনা করুন: পরে API কল থেকে ফলাফলগুলির নমুনা এখানে দেওয়া হয়েছেprint(currentConditions)

["icon": partly-cloudy-night, "precipProbability": 0, "pressure": 1015.39, "humidity": 0.75, "precipIntensity": 0, "windSpeed": 6.04, "summary": Partly Cloudy, "ozone": 321.13, "temperature": 49.45, "dewPoint": 41.75, "apparentTemperature": 47, "windBearing": 332, "cloudCover": 0.28, "time": 1480846460]

আপনার API কল থেকে ফিরে আসা নমুনা ডেটা কি আপনি রাখতে পারবেন?
ব্যবহারকারী

1
হ্যাঁ, আমি প্রিন্টের পরে মুদ্রিত ফলাফলগুলির একটি নমুনা (বর্তমান শর্তাদি) যুক্ত করেছি। আশা করি এটা সাহায্য করবে.
ব্যবহারকারী 2563039

Swift4 মধ্যে ব্যকরণগত JSON Codable প্রোটোকল ব্যবহার stackoverflow.com/a/52931265/9316566
নাসের মোহাম্মদ

উত্তর:


172

প্রথমত কোনও দূরবর্তী ইউআরএল থেকে কখনই ডেটা সিঙ্ক্রোনালি লোড করবেন না , সর্বদা মত অ্যাসিনক্রোনাস পদ্ধতি ব্যবহার করুন URLSession

'যে কোনও'র কোনও সাবস্ক্রিপ্ট সদস্য নেই

ঘটে কারণ কম্পাইলার কি টাইপ অন্তর্বর্তী বস্তু (উদাহরণস্বরূপ হয় কোন ধারণা আছে currently["currently"]!["temperature"]) এবং আপনার মত ফাউন্ডেশন সংগ্রহ ধরনের ব্যবহার করছেন যেহেতু NSDictionaryকম্পাইলার ধরনের সম্পর্কে সব সময়ে কোন ধারণা নেই।

অতিরিক্ত হিসাবে সুইফট 3 এ সমস্ত সাবস্ক্রিপশনযুক্ত সামগ্রীর ধরণের সম্পর্কে সংকলককে অবহিত করা প্রয়োজন ।

আপনাকে জেএসওএন সিরিয়ালাইজের ফলাফলটি প্রকৃত প্রকারে দিতে হবে।

এই কোডটি ব্যবহার করে URLSessionএবং একচেটিয়াভাবে সুইফট নেটিভ প্রকারগুলি

let urlString = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"

let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
  if error != nil {
    print(error)
  } else {
    do {

      let parsedData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
      let currentConditions = parsedData["currently"] as! [String:Any]

      print(currentConditions)

      let currentTemperatureF = currentConditions["temperature"] as! Double
      print(currentTemperatureF)
    } catch let error as NSError {
      print(error)
    }
  }

}.resume()

আপনার সমস্ত কী / মান currentConditionsজোড় লিখতে পারে

 let currentConditions = parsedData["currently"] as! [String:Any]

  for (key, value) in currentConditions {
    print("\(key) - \(value) ")
  }

সম্পর্কিত একটি নোট jsonObject(with data:

অনেকগুলি (এটি সমস্ত মনে হয়) টিউটোরিয়ালগুলি প্রস্তাব দেয় .mutableContainersবা .mutableLeavesবিকল্পগুলি যা সুইফটে সম্পূর্ণ বোকা। দুটি বিকল্প হ'ল উত্তরাধিকারী অবজেক্টিভ-সি বিকল্পগুলি NSMutable...বস্তুগুলিতে ফলাফল নির্ধারণের জন্য । varসুইফ্টে যে কোনও আইবলযোগ্য ডিফল্টরূপে পরিবর্তনযোগ্য এবং সেগুলির মধ্যে যে কোনও একটি বিকল্পকে পাস করা এবং ফলাফলকে letধ্রুবককে নির্ধারণের কোনও প্রভাব নেই has আরও বেশিরভাগ বাস্তবায়ন কখনই যাইহোক ডিসরিয়ালাইজড জেএসএনকে রূপান্তরিত করে না।

শুধুমাত্র (বিরল) বিকল্প যা সুইফট দরকারী হয় .allowFragmentsযা যদি তাদেরকে JSON রুট বস্তুর একটি মান টাইপ হতে পারে প্রয়োজন হয় ( String, Number, Boolবা null) বদলে সংগ্রহ ধরনের এক ( arrayবা dictionary)। তবে সাধারণত optionsপ্যারামিটারটি বাদ দিন যার অর্থ কোনও বিকল্প নেই

================================================== =========================

জেএসনকে পার্স করার জন্য কিছু সাধারণ বিবেচনা

জেএসএন একটি সুবিন্যস্ত পাঠ্য বিন্যাস। একটি JSON স্ট্রিং পড়া খুব সহজ। স্ট্রিং সাবধানে পড়ুন । এখানে ছয়টি বিভিন্ন ধরণের রয়েছে - দুটি সংগ্রহের ধরণ এবং চারটি মান প্রকার।


সংগ্রহের ধরণগুলি হ'ল

  • অ্যারে - জেএসওএন: বর্গাকার বন্ধনীতে বস্তু []- সুইফট: [Any]তবে বেশিরভাগ ক্ষেত্রে[[String:Any]]
  • অভিধান - JSON: কোঁকড়া ধনুর্বন্ধনী মধ্যে বস্তু {}- সুইফট:[String:Any]

মান ধরণের হয়

  • স্ট্রিং - জেএসওএন: ডাবল কোটগুলির যে কোনও মান "Foo", এমনকি "123"বা "false"- সুইফট:String
  • নম্বর - তাদেরকে JSON: সাংখ্যিক মান না উদ্ধৃতি চিহ্ন মধ্যে 123বা 123.0- সুইফট: IntবাDouble
  • Bool - তাদেরকে JSON: trueবা false না উদ্ধৃতি চিহ্ন মধ্যে - সুইফট: trueবাfalse
  • নাল - জেএসওএন: null- সুইফট:NSNull

জেএসএন স্পেসিফিকেশন অনুসারে অভিধানের সমস্ত কী থাকা দরকার String


মূলত এটি সর্বদা optionচ্ছিক বাইন্ডিংগুলি নিরাপদে unচ্ছিকভাবে মোড়কগুলিতে ব্যবহার করার জন্য পুনঃসংশ্লিষ্ট

মূল অবজেক্ট যদি অভিধান হয় ( {}) এ টাইপ করুন[String:Any]

if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [String:Any] { ...

এবং কীগুলির সাহায্যে মানগুলি পুনরুদ্ধার করুন ( OneOfSupportedJSONTypesহয় জেএসওএন সংগ্রহ বা উপরে বর্ণিত মানের ধরণ))

if let foo = parsedData["foo"] as? OneOfSupportedJSONTypes {
    print(foo)
} 

মূল অবজেক্টটি যদি একটি অ্যারে হয় ( []) এ টাইপ করুন[[String:Any]]

if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] { ...

এবং অ্যারের মাধ্যমে পুনরাবৃত্তি

for item in parsedData {
    print(item)
}

নির্দিষ্ট সূচীতে আপনার যদি আইটেমের প্রয়োজন হয় তবেও সূচকের উপস্থিতি আছে কিনা তা পরীক্ষা করে দেখুন

if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]], parsedData.count > 2,
   let item = parsedData[2] as? OneOfSupportedJSONTypes {
      print(item)
    }
}

দুর্লভ ক্ষেত্রে যে জেএসওএন কেবলমাত্র এক ধরণের মান ধরণের - কোনও সংগ্রহের ধরণের চেয়ে - আপনাকে .allowFragmentsবিকল্পটি পাস করতে হবে এবং ফলস্বরূপ উপযুক্ত মানের ধরণে ফল দিতে হবে উদাহরণস্বরূপ

if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String { ...

অ্যাপল একটি শীর্ষ নিবন্ধ প্রকাশ করেছে সুইফট ব্লগে: সুইফটে জেএসএন এর সাথে কাজ করা


================================================== =========================

সুইফট 4+ এ Codableপ্রোটোকল জেএসএনকে সরাসরি স্ট্রাক্ট / ক্লাসে পার্স করার জন্য আরও সুবিধাজনক উপায় সরবরাহ করে।

উদাহরণস্বরূপ প্রশ্নে প্রদত্ত জেএসএন নমুনা (কিছুটা সংশোধিত)

let jsonString = """
{"icon": "partly-cloudy-night", "precipProbability": 0, "pressure": 1015.39, "humidity": 0.75, "precip_intensity": 0, "wind_speed": 6.04, "summary": "Partly Cloudy", "ozone": 321.13, "temperature": 49.45, "dew_point": 41.75, "apparent_temperature": 47, "wind_bearing": 332, "cloud_cover": 0.28, "time": 1480846460}
"""

স্ট্রাক্ট মধ্যে ডিকোড করা যেতে পারে Weather। উপরের বর্ণিত সুইফট প্রকারগুলি একই রকম। কয়েকটি অতিরিক্ত বিকল্প রয়েছে:

  • স্ট্রিংগুলির প্রতিনিধিত্ব করে স্ট্রিংগুলি URLসরাসরি ডিকোড করা যায় URL
  • timeপূর্ণসংখ্যা হিসাবে সঙ্কেতমুক্ত করা যেতে পারে Dateসঙ্গে dateDecodingStrategy .secondsSince1970
  • snaked_cased তাদেরকে JSON কী কাজে রূপান্তরিত হতে পারে ক্যামেলকেস সঙ্গেkeyDecodingStrategy .convertFromSnakeCase

struct Weather: Decodable {
    let icon, summary: String
    let pressure: Double, humidity, windSpeed : Double
    let ozone, temperature, dewPoint, cloudCover: Double
    let precipProbability, precipIntensity, apparentTemperature, windBearing : Int
    let time: Date
}

let data = Data(jsonString.utf8)
do {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .secondsSince1970
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try decoder.decode(Weather.self, from: data)
    print(result)
} catch {
    print(error)
}

অন্যান্য কোডেবল উত্স:


এটি খুব সহায়ক। আমি কেবল কৌতূহলী যে উপরের কোডটি যখন খেলার মাঠে চালিত হয় তখন কেন দৃশ্যমান আউটপুট না দেখায়।
ব্যবহারকারী 2563039

উপরে উল্লিখিত হিসাবে dict!["currently"]!আপনাকে একটি অভিধানে দ্ব্যর্থক ফলাফল ফেলতে হবে যা সংকলক পরবর্তী কী সাবস্ক্রিপশনটি নিরাপদে নির্ধারণ করতে পারে।
ভাদিয়ান

1
অ্যাপল নিবন্ধটি বেশ দুর্দান্ত, তবে আমি কোনও কারণে এটি দ্রুত 3 দিয়ে চালাতে পারিনি। এটি টাইপ সম্পর্কে অভিযোগ [স্ট্রিং: যে কোনও]? কোন সাবস্ক্রিপ্ট সদস্য আছে। এটির সাথে আরও কিছু সমস্যা ছিল, তবে আমি এটি ঘিরে ফেলতে সক্ষম হয়েছি। কারও কাছে তাদের কোডের উদাহরণ রয়েছে যা আসলে চলে?
শেডস

@ শেডস একটি প্রশ্ন জিজ্ঞাসা করুন এবং আপনার কোড পোস্ট করুন। সম্ভবত আপনার সমস্যাটি মোড়কানো বিকল্পগুলির সাথে সম্পর্কিত।
ভাদিয়ান

আপনার API কল থেকে ফিরে আসা নমুনা ডেটা কি আপনি রাখতে পারবেন?
ব্যবহারকারী

12

এক বড় পরিবর্তন যা এক্সকোড 8 বিটা 6 এর সাথে সুইফ্ট 3 এর জন্য ঘটেছিল তা হ'ল আইডিটি এখন Anyপরিবর্তে আমদানি করে AnyObject

এর অর্থ হল এই টাইপটির parsedDataসাথে সম্ভবত একটি অভিধান হিসাবে প্রত্যাবর্তিত হয়েছে [Any:Any]। কোনও ডিবাগার ব্যবহার না করে আমি আপনাকে বলতে পারি না আপনার কাস্টটি ঠিক কী NSDictionaryকরবে তবে আপনি যে ত্রুটিটি দেখছেন তা হ'ল dict!["currently"]!টাইপ আছেAny

সুতরাং, আপনি এই সমাধান কিভাবে? আপনি যেভাবে এটি উল্লেখ করেছেন তা থেকে আমি ধরে নিই dict!["currently"]!যে একটি অভিধান এবং তাই আপনার কাছে অনেকগুলি বিকল্প রয়েছে:

প্রথমে আপনি এরকম কিছু করতে পারেন:

let currentConditionsDictionary: [String: AnyObject] = dict!["currently"]! as! [String: AnyObject]  

এটি আপনাকে একটি অভিধানের বস্তু দেবে যা আপনি তার পরে মানগুলির জন্য জিজ্ঞাসা করতে পারেন এবং আপনার তাপমাত্রাটি এভাবে পান:

let currentTemperatureF = currentConditionsDictionary["temperature"] as! Double

অথবা আপনি যদি পছন্দ করেন তবে লাইনে এটি করতে পারেন:

let currentTemperatureF = (dict!["currently"]! as! [String: AnyObject])["temperature"]! as! Double

আশা করি এটি সাহায্য করে, আমি ভয় করি যে এটি পরীক্ষা করার জন্য আমার কোনও নমুনা অ্যাপ্লিকেশন লেখার সময় হয়নি।

একটি চূড়ান্ত নোট: করণে সবচেয়ে সহজ কাজটি হতে পারে কেবল [String: AnyObject]শুরুতে ডানদিকে JSON পেডলোড castালাই ।

let parsedData = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as! Dictionary<String, AnyObject>

dict!["currently"]! as! [String: String]ক্রাশ হবে
ভাদিয়ান

এটি যে স্থানে বিধ্বস্ত হয়েছিল তা হ'ল "" তাপমাত্রা "] !! এবং স্ট্রিংকে
এনএসএসস্ট্রিংয়ের

[String: String]মোটামুটি কাজ করতে পারে না কারণ কয়েকটি সংখ্যক মান রয়েছে। এটি কোনও ম্যাক খেলার
মাঠে

@ ভাদিয়ান আহ, হ্যাঁ আমি সেগুলি লক্ষ্য করিনি এবং সুইফ্ট স্যান্ডবক্স সাহায্যমূলকভাবে তাদের আড়াল করেছে! - এখনই [আবার একবার] সংশোধন করা হয়েছে (এবং ম্যাকোএসে পরীক্ষা করা হয়েছে)। এটি নির্দেশ করার জন্য আপনাকে ধন্যবাদ :)
ডিসপ্লেভিলিও

6
let str = "{\"names\": [\"Bob\", \"Tim\", \"Tina\"]}"

let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false)!

do {
    let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
    if let names = json["names"] as? [String] 
{
        print(names)
}
} catch let error as NSError {
    print("Failed to load: \(error.localizedDescription)")
}

5

আমি এই উদ্দেশ্যে হুবহু কুইলটাইপ তৈরি করেছি । কেবলমাত্র আপনার নমুনা JSON কে পেস্ট করুন এবং আপনার এপিআই ডেটার জন্য দ্রুত টাইপ এই ধরণের শ্রেণিবিন্যাস উত্পন্ন করে:

struct Forecast {
    let hourly: Hourly
    let daily: Daily
    let currently: Currently
    let flags: Flags
    let longitude: Double
    let latitude: Double
    let offset: Int
    let timezone: String
}

struct Hourly {
    let icon: String
    let data: [Currently]
    let summary: String
}

struct Daily {
    let icon: String
    let data: [Datum]
    let summary: String
}

struct Datum {
    let precipIntensityMax: Double
    let apparentTemperatureMinTime: Int
    let apparentTemperatureLowTime: Int
    let apparentTemperatureHighTime: Int
    let apparentTemperatureHigh: Double
    let apparentTemperatureLow: Double
    let apparentTemperatureMaxTime: Int
    let apparentTemperatureMax: Double
    let apparentTemperatureMin: Double
    let icon: String
    let dewPoint: Double
    let cloudCover: Double
    let humidity: Double
    let ozone: Double
    let moonPhase: Double
    let precipIntensity: Double
    let temperatureHigh: Double
    let pressure: Double
    let precipProbability: Double
    let precipIntensityMaxTime: Int
    let precipType: String?
    let sunriseTime: Int
    let summary: String
    let sunsetTime: Int
    let temperatureMax: Double
    let time: Int
    let temperatureLow: Double
    let temperatureHighTime: Int
    let temperatureLowTime: Int
    let temperatureMin: Double
    let temperatureMaxTime: Int
    let temperatureMinTime: Int
    let uvIndexTime: Int
    let windGust: Double
    let uvIndex: Int
    let windBearing: Int
    let windGustTime: Int
    let windSpeed: Double
}

struct Currently {
    let precipProbability: Double
    let humidity: Double
    let cloudCover: Double
    let apparentTemperature: Double
    let dewPoint: Double
    let ozone: Double
    let icon: String
    let precipIntensity: Double
    let temperature: Double
    let pressure: Double
    let precipType: String?
    let summary: String
    let uvIndex: Int
    let windGust: Double
    let time: Int
    let windBearing: Int
    let windSpeed: Double
}

struct Flags {
    let sources: [String]
    let isdStations: [String]
    let units: String
}

এছাড়া ফেরত মান তুষ্ট করার নির্ভরতা মুক্ত marshaling কোড জেনারেট করে JSONSerialization.jsonObjectএকটি মধ্যে Forecast, একটি সুবিধা কন্সট্রাকটর করে একটি JSON স্ট্রিংকে লাগে তাহলে আপনি দ্রুত একটি শক্তিশালী ভাবে টাইপ পার্স করতে পারেন তা সহ Forecastমান এবং তার ক্ষেত্র একসেস করুন:

let forecast = Forecast.from(json: jsonString)!
print(forecast.daily.data[0].windGustTime)

আপনি এনপিএম থেকে দ্রুত টাইপ ইনস্টল করতে পারেন npm i -g quicktypeবা ওয়েব ইউআই ব্যবহার করে আপনার খেলার মাঠে পেস্ট করার জন্য সম্পূর্ণ উত্পন্ন কোড পেতে পারেন।


লিঙ্কগুলি ব্যর্থ হচ্ছে।
অঙ্কিত ..

ফ্যান্টাস্টিক টাইম সেভার! ভাল করেছ!
মার্কো

1
উজ্জ্বল সরঞ্জাম। ধন্যবাদ।
আহমেত আরদাল

4

আপডেট করা হয়েছেisConnectToNetwork-Function পরে, এই ধন্যবাদ পোস্টটি

আমি এটির জন্য একটি অতিরিক্ত পদ্ধতি লিখেছি:

import SystemConfiguration

func loadingJSON(_ link:String, postString:String, completionHandler: @escaping (_ JSONObject: AnyObject) -> ()) {

    if(isConnectedToNetwork() == false){
        completionHandler("-1" as AnyObject)
        return
    }

    let request = NSMutableURLRequest(url: URL(string: link)!)
    request.httpMethod = "POST"
    request.httpBody = postString.data(using: String.Encoding.utf8)

    let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
        guard error == nil && data != nil else { // check for fundamental networking error
            print("error=\(error)")
            return
        }

        if let httpStatus = response as? HTTPURLResponse , httpStatus.statusCode != 200 { // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
        }
        //JSON successfull
        do {
            let parseJSON = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
            DispatchQueue.main.async(execute: {
                completionHandler(parseJSON as AnyObject)
            });
        } catch let error as NSError {
            print("Failed to load: \(error.localizedDescription)")
        }
    }
    task.resume()
}

func isConnectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
    if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
        return false
    }

    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    let ret = (isReachable && !needsConnection)

    return ret
}

সুতরাং এখন আপনি যেখানেই চান সহজেই আপনার অ্যাপটিতে এটি কল করতে পারেন

loadingJSON("yourDomain.com/login.php", postString:"email=\(userEmail!)&password=\(password!)") { parseJSON in

    if(String(describing: parseJSON) == "-1"){
        print("No Internet")
    } else {

    if let loginSuccessfull = parseJSON["loginSuccessfull"] as? Bool {
        //... do stuff
    }
}

মার্কো, প্রকল্পে এই ফাংশনটি যুক্ত করার সর্বোত্তম উপায় কী হবে? কোন কনট্রোলার বা মডেল?
কমলপানহ্বর

আরে, আপনি কেবলমাত্র একটি অতিরিক্ত সুইফ্ট ফাইল বা শ্রেণিতে প্রথম পদ্ধতি ফানক লোডিং জেএসএন (...) যুক্ত করুন। এর পরে আপনি আপনার প্রকল্পের প্রতিটি নিয়ন্ত্রকের কাছ থেকে এটি কল করতে সক্ষম হন
মার্কো ওয়েবার

আমি এটি চেষ্টা করেছিলাম, তবে আমি একটি সম্পূর্ণ সমাধান প্রদর্শনের ধারণা এবং সহায়ক সহায়ক পদ্ধতি সহ এটি কীভাবে ব্যবহার করতে পারি তা কল্পনা করি (কানেক্টেড টোটনেটওয়ার্ক () এটি সম্ভবত ভাল কোডে কীভাবে প্রয়োগ করা যায় সে সম্পর্কে আমার ধারণা
আমর অ্যাংরি

সুতরাং আমি সবেমাত্র একটি নতুন সুইফট-ফাইল (আপনার প্রকল্পের গাছে বাম ক্লিক, নতুন ফাইল ..., সুইফ্ট ফাইল) ব্যবহার করেছি এবং এটিকে jsonhelper.swift বলে। এই ফাইলে আপনি প্রথম কোডটি লোডিং JSON () এবং isConnectedToNetwork () স্থাপন করেছেন। এর পরে আপনি আপনার প্রকল্পের প্রতিটি অংশে এই দুটি ফাংশন ব্যবহার করতে পারেন। উদাহরণস্বরূপ লগইনভিসি-তে, লগইন বোতামের ক্রিয়া হিসাবে আপনি দ্বিতীয় কোডটি ব্যবহার করতে সক্ষম হচ্ছেন, স্পষ্টতই আপনাকে ডোমেন, পোস্ট স্ট্রিং এবং প্যাসজেসন মানগুলি (পার্সজেএসন ["লগইনসুসেসফুল"]) পরিবর্তন করতে হবে যাতে তারা এর সাথে মেলে আপনার পিএইচপি ফাইল
মার্কো ওয়েবার

0

সুইফট একটি শক্তিশালী টাইপ অনুমিতি আছে। ফাংশনাল অ্যাপ্রোচ ব্যবহার করে "যদি যাক" বা "রক্ষককে" বয়লারপ্লেট থেকে মুক্ত করতে দেয় এবং বাধ্যতামূলকভাবে আঁকতে পারে:

  1. এখানে আমাদের জেএসওএন। আমরা alচ্ছিক JSON বা যথারীতি ব্যবহার করতে পারি। আমি আমাদের উদাহরণে alচ্ছিক ব্যবহার করছি:

    let json: Dictionary<String, Any>? = ["current": ["temperature": 10]]
  1. সহায়ক কার্যাদি। আমাদের এগুলি কেবল একবার লিখতে হবে এবং তারপরে যেকোন অভিধানের সাথে আবার ব্যবহার করতে হবে:

    /// Curry
    public func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
        return { a in
            { f(a, $0) }
        }
    }

    /// Function that takes key and optional dictionary and returns optional value
    public func extract<Key, Value>(_ key: Key, _ json: Dictionary<Key, Any>?) -> Value? {
        return json.flatMap {
            cast($0[key])
        }
    }

    /// Function that takes key and return function that takes optional dictionary and returns optional value
    public func extract<Key, Value>(_ key: Key) -> (Dictionary<Key, Any>?) -> Value? {
        return curry(extract)(key)
    }

    /// Precedence group for our operator
    precedencegroup RightApplyPrecedence {
        associativity: right
        higherThan: AssignmentPrecedence
        lowerThan: TernaryPrecedence
    }

    /// Apply. g § f § a === g(f(a))
    infix operator § : RightApplyPrecedence
    public func §<A, B>(_ f: (A) -> B, _ a: A) -> B {
        return f(a)
    }

    /// Wrapper around operator "as".
    public func cast<A, B>(_ a: A) -> B? {
        return a as? B
    }
  1. এবং এখানে আমাদের যাদুটি - মানটি বের করুন:

    let temperature = (extract("temperature") § extract("current") § json) ?? NSNotFound

কোডের কেবল একটি লাইন এবং কোনও বাহিনী আনপ্রেপস বা ম্যানুয়াল টাইপ কাস্টিং নয়। এই কোডটি খেলার মাঠে কাজ করে, তাই আপনি এটি অনুলিপি করে এটি পরীক্ষা করতে পারেন। এখানে গিটহাবের একটি বাস্তবায়ন রয়েছে।


0

এটি আপনার সমস্যা সমাধানের অন্য উপায়। সুতরাং দয়া করে নীচের সমাধানটি দেখুন। আশা করি এটা তোমাকে সাহায্য করবে।

let str = "{\"names\": [\"Bob\", \"Tim\", \"Tina\"]}"
let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
    let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
    if let names = json["names"] as? [String] {
        print(names)
    }
} catch let error as NSError {
    print("Failed to load: \(error.localizedDescription)")
}

0

সমস্যাটি এপিআই ইন্টারঅ্যাকশন পদ্ধতিতে। জেএসএন পার্সিং কেবল সিনট্যাক্সে পরিবর্তিত হয়েছে। মূল সমস্যাটি ডেটা আনার উপায় নিয়ে। আপনি যা ব্যবহার করছেন তা ডেটা পাওয়ার একটি সুসংগত উপায়। এটি প্রতিটি ক্ষেত্রে কাজ করে না। আপনার যা ব্যবহার করা উচিত তা ডেটা আনার জন্য একটি অ্যাসিনক্রোনাস উপায় way এইভাবে, আপনাকে এপিআইয়ের মাধ্যমে ডেটা অনুরোধ করতে হবে এবং এটি ডেটার সাথে প্রতিক্রিয়া জানার জন্য অপেক্ষা করতে হবে। আপনি ইউআরএল সেশন এবং তৃতীয় পক্ষের লাইব্রেরি দ্বারা এটি অর্জন করতে পারেন Alamofire। নীচে ইউআরএল সেশন পদ্ধতির কোড রয়েছে।

let urlString = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"
let url = URL.init(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
    guard error == nil else {
        print(error)
    }
    do {
        let Data = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
        // Note if your data is coming in Array you should be using [Any]()
        //Now your data is parsed in Data variable and you can use it normally
        let currentConditions = Data["currently"] as! [String:Any]
        print(currentConditions)
        let currentTemperatureF = currentConditions["temperature"] as! Double
        print(currentTemperatureF)
    } catch let error as NSError {
        print(error)
    }
}.resume()

0
{
    "User":[
      {
        "FirstUser":{
        "name":"John"
        },
       "Information":"XY",
        "SecondUser":{
        "name":"Tom"
      }
     }
   ]
}

যদি আমি পূর্ববর্তী জসন ব্যবহার করে মডেল তৈরি করি তবে এই লিঙ্কটি ব্যবহার করে [ব্লগ]: কোডিং কাঠামো বা যেকোন বিন্যাস তৈরি করতে http://www.jsoncafe.com

মডেল

import Foundation
struct RootClass : Codable {
    let user : [Users]?
    enum CodingKeys: String, CodingKey {
        case user = "User"
    }

    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        user = try? values?.decodeIfPresent([Users].self, forKey: .user)
    }
}

struct Users : Codable {
    let firstUser : FirstUser?
    let information : String?
    let secondUser : SecondUser?
    enum CodingKeys: String, CodingKey {
        case firstUser = "FirstUser"
        case information = "Information"
        case secondUser = "SecondUser"
    }
    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        firstUser = try? FirstUser(from: decoder)
        information = try? values?.decodeIfPresent(String.self, forKey: .information)
        secondUser = try? SecondUser(from: decoder)
    }
}
struct SecondUser : Codable {
    let name : String?
    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        name = try? values?.decodeIfPresent(String.self, forKey: .name)
    }
}
struct FirstUser : Codable {
    let name : String?
    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        name = try? values?.decodeIfPresent(String.self, forKey: .name)
    }
}

ব্যকরণগত

    do {
        let res = try JSONDecoder().decode(RootClass.self, from: data)
        print(res?.user?.first?.firstUser?.name ?? "Yours optional value")
    } catch {
        print(error)
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.