GO FURTHER, FASTER: Try the Swift Career Accelerator today! >>

Day 60 Challenge - JSON problems

Forums > 100 Days of SwiftUI

Hello everyone! I have been working on my code for a while trying to figure out an issue and cant find anything. I even checked it with other people I know who have compleated the course to see what solution they found. Despite my code being identical excpet for a few names it still wont work. Firstly I continously find that I am only getting about half the amount of data (I'm getting 5399 Bytes) as my friends. In addition my code wont return any data to my array of structs. When trying to debug my code I found an error message that says "Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unexpected character '<' around line 1, column 1." UserInfo={NSJSONSerializationErrorIndex=0, NSDebugDescription=Unexpected character '<' around line 1, column 1.}))". Since I am relativly new I dont know what that means. Please if you know anything let me know. My code will be attached below. Thank you for the help.

import SwiftUI

struct Response: Codable {
    var results: [User]
}

struct ContentView: View {
    @State private var users = [User]()
    var body: some View {
        NavigationStack {
            List(users, id: \.id) { user in
                HStack {
                    VStack {
                        Text("\(user.name)")
                            .font(.headline)
                        Text("\(user.age)")
                    }
                    Text("\(user.company)")
                }
            }
            .task {
                await loadData()
            }
            .navigationTitle("FriendFace")
            Text("\(users.count)")
        }
        .padding()
    }
    func loadData() async {
        guard let url = URL(string: "https://www.hackingwithswift.com/samples/friendface.json") else {
            print("Invalid URL!")
            return
        }

            // getting data from url
            // decoding data
            do {
                let (data, _) = try await URLSession.shared.data(from: url)
                print(data)
                let decoder = JSONDecoder()
                decoder.dateDecodingStrategy = .iso8601
                let decodedUsers = try decoder.decode([User].self, from: data)
                users = decodedUsers
            } catch DecodingError.dataCorrupted(let context) {
                print(context)
            } catch DecodingError.keyNotFound(let key, let context) {
                print("Key '\(key)' not found:", context.debugDescription)
                print("codingPath:", context.codingPath)
            } catch DecodingError.valueNotFound(let value, let context) {
                print("Value '\(value)' not found:", context.debugDescription)
                print("codingPath:", context.codingPath)
            } catch DecodingError.typeMismatch(let type, let context)  {
                print("Type '\(type)' mismatch:", context.debugDescription)
                print("codingPath:", context.codingPath)
            } catch {
                print("error: ", error)
            }
    }
}

#Preview {
    ContentView()
}
import Foundation
import SwiftUI

struct Friend: Codable, Identifiable {
    var id: String
    var name: String
}
struct User: Codable {
    var id: String?
    var isActive: Bool
    var name: String
    var age: Int
    var company: String
    var email: String
    var address: String
    var about: String
    var registered: Date
    var tags: [String]
    var friends: [Friend]
}

   

I have run the code (copy & paste to a new project) and get no errors.

Just of couple of things that would change.

  1. Why is var id: String? an optional (not needed)
  2. No need for Response (not used)
  3. No need to import SwiftUI to model.
  4. You can make the User to conform to Identifiable then need no need for , id: \.id in the List
  5. My prerference would be to nest the Friend inside User
struct User: Codable, Identifiable {
    struct Friend: Codable, Identifiable {
        var id: String
        var name: String
    }

    var id: String
    var isActive: Bool
    var name: String
    var age: Int
    var company: String
    var email: String
    var address: String
    var about: String
    var registered: Date
    var tags: [String]
    var friends: [Friend]
}

   

Also, this:

guard let url = URL(string: "https://www.hackingwithswift.com/samples/friendface.json") else {
    print("Invalid URL!")
    return
}

is completely unnecessary. The else clause will never happen because you are initializing URL with a static string that you know is a valid URL. Force unwrapping would be perfectly safe in a case like this:

let url = URL(string: "https://www.hackingwithswift.com/samples/friendface.json")!

   

Thank you for the suggustions. I tried both however neither of them ended up fixing my problem. I did however getting slightly more data (5424 Bytes) when I tried your sugguations but it still gives me the same error message and wont update my users array.

   

Is the above the whole of your code? Because, like Nigel I get no errors when I copy/paste your code into a new project. So I'm thinking there might be something else in your project interfering. You could also try copy/pasting just the code you have posted here into a new project and see what happens.

The error message is especially interesting.

Context(codingPath: [], debugDescription: "The given data was not valid JSON.", 
underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 
"Unexpected character '<' around line 1, column 1." UserInfo={
NSJSONSerializationErrorIndex=0, NSDebugDescription=Unexpected character 
'<' around line 1, column 1.}))

This indicates that whatever data you are passing to the JSONDecoder isn't actually JSON and begins with a < character. But looking at the raw data returned from the URL, there is no < present. So I'm not sure where that errant < is coming from.

   

I tried creating a new project and it worked just fine. I'm extreamly unclear on what the problem could have been because as far as I'm aware I did nothing diffrent in this project than my old one. Anyways thank you both for the help!

   

Hacking with Swift is sponsored by Alex.

SPONSORED Alex is the iOS & Mac developer’s ultimate AI assistant. It integrates with Xcode, offering a best-in-class Swift coding agent. Generate modern SwiftUI from images. Fast-apply suggestions from Claude 3.5 Sonnet, o3-mini, and DeepSeek R1. Autofix Swift 6 errors and warnings. And so much more. Start your 7-day free trial today!

Try for free!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.