JSONã䜿çšããããšããªãéçºè ãæããŠãã ããã ã·ã³ãã«ããæè»æ§ãå¯èŠæ§ã«ããããã®ããŒã¿è¡šç€ºåœ¢åŒã¯éåžžã«äººæ°ããããçŸåšã©ãã§ã䜿çšãããŠããŸãã ãã®ãããSwiftã®å®éšäžã«ãJSONããŒã¿ã解æããå¿ èŠæ§ã«ããã«æ°ä»ããŸããã
å®éãæšæºã®Foundation APIïŒ NSJSONSerializationïŒã¯ãããã¹ãè¡šçŸãããªããžã§ã¯ãã¢ãã«ãžã®JSONã®çŽæ¥ããã³éå€æã®ã¿ã¹ã¯ã«å®å šã«å¯Ÿå¿ããŠããŸãã Appleã¯SwiftãšObjective-Cã³ãŒãéã®çŽæ¥ããã³éã®çžäºäœçšã確å®ã«ããããã«å€ãã®äœæ¥ãè¡ããŸããïŒ ScoftãšCocoaããã³Objective-Cã䜿çšããïŒã䜿ãæ £ããCocoa APIã®äœ¿çšã¯å®éã«å¯èœã§ããã ãã§ãªãã䟿å©ã§äžèªç¶ã«èŠããŸããïŒ
let jsonString = "{\"name\":\"John\",\"age\":32,\"phoneNumbers\":[{\"type\":\"home\",\"number\":\"212 555-1234\"}]}" let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) let jsonObject: AnyObject! = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions(0), error: nil)
ããããéçã«åæå®ãããSwiftã§çµæãæäœããã®ã¯äžäŸ¿ã§ããå€ãååŸããã«ã¯ããã§ãã¯ãšåå€æã®ãã§ãŒã³ãå¿ èŠã§ãã 次ã«ããã®åé¡ã®è§£æ±ºçãæ€èšãããšåæã«ãSwiftã®ããã€ãã®æ©èœã«ç²ŸéããŸãã
NSJSONSerializationã«ãã£ãŠæ£åŒã«ååŸãããJSONè¡šçŸã¯ãNSNullãNSNumberãNSStringãNSArrayãNSDictionaryã®Foundationã¿ã€ãã®ã€ã³ã¹ã¿ã³ã¹ã§æ§æãããŠããŸãã ãããã ã©ã³ã¿ã€ã ããªããžã³ã°ã¯ããããã®åãšå¯Ÿå¿ããSwiftããªããã£ãïŒæ°å€åïŒIntãDoubleãªã©ïŒãæååãé åãèŸæžïŒã®å®å šãªäºææ§ãšäºææ§ãæäŸããŸãã ãããã£ãŠãSwiftã³ãŒãã§ã¯ãçæããããªããžã§ã¯ããããã€ãã£ãã«ãåŠçã§ããŸãã æåã®é»è©±çªå·ã®å€ã確èªããå¿ èŠããããšããŸãã Objective-Cã§ã¯ãããã¯æ¬¡ã®ããã«ãªããŸãã
NSString *number = jsonObject[@âphoneNumbersâ][0][@ânumberâ]; NSAssert(["212 555-1234" isEqualToString:number], @ânumbers should matchâ);
åçãªåæå®ã䜿çšããããšã«ãããJSONãªããžã§ã¯ãã®éå±€ãããã²ãŒãããŠããObjective-Cã§åé¡ã¯çºçããŸããã ãããšã¯å¯Ÿç §çã«ãSwiftã¯å³å¯ãªéçåä»ãã䜿çšãããããéå±€ã®ãããæ·±ããåã¹ãããã§æ瀺çãªåãã£ã¹ãã䜿çšããå¿ èŠããããŸãã
let person = jsonObject! as Dictionary<String,AnyObject> let phoneNumbers = person["phoneNumbers"] as Array<AnyObject> let phoneNumber = phoneNumbers[0] as Dictionary<String,AnyObject> let number = phoneNumber["number"] as String assert(number == "212 555-1234")
æ®å¿µãªãããçŸåšã®ããŒãžã§ã³ã®ã³ã³ãã€ã©ïŒXcode 6ããŒã¿2ïŒã¯ãã®ã³ãŒãã«å¯ŸããŠãšã©ãŒãçæããŸã- æ·»åã䜿çšãããªãã©ã³ããæã€æ瀺çãªåå€æã®åŒã®è§£æã«åé¡ããããŸã ã ããã¯äžéå€æ°ã«ãã£ãŠåé¿ã§ããŸãïŒ
let person = jsonObject! as Dictionary<String,AnyObject> let phoneNumbers : AnyObject? = person["phoneNumbers"] let phoneNumbersArray = phoneNumbers as Array<AnyObject> let phoneNumber : AnyObject? = phoneNumbersArray[0] let phoneNumberDict = phoneNumber as Dictionary<String,AnyObject> let number : AnyObject? = phoneNumberDict["number"] let numberString = number as String assert(numberString == "212 555-1234")
ãã®ãªãã·ã§ã³ã¯æ£ããæ©èœããŸããã確ãã«ã²ã©ãããã«èŠããŸãã 1ã€ã®åŒã§å€ãååŸããããšãšã ãªãã·ã§ã³ã®ããŠã³ãã£ã¹ãããã³ãªãã·ã§ã³ã®é£éãçµã¿åãããŸã ã
let maybeNumber = (((jsonObject as? NSDictionary)?["phoneNumbers"] as? NSArray)?[0] as? NSDictionary)?["number"] as? NSString assert(maybeNumber == "212 555-1234")
ãã§ã«åªããŠããŸããããã¡ãããã®ãããªã¬ã³ãŒãã䟿å©ãªãã®ãšåŒã¶ããšã¯å°é£ã§ã-èªæžãç¹ã«ç·šéã®ããã«ã
ããã¯ãããããåé¡ã®ç¹æ®ãªã±ãŒã¹ãã€ãŸãå³å¯ã«åæå®ãããèšèªã§åçããŒã¿æ§é ãæäœããè€éãã ãã§ããããšã¯æããã§ãã ãã®åé¡ã解決ããã«ã¯ããŸããŸãªã¢ãããŒãããããããŒã¿ã®åŠçæ¹æ³ãå€ãããã®ããããŸãã ããããJSONãªããžã§ã¯ãã解æããç¹å®ã®ã±ãŒã¹ã§ã¯ã次ã®èŠä»¶ãæºããç°¡åãªãœãªã¥ãŒã·ã§ã³ãæ¢ããŠããŸããã
- ã³ãŒãã®ã³ã³ãã¯ãããšèªã¿ãããã
- æ瀺çãªåãã£ã¹ãã®å¿ èŠæ§ãæå°éã«ããŸãã
- ãã§ãŒã³å ã®1ã€ã®åŒã§éå±€ã®ããã€ãã®ã¬ãã«ããé瀺ãããå¯èœæ§ãšå©äŸ¿æ§ã
- JSONæ§é ãšæåŸ å€ãšã®äžäžèŽã«ããå®è¡æãšã©ãŒã®å¯èœæ§ãæé€ããŸã-ãã®ãããªå ŽåãåŒå šäœã®å€ã¯ãŒãã§ãªããã°ãªããŸããã
- CPUãšã¡ã¢ãªã®ãªãŒããŒããããæå°éã«æããŸãã
ãŸããæ¢æã®ãœãªã¥ãŒã·ã§ã³ãèŠã€ããŠåæããããšããŸããã
åæè¡šçŸ
æ°äººã®èè ãããã«åæ§ã®ã¢ãããŒããææ¡ããŠããŸãïŒ
- github.com/owensd/json-swift
- github.com/lingoer/SwiftyJSON
- github.com/maxpow4h/swiftz/blob/master/swiftz/JSON.swift
äŸãšããŠjson-swiftã䜿çšããããã€ã¹ã«ã€ããŠç°¡åã«èããŠã¿ãŸãããã
- JSONãªããžã§ã¯ããè¡šãæ°ããåæåïŒ github ïŒãå°å ¥ãããŸãã
- é¢é£ããå€ã®ã¡ã«ããºã ã䜿çšããŠããã®åæåã®å¯èœãªå€ã¯ãJSONåïŒ github ïŒã«å¯Ÿå¿ããããªããã£ããªSwiftåã«èšå®ãããŸã
- ã¡ã€ã³ã®åã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãæž¡ããããªããžã§ã¯ãã®åããã§ãã¯ããç®çã®åæå€ïŒ github ïŒãæã€ã€ã³ã¹ã¿ã³ã¹ãè¿ããŸã
- åæã«ãã³ã³ããïŒé åããã³èŸæžïŒã®å ŽåãèŠçŽ ã¯ååž°çã«åŠçãããŸãïŒ github ïŒ
- JSONéå±€ãããã²ãŒãããããã«ãé åãšèŸæžã«é©åãªèŠçŽ ãè¿ãæ·»ãåãå®è£ ãããŠããŸãïŒ github ïŒ
- JSONåæåãã察å¿ããããªããã£ãSwiftåãžã®éå€æã§ã¯ã èšç®ãããããããã£ã䜿çšãã ãåãäžèŽããå Žåã«ã®ã¿é¢é£ä»ããããå€ãè¿ããŸãïŒ github ïŒ
å ã®ãªããžã§ã¯ãã¢ãã«ããã®ãããªè¡šçŸã«å€æãããšãéå±€ãããã²ãŒãããŠæåŸ ãããã¿ã€ãã®å€ãååŸããããã«äœ¿çšã§ãã䟿å©ãªã€ã³ã¿ãŒãã§ã€ã¹ãåŸãããŸãã
let number = JSON(jsonObject)?[âphoneNumbersâ]?[0]?[ânumberâ]?.string assert(number == "212 555-1234")
ããã§ã¯ããªãã·ã§ã³ã®é£éã¡ã«ããºã ã«ãããã©ã³ã¿ã€ã ãšã©ãŒããªãããšãä¿èšŒããŸãã äžé©åãªæ§é ãæã€ãªããžã§ã¯ãã解æããå ŽåãåŒå šäœã®å€ã¯nilã«ãªããŸãïŒé åã®å€éšã§ã€ã³ããã¯ã¹ã«ã¢ã¯ã»ã¹ããå Žåãé€ãïŒã
ãã®ãããªãœãªã¥ãŒã·ã§ã³ã¯ã1ã€ãé€ããã¹ãŠã®èŠä»¶ãæºãããŠããããšãããããŸãã ããã䜿çšãããšãJSONãªããžã§ã¯ãã®éå±€å šäœã®å¿ é ã®ååž°ãã©ããŒãµã«ãçºçããããŒã¿ã®æ°ãããªããžã§ã¯ãè¡šçŸãäœæãããŸãã ãã¡ãããå Žåã«ãã£ãŠã¯ããã®ãããªãªãŒããŒãããã¯åºæ¬çãªåœ¹å²ãæãããŸããã ããããããã§ããCPUãªãœãŒã¹ãšã¡ã¢ãªãªãœãŒã¹ã®äœ¿çšã«é¢ããŠããœãªã¥ãŒã·ã§ã³å šäœãæé©ãšã¯èšããŸããã
ãã®åé¡ã解決ããåºæ¬çãªæ¹æ³ã¯ãããã¹ãè¡šçŸããã®å€æã®æ®µéã§ãã®ãããªãªããžã§ã¯ãJSONè¡šçŸã䜿çšããããšã§ãã ãããããã®ãããªã¢ãããŒãã¯ãã§ã«æ€èšäžã®åé¡ã®ç¯å²ãè¶ ããŠããŸã-JSONã®ãã€ãã£ããªããžã§ã¯ãè¡šçŸã䜿çšãã䟿å©ãªäœæ¥ã§ãã
é 延åŠç
å®å šãªå€æã®åé¡ã解決ããå¥ã®ã¢ãããŒãã¯ãJSONããã©ããŒã¹ãããšãã«ãé 延ãããžãã¯ã䜿çšããŠåããã§ãã¯ããã³ãã£ã¹ãããããšã§ãã å¿ èŠãªã¿ã€ãã®å€ã䜿çšããŠJSONéå±€å šäœãããã«åäœæãã代ããã«ãèŠæ±ããã1ã€ã®èŠçŽ ã®ã¿ã«å¯ŸããŠãã詳现ãã®åã¹ãããã§ãããå®è¡ã§ããŸãã ãã®ãããªã¢ãããŒãã®å®è£ ã¯ãæªåé«ããã€ã¯ã¢ãã·ã¥ã«ãã£ãŠæäŸãããŠããŸãïŒ gist.github.com/mikeash/f443a8492d78e1d4dd10
æ®å¿µãªããããã®ã¢ãããŒãã§ã¯ãåå¥ã®JSONå€ãåã䟿å©ãªåœ¢åŒïŒenum +é¢é£ããå€ïŒã§æ瀺ããããšã¯ã§ããŸããã ãããããã®ãããªãœãªã¥ãŒã·ã§ã³ã¯æããã«æé©ã§ãã äžèŠãããšãããéå±€ã®æ·±ãåã¹ãããã§è¿œå ã®ã©ãããŒãªããžã§ã¯ããäœæãããšãã圢ã§å°ããªãªãŒããŒãããããããŸãã ãã ãããããã®ãªããžã§ã¯ãã¯æ§é äœïŒæ§é äœå€ïŒãšããŠå®çŸ©ãããŠãããããSwiftã®ã³ã³ãã€ã©ãŒã«ãã£ãŠåæåãšäœ¿çšãé©åã«æé©åã§ããŸãã
解決ç
æ°ããåã䜿çšãããå¿ èŠã«å¿ããŠæšæºåã®åäœãæ¡åŒµãããœãªã¥ãŒã·ã§ã³ãæ¢ããŠããŸããã æšæºæ§æã䜿çšããŠåŒã詳ããèŠãŠã¿ãŸããã
(((jsonObject as? NSDictionary)?["phoneNumbers"] as? NSArray)?[0] as? NSDictionary)?["number"] as? NSString
å®éãèŸæžãšé åã®èŠçŽ ãžã®ç§»è¡ã ããããã§åé¡ãåŒãèµ·ãããŸãã ããã¯ãæ·»ãååŒã³åºãïŒ
[1]
ãŸãã¯
[ânumberâ]
ïŒãé©çšãããå€ã®ã¿ã€ãã«èŠä»¶ã課ãããã§ãããã®å ŽåãNSDictionaryãŸãã¯NSArrayã«ãã£ã¹ãããŠããŸãã ãŸãã¯ãNSArrayããã³NSDictionaryããååŸããå€ã¯AnyObjectåã§ãããããã³ãŒã«ãã§ãŒã³ã®åŸåã§äœ¿çšããåãã£ã¹ããå¿ èŠã§ãã
æåã«æ·»ãåãªãã·ã§ã³ã®äž¡æ¹ããµããŒãããåãã¿ã€ãã®ãªããžã§ã¯ããè¿ããŠãããŒãµã«ã¿ã€ããæäœãããšããã£ã¹ãã®å¿ èŠæ§ããªããªãããšãããããŸãã Swiftã§ã¯ããããã³ã«ã¯æ£åŒã«ãã®å®çŸ©ãæºãããŠããŸãã
protocol JSONValue { subscript(key: String) -> JSONValue? { get } subscript(index: Int) -> JSONValue? { get } }
ãããã£ãŠããããã³ã«ã¯JSONå€ã決å®ããŸããããã«ã¯ãæ·»ãåïŒIntãŸãã¯Stringãã©ã¡ãŒã¿ãŒã䜿çšïŒã«ãã£ãŠåžžã«ã¢ã¯ã»ã¹ã§ããŸãã ãã®çµæãã³ã¬ã¯ã·ã§ã³èŠçŽ ïŒãªããžã§ã¯ããã³ã¬ã¯ã·ã§ã³ã§ããå Žåããã®ã¿ã€ãã¯äžä»ãæåã¿ã€ãã«å¯Ÿå¿ãããã®ãããªäžä»ãæåãæã€èŠçŽ ã¯ã³ã¬ã¯ã·ã§ã³å ã«ãããŸãïŒãŸãã¯nilãååŸã§ããŸãã
ãã®æ¹æ³ã§æšæºåã䜿çšããã«ã¯ãããããJSONValueãšäžèŽããããšã確èªããå¿ èŠããããŸãã Swiftã§ã¯ãæ¡åŒµæ©èœã䜿çšããŠãããã³ã«å®è£ ãè¿œå ã§ããŸãã ãã®çµæããœãªã¥ãŒã·ã§ã³å šäœã¯æ¬¡ã®ããã«ãªããŸãã
protocol JSONValue { subscript(#key: String) -> JSONValue? { get } subscript(#index: Int) -> JSONValue? { get } } extension NSNull : JSONValue { subscript(#key: String) -> JSONValue? { return nil } subscript(#index: Int) -> JSONValue? { return nil } } extension NSNumber : JSONValue { subscript(#key: String) -> JSONValue? { return nil } subscript(#index: Int) -> JSONValue? { return nil } } extension NSString : JSONValue { subscript(#key: String) -> JSONValue? { return nil } subscript(#index: Int) -> JSONValue? { return nil } } extension NSArray : JSONValue { subscript(#key: String) -> JSONValue? { return nil } subscript(#index: Int) -> JSONValue? { return index < count && index >= 0 ? JSON(self[index]) : nil } } extension NSDictionary : JSONValue { subscript(#key: String) -> JSONValue? { return JSON(self[key]) } subscript(#index: Int) -> JSONValue? { return nil } } func JSON(object: AnyObject?) -> JSONValue? { if let some : AnyObject = object { switch some { case let null as NSNull: return null case let number as NSNumber: return number case let string as NSString: return string case let array as NSArray: return array case let dict as NSDictionary: return dict default: return nil } } else { return nil } }
ããã€ãã®ã¡ã¢ïŒ
- NSDictionaryããã³NSArrayã®æšæºæ·»ãåãšã®ç«¶åãé¿ããããã«ãååä»ããã©ã¡ãŒã¿ãŒãæã€æ·»ãåã䜿çšãããŸã-ïŒkeyãïŒindex;
- æšæºã®æ€èšŒæŒç®åãšãã£ã¹ãæŒç®åã¯
@objc
å±æ§ã§ããŒã¯ããããããã³ã«ã§ã®ã¿æ©èœããããããã«ããŒé¢æ°ã䜿çšããŠä»»æã®å€ãJSONValueåã«ãã£ã¹ãããŸã ïŒããã¯ã@objc
ãããã³ã«ããã®ãããªSwiftåã«è¿œå ã§ããããã§ããå®è¡æã«å©çšã§ããªãããŒã¿ïŒ; - ã³ãŒãã¯Foundationã¿ã€ãã§åäœããŸãããã©ã³ã¿ã€ã ããªããžã³ã°ã«ãããSwiftããªããã£ããæ£ããåäœããããšãä¿èšŒãããŸãã
ãã®çµæãåŒã䜿çšããŠJSONãæäœã§ããŸãã
let maybeNumber = JSON(jsonObject)?[key:"phoneNumbers"]?[index:0]?[key:"number"] as? NSString assert(maybeNumber == "212 555-1234")
ããã¯æ€èšå¯Ÿè±¡ã®äžã§æãã³ã³ãã¯ããªãªãã·ã§ã³ã§ã¯ãããŸãããããã®ãããªãœãªã¥ãŒã·ã§ã³ã¯äžèšã®ãã¹ãŠã®èŠä»¶ãå®å šã«æºãããŠããŸãã
代æ¿ãªãã·ã§ã³
åãèãã«åºã¥ããŠã
@objc
å±æ§ãæã€ãããã³ã«ã䜿çšããããªã¢ã³ãã
@objc
ã§ãã ããã«ãããè£å©é¢æ°ã®ä»£ããã«æ瀺çãªåãã£ã¹ãã䜿çšã§ããŸãããæ·»ãåã®äœ¿çšã¯çŠæ¢ãããŸã-代ããã«éåžžã®ã¡ãœããã䜿çšããå¿ èŠããããŸãã ãã ãããããã®ã¡ãœããã¯
@optional
ãšããŠå®£èšã§ããŸãã
@objc protocol JSON { @optional func array(index: Int) -> JSON? @optional func object(key: String) -> JSON? } extension NSArray : JSON { func array(index: Int) -> JSON? { return index < count && index >= 0 ? self[index] as? JSON : nil } } extension NSDictionary: JSON { func object(key: String) -> JSON? { return self[key] as? JSON } } extension NSNull : JSON {} extension NSNumber : JSON {} extension NSString : JSON {}
䜿çšäŸïŒ
let maybeNumber = (jsonObject as? JSON)?.object?(âphoneNumbersâ)?.array?(0)?.object?(ânumberâ) as? NSString assert(maybeNumber == "212 555-1234")
æ·»ãåä»ããªãã·ã§ã³ã»ã©ã³ã³ãã¯ãã§ã¯ãããŸããã çå笊ã®æ°ã«æžæã人ããããããããŸãããããã®äžæ¹ã§ãããããã®äœ¿çšã¯ç解å¯èœã§ãããæå³çãªè² è·ãããããŸãã
ç§ã®æèŠã§ã¯ãèŠã€ãã£ããœãªã¥ãŒã·ã§ã³ã¯æå®ãããèŠä»¶ãæºãããæ€èšãããŠããä»ã®ãªãã·ã§ã³ãããæãŸããããã«èŠããŸãã ãããŠã䜿çšãããã¢ã€ãã¢-ãªãã·ã§ã³ã®å€ãè¿ãã¡ãœããã䜿çšãããŠãããŒãµã«ãããã³ã«ã®å²ãåœãŠ-ã¯ãJSONã ãã§ãªããä»ã®åçããŒã¿æ§é ã§ã䟿å©ã«äœ¿çšã§ããŸãã
ã³ãŒããšäœ¿çšäŸã¯githubã§å ¥æã§ããŸãã