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.

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.