2

I have a structure within my swift class that shall describe a card and I want to have it as a JSON which shall be written out to a file on save.

My problem is, I get an error during the NSJSONSerialization stating that top level typ is wrong. This is the exact error:

NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write

Below is my struct and my toJSON() function, which gives the named error.

struct CardStructure {
   var UUID: NSUUID = NSUUID.init()
   var Chapter: Int = 0
   var Card: Int = 0
   var CorrectAnswers: Int = 0
   var WrongAnswers: Int = 0
   var Unknown: Int = 0
   var LastAsked: String = ""
   var Question: String = ""
   var Answer: String = ""
   var Hint: String = ""
   var Tags: [String] = []
   var Links: [String] = []
   var Picture: String = ""

    func toJSON() -> String? {
        let props = ["UUID": String(describing: UUID),
                     "Chapter": Chapter,
                     "Card": Card,
                     "Question": Question,
                     "Answer": Answer,
                     "Hint": Hint,
                     "Tags": Tags,
                     "Links": Links,
                     "Picture": Picture
                     ] as [String : Any]
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: props,
                                                                      options: .prettyPrinted)
            return String(data: jsonData, encoding: String.Encoding.utf8)
        } catch let error {
            print("error converting to json: \(error)")
            return nil
        }
    }
}

I'm fairly new to swift and have no clue why this error is caused. Can anyone help me??? I tried to understand tips in other posts regarding this error, but so far, my knowledge on swift is too low, to adapt solutions provided, like this one in the link:

invalid-top-level-type-in-json-write

Best regards,

Chris

Community
  • 1
  • 1
siliconchris
  • 613
  • 2
  • 9
  • 22
  • 1
    `print(CardStructure().toJSON())` runs without problems for me. Can you post a (minimal) *self-contained* example demonstrating the problem? – Martin R Oct 31 '16 at 10:59
  • You should replace `String(describing: UUID)` by `UUID.uuidString` – Eric Aya Oct 31 '16 at 11:11

1 Answers1

-1

I originally missed that the question was about serializing the properties of CardStructure instead of an instance of CardStrucure itself ... Leaving the original answer below since the comments refer to it ...

I just tried the above code with the following two lines in both a macOS and an iOS Playground. The code ran fine without any issues. Which version of Xcode, Swift etc. are you using?

let cs = CardStructure()
let str = cs.toJSON()

-- Original answer

If you refer to the JSONSerialization documentation here:

https://developer.apple.com/reference/foundation/jsonserialization

You will notice that it mentions the following:

An object that may be converted to JSON must have the following properties:

The top level object is an NSArray or NSDictionary.

All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.

All dictionary keys are instances of NSString.

Numbers are not NaN or infinity.

Since your top-level object, CardStructure, is not an NSArray or NSDictionary, the error would seem to be correct.

Fahim
  • 3,466
  • 1
  • 12
  • 18
  • 1
    Yes but OP is serializing the `props` dictionary, not the struct. – Eric Aya Oct 31 '16 at 10:56
  • Ah, missed that, sorry :) Actually, I just tested the code in a macOS Playground and it compiles and runs fine - no errors on serialization ... – Fahim Oct 31 '16 at 10:57