JSON 문자열을 사전으로 변환하는 방법?
String을 Dictionary 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;
}
경고 : 어떤 이유로 JSON 문자열에서 작업해야하는 경우 JSON 문자열을 사전으로 변환하는 편리한 방법입니다. 그러나 JSON 데이터를 사용할 수 있는 경우 문자열을 전혀 사용하지 않고 data로 작업 해야 합니다.
스위프트 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)
스위프트 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)
원본 스위프트 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에 대한 Eric D의 답변을 업데이트했습니다 .
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
}
스위프트 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
주어진 JSON 데이터에서 Foundation 객체를 반환합니다.
당신이 사용하는 경우 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.}
}
#삼. 선택 사항이 아닌 유형을 던지지 않고 리턴하는 메소드 사용
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: nil
let string3 = "{\"Object\"}"
let dictionary3 = convertToDictionary(from: string3)
print(String(describing: dictionary3)) // prints: nil
스위프트 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
}
}
json 문자열을 NSDictionary 또는 NSArray로 변환하는 코드를 찾았습니다. 확장명을 추가하십시오.
스위프트 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
}
}
}
세부
- Xcode 버전 10.3 (10G8), 스위프트 5
해결책
import Foundation
// MARK: - CastingError
struct CastingError: Error {
let fromType: Any.Type
let toType: Any.Type
init<FromType, ToType>(fromType: FromType.Type, toType: ToType.Type) {
self.fromType = fromType
self.toType = toType
}
}
extension CastingError: LocalizedError {
var localizedDescription: String { return "Can not cast from \(fromType) to \(toType)" }
}
extension CastingError: CustomStringConvertible { var description: String { return localizedDescription } }
// MARK: - Data cast extensions
extension Data {
func toDictionary(options: JSONSerialization.ReadingOptions = []) throws -> [String: Any] {
return try to(type: [String: Any].self, options: options)
}
func to<T>(type: T.Type, options: JSONSerialization.ReadingOptions = []) throws -> T {
guard let result = try JSONSerialization.jsonObject(with: self, options: options) as? T else {
throw CastingError(fromType: type, toType: T.self)
}
return result
}
}
// MARK: - String cast extensions
extension String {
func asJSON<T>(to type: T.Type, using encoding: String.Encoding = .utf8) throws -> T {
guard let data = data(using: encoding) else { throw CastingError(fromType: type, toType: T.self) }
return try data.to(type: T.self)
}
func asJSONToDictionary(using encoding: String.Encoding = .utf8) throws -> [String: Any] {
return try asJSON(to: [String: Any].self, using: encoding)
}
}
// MARK: - Dictionary cast extensions
extension Dictionary {
func toData(options: JSONSerialization.WritingOptions = []) throws -> Data {
return try JSONSerialization.data(withJSONObject: self, options: options)
}
}
용법
let value1 = try? data.toDictionary()
let value2 = try? data.to(type: [String: Any].self)
let value3 = try? data.to(type: [String: String].self)
let value4 = try? string.asJSONToDictionary()
let value5 = try? string.asJSON(to: [String: String].self)
테스트 샘플
여기에 솔루션 코드 를 붙여 넣는 것을 잊지 마십시오
func testDescriber(text: String, value: Any) {
print("\n//////////////////////////////////////////")
print("-- \(text)\n\n type: \(type(of: value))\n value: \(value)")
}
let json1: [String: Any] = ["key1" : 1, "key2": true, "key3" : ["a": 1, "b": 2], "key4": [1,2,3]]
var jsonData = try? json1.toData()
testDescriber(text: "Sample test of func toDictionary()", value: json1)
if let data = jsonData {
print(" Result: \(String(describing: try? data.toDictionary()))")
}
testDescriber(text: "Sample test of func to<T>() -> [String: Any]", value: json1)
if let data = jsonData {
print(" Result: \(String(describing: try? data.to(type: [String: Any].self)))")
}
testDescriber(text: "Sample test of func to<T>() -> [String] with cast error", value: json1)
if let data = jsonData {
do {
print(" Result: \(String(describing: try data.to(type: [String].self)))")
} catch {
print(" ERROR: \(error)")
}
}
let array = [1,4,5,6]
testDescriber(text: "Sample test of func to<T>() -> [Int]", value: array)
if let data = try? JSONSerialization.data(withJSONObject: array) {
print(" Result: \(String(describing: try? data.to(type: [Int].self)))")
}
let json2 = ["key1": "a", "key2": "b"]
testDescriber(text: "Sample test of func to<T>() -> [String: String]", value: json2)
if let data = try? JSONSerialization.data(withJSONObject: json2) {
print(" Result: \(String(describing: try? data.to(type: [String: String].self)))")
}
let jsonString = "{\"key1\": \"a\", \"key2\": \"b\"}"
testDescriber(text: "Sample test of func to<T>() -> [String: String]", value: jsonString)
print(" Result: \(String(describing: try? jsonString.asJSON(to: [String: String].self)))")
testDescriber(text: "Sample test of func to<T>() -> [String: String]", value: jsonString)
print(" Result: \(String(describing: try? jsonString.asJSONToDictionary()))")
let wrongJsonString = "{\"key1\": \"a\", \"key2\":}"
testDescriber(text: "Sample test of func to<T>() -> [String: String] with JSONSerialization error", value: jsonString)
do {
let json = try wrongJsonString.asJSON(to: [String: String].self)
print(" Result: \(String(describing: json))")
} catch {
print(" ERROR: \(error)")
}
테스트 로그
//////////////////////////////////////////
-- Sample test of func toDictionary()
type: Dictionary<String, Any>
value: ["key4": [1, 2, 3], "key2": true, "key3": ["a": 1, "b": 2], "key1": 1]
Result: Optional(["key4": <__NSArrayI 0x600002a35380>(
1,
2,
3
)
, "key2": 1, "key3": {
a = 1;
b = 2;
}, "key1": 1])
//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: Any]
type: Dictionary<String, Any>
value: ["key4": [1, 2, 3], "key2": true, "key3": ["a": 1, "b": 2], "key1": 1]
Result: Optional(["key4": <__NSArrayI 0x600002a254d0>(
1,
2,
3
)
, "key2": 1, "key1": 1, "key3": {
a = 1;
b = 2;
}])
//////////////////////////////////////////
-- Sample test of func to<T>() -> [String] with cast error
type: Dictionary<String, Any>
value: ["key4": [1, 2, 3], "key2": true, "key3": ["a": 1, "b": 2], "key1": 1]
ERROR: Can not cast from Array<String> to Array<String>
//////////////////////////////////////////
-- Sample test of func to<T>() -> [Int]
type: Array<Int>
value: [1, 4, 5, 6]
Result: Optional([1, 4, 5, 6])
//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String]
type: Dictionary<String, String>
value: ["key1": "a", "key2": "b"]
Result: Optional(["key1": "a", "key2": "b"])
//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String]
type: String
value: {"key1": "a", "key2": "b"}
Result: Optional(["key1": "a", "key2": "b"])
//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String]
type: String
value: {"key1": "a", "key2": "b"}
Result: Optional(["key1": a, "key2": b])
//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String] with JSONSerialization error
type: String
value: {"key1": "a", "key2": "b"}
ERROR: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 21." UserInfo={NSDebugDescription=Invalid value around character 21.}
참고 URL : https://stackoverflow.com/questions/30480672/how-to-convert-a-json-string-to-a-dictionary
'Programing' 카테고리의 다른 글
Ruby에서 문자열을 작성할 때 삽 연산자 (<<)가 더하기 등호 (+ =)보다 선호되는 이유는 무엇입니까? (0) | 2020.06.12 |
---|---|
CSS를 사용하여 양식 필드를 비활성화하려면 어떻게합니까? (0) | 2020.06.12 |
Sublime Text 2 및 3에서 키보드로 사이드 바를 사용하는 방법은 무엇입니까? (0) | 2020.06.12 |
전체 iOS 앱에 기본 글꼴을 설정 하시겠습니까? (0) | 2020.06.12 |
프로그래밍 방식으로 UIScrollView를 스크롤 (0) | 2020.06.12 |