1

I am currently working on a school project where I need to be able to read, write and view information from a JSON file. For my assignment, I am attempting to build an app that is a dictionary where you can add your own words, definitions, etc.

I have been stuck on trying to write the new data to the JSON file without overwriting the old. I also have an error on the last line that I am confused about.

Here is the code that I have so far.

    func fileUrl() -> URL {
    let documentURL = try!
        FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    return documentURL.appendingPathComponent("data.json")
}

@IBAction func addWords(_ sender: UIButton) {
    if let oldWords:[[String : String]] = getJsonData() as [[String:String]]? {
        if let oldJson = try? JSONSerialization.data(withJSONObject: oldWords, options: []) {
            // Add old words to JSON file
        }
    }
    let data: [String:String] = [
        "Name": nameField.text ?? "N/A",
        "Part of Speech": posField.text ?? "N/A",
        "Definition": defView.text ?? "N/A"

    ]
    let url = fileUrl()
    if let jsonData = try? JSONSerialization.data(withJSONObject: data, options: []) {
        // Append data into JSON file
        print(data)
        nameField.text = ""
        defView.text = ""
        posField.text = ""
    } else {
        print("Failed to save")
    }
}

func getJsonData() -> [[String:String]]? {
    let url = fileUrl()
    let responseData: Data? = try! Data(contentsOf: url)
    if let responseData = responseData {
        let json: String? = try? JSONSerialization.jsonObject(with: responseData, options: []) as? String
        if let dictionary: [[String:String]]? = json as? [[String:String]]? {
            return dictionary
        }
    }
} // Missing return in a function expected to return '[[String : String]]?' error
@IBAction func loadData(_ sender: UIButton) {
    let url = fileUrl()
    let responseData: Data? = try! Data(contentsOf: url)
    if let responseData = responseData {
        let json: Any? = try? JSONSerialization.jsonObject(with: responseData, options: [])
        if let json = json {
            let dictionary: [String: Any]? = json as? [String: Any]
            if let dictionary = dictionary {
                for names in dictionary {
                    let name: String = dictionary["Name"] as! String
                    let definition: String = dictionary["Definition"] as! String
                    let pos: String = dictionary["Part of Speech"] as! String
                    print(name, definition, pos)
                    textView.text = ("Name: \(name) (\(pos))\n Definition: \(definition)\n ")
                }
            }
        }
    }
}

I have been researching a way to add the JSON data but maybe I have been staring at the code so long that I am missing an easy fix.

Vshastra
  • 63
  • 7

1 Answers1

2

There is no native way in swift, nor with a third party library to append json objects to a file.

What you need to do is, when you call getJsonData -- you save the whole contents of that JSON into a variable and append from there. I recommend looking at Daniel's answer for an easy extension for appending JSON together. Let me know if you need any more help!

Regarding your error on the last line - It is good practice to never force un-wrap variables. It's hard to tell given we can't see the JSON tree; but make sure you are accessing the correct spot. print(dictionary) your dictionary and try some debugging and/or create validation for your array.

Community
  • 1
  • 1
Harry J
  • 1,842
  • 3
  • 12
  • 28