Swift 4 Codableプロトコルを介してエンコードされたJSONオブジェクトをファイルに書き込むにはどうすればよいですか?以前はSwift 4 _JSONSerialization.writeJSONObject
_を使用しましたが_JSONSerialization.isValidJSONObject
_は、作成されたデータ(または文字列)に対してfalse
を返すようになりました。例:
_import Foundation
class Shark : Codable
{
var name:String = ""
var carnivorous:Bool = true
var numOfTeeth:Int = 0
var hobbies:[String] = []
}
class JSON
{
class func encode<T:Encodable>(_ obj:T) -> String?
{
if let encodedData = try? JSONEncoder().encode(obj)
{
return String(data: encodedData, encoding: .utf8)
}
return nil
}
class func writeToStream(data:Any, path:String) -> Bool
{
var success = false
if JSONSerialization.isValidJSONObject(data)
{
if let stream = OutputStream(toFileAtPath: "\(path)", append: false)
{
stream.open()
var error:NSError?
JSONSerialization.writeJSONObject(data, to: stream, options: [], error: &error)
stream.close()
if let error = error
{
print("Failed to write JSON data: \(error.localizedDescription)")
success = false
}
}
else
{
print("Could not open JSON file stream at \(path).")
success = false
}
}
else
{
print("Data is not a valid format for JSON serialization: \(data)")
success = false
}
return success
}
}
let shark = Shark()
shark.name = "Nancy"
shark.carnivorous = true
shark.numOfTeeth = 48
shark.hobbies = ["Dancing", "Swiming", "Eating people"]
if let jsonString = JSON.encode(shark)
{
let success = JSON.writeToStream(data: jsonString.data(using: .utf8), path: "\(NSHomeDirectory())/Documents")
}
_
これらの形式は両方ともJSONSerialization.isValidJSONObject()
には無効です。
_JSON.writeToStream(data: jsonString, path: "\(NSHomeDirectory())/Documents")
JSON.writeToStream(data: jsonString.data(using: .utf8), path: "\(NSHomeDirectory())/Documents")
_
データはJSONシリアル化の有効な形式ではありません:
{"numOfTeeth":48、 "hobbies":["Dancing"、 "Swimming"、 "Eating people"]、 "name": "Nancy"、 "carnivorous":true}
データはJSONシリアル化の有効な形式ではありません:オプション(99バイト)
JSON検証に合格してからファイルに書き込むにはどうすればよいですか?
JSONSerialization。 _JSONSerialization.isValidJSONObject
_の使用法が間違っています。ドキュメントとして 明確に述べています :
JSONに変換できるFoundationオブジェクトには、次のプロパティが必要です。
•最上位のオブジェクトはNSArray
またはNSDictionary
です。
•すべてのオブジェクトは、NSString
、NSNumber
、NSArray
、NSDictionary
、またはNSNull
のインスタンスです。
•すべての辞書キーはNSString
のインスタンスです。
そのため、Data
またはString
タイプはまったく有効ではありません;)
エンコードされたデータの書き込み。生成されたData
を実際に書き込むには、代わりに対応する Data.write(to: URL)
メソッドを使用します。例えば:
_if let encodedData = try? JSONEncoder().encode(obj) {
let path = "/path/to/obj.json"
let pathAsURL = URL(fileURLWithPath: path)
do {
try encodedData!.write(to: pathAsURL)
}
catch {
print("Failed to write JSON data: \(error.localizedDescription)")
}
}
_
JSONデータが標準のJSONEncoder
によって生成されている限り、追加の検証は実際には必要ありません;)