Как преобразовать строку JSON в словарь?
Я хочу сделать одну функцию в моем проекте swift, которая преобразует строку в формат словаря json, но у меня есть одна ошибка:
не удается преобразовать тип выражения (@lvalue NSData, options: IntegerLitralConvertible ...
Это мой код:
func convertStringToDictionary (text:String) -> Dictionary<String,String> {
var data :NSData = text.dataUsingEncoding(NSUTF8StringEncoding)!
var json :Dictionary = NSJSONSerialization.JSONObjectWithData(data, options:0, error: nil)
return json
}
Я делаю эту функцию в Objective-C:
- (NSDictionary*)convertStringToDictionary:(NSString*)string {
NSError* error;
//giving error as it takes dic, array,etc only. not custom object.
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
return json;
}
6 ответов:
предупреждение: это удобный метод для преобразования строки JSON в словарь, если по какой-то причине вам нужно работать со строкой JSON. Но если у вас есть JSON сведения доступно, вы должны вместо работа с данными, без использования строки вообще.
Swift 3
func convertToDictionary(text: String) -> [String: Any]? { if let data = text.data(using: .utf8) { do { return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] } catch { print(error.localizedDescription) } } return nil } let str = "{\"name\":\"James\"}" let dict = convertToDictionary(text: str)Swift 2
func convertStringToDictionary(text: String) -> [String:AnyObject]? { if let data = text.dataUsingEncoding(NSUTF8StringEncoding) { do { return try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject] } catch let error as NSError { print(error) } } return nil } let str = "{\"name\":\"James\"}" let result = convertStringToDictionary(str)Оригинал Swift 1 ответ:
func convertStringToDictionary(text: String) -> [String:String]? { if let data = text.dataUsingEncoding(NSUTF8StringEncoding) { var error: NSError? let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? [String:String] if error != nil { println(error) } return json } return nil } let str = "{\"name\":\"James\"}" let result = convertStringToDictionary(str) // ["name": "James"] if let name = result?["name"] { // The `?` is here because our `convertStringToDictionary` function returns an Optional println(name) // "James" }в вашей версии вы не передали правильные параметры в
NSJSONSerializationи забыл отдать результат. Кроме того, лучше проверить на возможную ошибку. Последнее примечание: это работает только если значение является строкой. Если это может быть другой тип, было бы лучше объявить преобразование словаря следующим образом:let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? [String:AnyObject]и, конечно, вам также нужно будет изменить тип возврата функции:
func convertStringToDictionary(text: String) -> [String:AnyObject]? { ... }
я обновил ответ Эрика Д для Swift 2:
func convertStringToDictionary(text: String) -> [String:AnyObject]? { if let data = text.dataUsingEncoding(NSUTF8StringEncoding) { do { let json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as? [String:AnyObject] return json } catch { print("Something went wrong") } } return nil }
Swift 3:
if let data = text.data(using: String.Encoding.utf8) { do { let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any] print(json) } catch { print("Something went wrong") } }
С Swift 3,
JSONSerializationимеет метод под названиемjsonObject(with:options:).jsonObject(with:options:)есть следующее объявление:class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Anyвозвращает объект Foundation из заданных данных JSON.
при использовании
jsonObject(with:options:), вам приходится иметь дело с обработкой ошибок (try,try?илиtry!) и тип литья (отAny). Поэтому вы можете решить свою проблему с помощью одного из следующих шаблонов.
#1. Использование метода это бросает и возвращает необязательный тип
import Foundation func convertToDictionary(from text: String) throws -> [String: String] { guard let data = text.data(using: .utf8) else { return [:] } let anyResult: Any = try JSONSerialization.jsonObject(with: data, options: []) return anyResult as? [String: String] ?? [:] }использование:
let string1 = "{\"City\":\"Paris\"}" do { let dictionary = try convertToDictionary(from: string1) print(dictionary) // prints: ["City": "Paris"] } catch { print(error) }let string2 = "{\"Quantity\":100}" do { let dictionary = try convertToDictionary(from: string2) print(dictionary) // prints [:] } catch { print(error) }let string3 = "{\"Object\"}" do { let dictionary = try convertToDictionary(from: string3) print(dictionary) } catch { print(error) // prints: Error Domain=NSCocoaErrorDomain Code=3840 "No value for key in object around character 9." UserInfo={NSDebugDescription=No value for key in object around character 9.} }
#2. Используя метод, который выбрасывает и возвращает необязательный тип
import Foundation func convertToDictionary(from text: String) throws -> [String: String]? { guard let data = text.data(using: .utf8) else { return [:] } let anyResult: Any = try JSONSerialization.jsonObject(with: data, options: []) return anyResult as? [String: String] }использование:
let string1 = "{\"City\":\"Paris\"}" do { let dictionary = try convertToDictionary(from: string1) print(String(describing: dictionary)) // prints: Optional(["City": "Paris"]) } catch { print(error) }let string2 = "{\"Quantity\":100}" do { let dictionary = try convertToDictionary(from: string2) print(String(describing: dictionary)) // prints nil } catch { print(error) }let string3 = "{\"Object\"}" do { let dictionary = try convertToDictionary(from: string3) print(String(describing: dictionary)) } catch { print(error) // prints: Error Domain=NSCocoaErrorDomain Code=3840 "No value for key in object around character 9." UserInfo={NSDebugDescription=No value for key in object around character 9.} }
#3. Используя метод, который не бросает и возвращает необязательный тип
import Foundation func convertToDictionary(from text: String) -> [String: String] { guard let data = text.data(using: .utf8) else { return [:] } let anyResult: Any? = try? JSONSerialization.jsonObject(with: data, options: []) return anyResult as? [String: String] ?? [:] }использование:
let string1 = "{\"City\":\"Paris\"}" let dictionary1 = convertToDictionary(from: string1) print(dictionary1) // prints: ["City": "Paris"]let string2 = "{\"Quantity\":100}" let dictionary2 = convertToDictionary(from: string2) print(dictionary2) // prints: [:]let string3 = "{\"Object\"}" let dictionary3 = convertToDictionary(from: string3) print(dictionary3) // prints: [:]
#4. Использование метода это не бросает и возвращает необязательный тип
import Foundation func convertToDictionary(from text: String) -> [String: String]? { guard let data = text.data(using: .utf8) else { return nil } let anyResult = try? JSONSerialization.jsonObject(with: data, options: []) return anyResult as? [String: String] }использование:
let string1 = "{\"City\":\"Paris\"}" let dictionary1 = convertToDictionary(from: string1) print(String(describing: dictionary1)) // prints: Optional(["City": "Paris"])let string2 = "{\"Quantity\":100}" let dictionary2 = convertToDictionary(from: string2) print(String(describing: dictionary2)) // prints: nillet string3 = "{\"Object\"}" let dictionary3 = convertToDictionary(from: string3) print(String(describing: dictionary3)) // prints: nil
Я нашел код, который преобразует строку json в NSDictionary или NSArray.просто добавьте расширение SWIFT 3.0
КАК ИСПОЛЬЗОВАТЬ
let jsonData = (convertedJsonString as! String).parseJSONStringрасширение
extension String { var parseJSONString: AnyObject? { let data = self.data(using: String.Encoding.utf8, allowLossyConversion: false) if let jsonData = data { // Will return an object or nil if JSON decoding fails do { let message = try JSONSerialization.jsonObject(with: jsonData, options:.mutableContainers) if let jsonResult = message as? NSMutableArray { return jsonResult //Will return the json array output } else if let jsonResult = message as? NSMutableDictionary { return jsonResult //Will return the json dictionary output } else { return nil } } catch let error as NSError { print("An error occurred: \(error)") return nil } } else { // Lossless conversion of the string was not possible return nil } }}
Swift 4
extension String { func convertToDictionary() -> [String: Any]? { if let data = self.data(using: .utf8) { do { return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] } catch { print(error.localizedDescription) } } return nil } }
Comments