SwiftプロジェクトでStringをDictionary json形式に変換する関数を1つ作成したいのですが、エラーが1つ発生しました。
式の型を変換できません(@lvalue NSData、オプション: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)
元の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]? { ... }
Eric Dの答えを 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
}
スイフト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
から)を処理する必要があります。したがって、次のいずれかの方法で問題を解決できます。
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.}
}
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: [:]
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.justに変換するコードを見つけ、拡張子 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
}
}
}
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.}