BundleのmyFile.jsonからJSONファイルを読み込み、いくつかの要素を変更してJSONファイルとしてドキュメントディレクトリに保存しようとしています。私はそれがデータを持続させる簡単な方法だと思った。その後、私はドキュメントディレクトリに読み書きするつもりです。次のコードは、私がやったことを示しており、ひどくコメントされています。予想されるJSONコンバージョンがJSON仕様と一致しないため、いくつかの重要なステップが欠落しているようです。私は遊び場でどのようにテストしたかについての提案を受けています。コードは、問題はあなたがエンコードされたJSONのではなく、ファイルに辞書オブジェクトを保存することである予期しないJSONから辞書への変換とJSONへ戻る
Convert Dictionary to JSON in Swift
import UIKit
/* Trying to read a json file from myFile.json in Bundle, modify some elemnts and store it
in the document directory as a json file. Subsequently, intent to read and write to document directory
myFile.json consistes of
{
"record": {"id": "A1234", "customer": "Customer-1"}
}
*/
typealias MyRecord = [String: AnyObject]
var json:MyRecord!
let fileName = "myFile"
var dictionary = MyRecord()
func loadJsonFromBundle (forFilename fileName: String) -> MyRecord {
if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
if let data = NSData(contentsOf: url) {
do {
let dictionary = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as? [String:Any]
print("dictionary = \(dictionary!)")
/* displays
dictionary = ["record": {
customer = "Customer-1";
id = A1234;
}]
*/
return dictionary! as MyRecord
} catch {
print("Error!! Unable to parse \(fileName).json")
}
}
print("Error!! Unable to load \(fileName).json")
}
return [:]
}
func loadJsonFromDocument (forFilename fileName: String) -> MyRecord {
let docDirectory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
if let url = docDirectory?.appendingPathComponent(fileName).appendingPathExtension("json") {
if let data = NSData(contentsOf: url) {
do {
let dictionary = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as? [String:Any]
print("dictionary = \(dictionary!)")
return dictionary! as MyRecord
} catch {
print("Error!! Unable to parse \(fileName).json")
}
}
print("Error!! Unable to load \(fileName).json")
}
return [:]
}
func saveJsonToFile (_ fileName:String, outString: String) -> URL {
let docDirectory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
if let fileURL = docDirectory?.appendingPathComponent(fileName).appendingPathExtension("json") {
print("fileURL = \(fileURL)")
// Write to a file on disk
do {
try outString.write(to: fileURL, atomically: true, encoding: .utf8)
} catch {
print("Failed writing to URL: \(fileURL), Error: " + error.localizedDescription)
}
return fileURL
}
return URL(string: "")!
}
let sq = "\""
func q(_ x:String) -> String {
return "\(sq)\(x)\(sq)"
}
dictionary = loadJsonFromBundle (forFilename: fileName)
var a = dictionary["record"] as? [String:String]
a?["customer"] = "newName"
var dict = MyRecord()
dict["record"] = a as AnyObject?
print(dict)
/* prints:
["record": {
customer = newName;
id = A1234;
}]
*/
// https://stackoverflow.com/questions/29625133/convert-dictionary-to-json-in-swift/29628000#29628000
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
// here "jsonData" is the dictionary encoded in JSON data
let decoded = try JSONSerialization.jsonObject(with: jsonData, options: [])
// here "decoded" is of type `Any`, decoded from JSON data
// you can now cast it with the right type
if let dictFromJSON = decoded as? [String:Any] {
// need to save dictFromJson to a file in document directory
// saveJsonToFile is expecting a String for the json argument
// I converted dictFromJson to a string so I can save it
var outString = String(describing: dictFromJSON)
print("outString = \(outString)")
/* Notice that the internal structure is not quoted and there are semi-colons
outString = ["record": {
customer = newName;
id = A1234;
}]
*/
outString = outString.replacingOccurrences(of: "[", with: "{")
outString = outString.replacingOccurrences(of: "]", with: "}")
let url = saveJsonToFile("newFile", outString: String(describing: outString))
print(url)
/* Resulting File looks like this:
{"record": {
customer = newName;
id = A1234;
}}
Question: Why were the braces swapped with brackets. The internal elements
were not quoted.
*/
// Will try to read back the json string from document directory
dictionary = loadJsonFromDocument(forFilename: fileName)
// results in ERROR (Unable to load myFile.json
a = dictionary["record"] as? [String:String]
a?["customer"] = "newName"
dict = MyRecord()
dict["record"] = a as AnyObject?
print(dict)
}
} catch {
print(error.localizedDescription)
}
[String:AnyObject]ではなく[String:Any]を試してください。 –