0

I'm using a decode function to get data from a json file in the project. There is no error when compelling but the xcode can't resume the canvas.

I'm using a decode function to get data from a json file in the project. There is no error when compelling but the xcode can't resume the canvas.

my data modle:

struct Movie1:Codable {
    var MOVIE_ID:String
    var NAME:String
    var ALIAS:String?
    var ACTORS:String?
    var COVER:String?
    var DIRECTORS:String?
    var DOUBAN_SCORE:Double?
    var DOUBAN_VOTES:Int?
    var GENRES:String?
    var IMDB_ID:String?
    var LANGUAGES:String?
    var MINS:Double?
    var OFFICIAL_SITE:String?
    var REGIONS:String?
    var RELEASE_DATE:String?
    var SLUG:String?
    var STORYLINE:String?
    var TAGS:String?
    var YEAR:String?
    var ACTOR_IDS:String?
    var DIRECTOR_IDS:String?
    
}


my json data:

 {"MOVIE_ID":"27021694",
"NAME":"耶尔玛",
"ALIAS":"",
"ACTORS":"比莉·派佩/布伦丹·考威尔/约翰·麦克米兰",
"COVER":"",
"DIRECTORS":"西蒙·斯通",
"DOUBAN_SCORE":"8.2",
"DOUBAN_VOTES":"187",
"GENRES":"剧情/戏曲",
"IMDB_ID":"tt6847880",
"LANGUAGES":"英语",
"MINS":"0",
"OFFICIAL_SITE":"http://ntlive.nationaltheatre.org.uk/productions/ntlout22-yerma",
"REGIONS":"英国",
"RELEASE_DATE":"2017/8/31",
"SLUG":"72FZ3FZ3b",
"STORYLINE":"A young woman is driven to the unthinkable by her desperate desire to have a child in Simon Stone’s radical production of Lorca’s achingly powerful masterpiece.",
"TAGS":"NTLive/女性/舞台剧/戏剧/英国/英国国家剧院现场/BilliePiper/NTL",
"YEAR":"2017",
"ACTOR_IDS":"比莉·派佩:1049548|Maureen Beattie:|布伦丹·考威尔:1022987|约翰·麦克米兰:1319678|Charlotte Randle:|Thalissa Teixeira:",
"DIRECTOR_IDS":"西蒙·斯通:1336274"}

my bundle function


import Foundation
extension Bundle{
    func decode<T:Codable>(filename:String) -> T {
        guard let url = Bundle.main.url(forResource: filename, withExtension: nil),
              let data = try? Data(contentsOf: url),
              let getResponse = try? JSONDecoder().decode(T.self, from: data)
              else { fatalError("no data")}
        return getResponse
    }
}

my view calling the function


struct homePage: View {
    
    let datas:[Movie1]=Bundle.main.decode(filename: "movieData1.json")
   
    
    var body: some View {
       
        
        HStack {
            Text("hello")
            Text(datas[1].ACTORS ?? "none")
            
        }
      
    }

}

my structure and json file image

Hannah
  • 69
  • 2
  • 6

1 Answers1

0

Your Movie1 structure is wrong. All your var in Movie1 should be String?. No Double, no Int

Here is the code that works for me:

struct Movie1:Codable {
    var MOVIE_ID:String
    var NAME:String
    var ALIAS:String?
    var ACTORS:String?
    var COVER:String?
    var DIRECTORS:String?
    var DOUBAN_SCORE:String?   // <-- here
    var DOUBAN_VOTES:String?  // <-- here
    var GENRES:String?
    var IMDB_ID:String?
    var LANGUAGES:String?
    var MINS:String? // <-- here
    var OFFICIAL_SITE:String?
    var REGIONS:String?
    var RELEASE_DATE:String?
    var SLUG:String?
    var STORYLINE:String?
    var TAGS:String?
    var YEAR:String?
    var ACTOR_IDS:String?
    var DIRECTOR_IDS:String?
}

    struct ContentView: View {
    @State var movieData: [Movie1] = []
    
    var body: some View {
        HStack {
            Text("hello")
            if !movieData.isEmpty {
                Text(movieData[0].ACTORS ?? "none")
            }
        }
        .onAppear {
            if let datas: [Movie1] = Bundle.main.decode(filename: "movieData1.json") {
                movieData = datas
            }
        }
    }
}

// do what @Paulw11 is suggesting, use do/try/catch with [T]?
extension Bundle{
    func decode<T:Codable>(filename:String) -> [T]? {
        guard let url = Bundle.main.url(forResource: filename, withExtension: nil),
              let data = try? Data(contentsOf: url),
              let getResponse = try? JSONDecoder().decode([T].self, from: data)
              else {
                  return nil
              }
        return getResponse
    }
}

data in your "movieData1.json" file (note the start "[" and end "]"):

[
{
"MOVIE_ID":"27021694",
"NAME":"耶尔玛",
"ALIAS":"",
"ACTORS":"比莉·派佩/布伦丹·考威尔/约翰·麦克米兰",
"COVER":"",
"DIRECTORS":"西蒙·斯通",
"DOUBAN_SCORE":"8.2",
"DOUBAN_VOTES":"187",
"GENRES":"剧情/戏曲",
"IMDB_ID":"tt6847880",
"LANGUAGES":"英语",
"MINS":"0",
"OFFICIAL_SITE":"http://ntlive.nationaltheatre.org.uk/productions/ntlout22-yerma",
"REGIONS":"英国",
"RELEASE_DATE":"2017/8/31",
"SLUG":"72FZ3FZ3b",
"STORYLINE":"A young woman is driven to the unthinkable by her desperate desire to have a child in Simon Stone’s radical production of Lorca’s achingly powerful masterpiece.",
"TAGS":"NTLive/女性/舞台剧/戏剧/英国/英国国家剧院现场/BilliePiper/NTL",
"YEAR":"2017",
"ACTOR_IDS":"比莉·派佩:1049548|Maureen Beattie:|布伦丹·考威尔:1022987|约翰·麦克米兰:1319678|Charlotte Randle:|Thalissa Teixeira:",
"DIRECTOR_IDS":"西蒙·斯通:1336274"
}
]

EDIT1: adding a new element.

Adding a new var is no problem at all. In your Movie1 struct:

struct Movie1:Codable {
    var isFavored:Bool   // <--- 
    var MOVIE_ID:String
    ....
}

and at the same time you need to modify your data to include this new element, like this:

[
{
"isFavored": true,
"MOVIE_ID":"27021694",
...
}
]

If you do not want your data to have a isFavored element, then give it an initial value in the Movie1 struct, and use CodingKeys to omit this isFavored That will remove the JSON coding and decoding of isFavored:

struct Movie1:Codable {
    var MOVIE_ID:String
    var NAME:String
    var ALIAS:String?
    var ACTORS:String?
    var COVER:String?
    var DIRECTORS:String?
    var DOUBAN_SCORE:String?   
    var DOUBAN_VOTES:String?  
    var GENRES:String?
    var IMDB_ID:String?
    var LANGUAGES:String?
    var MINS:String? 
    var OFFICIAL_SITE:String?
    var REGIONS:String?
    var RELEASE_DATE:String?
    var SLUG:String?
    var STORYLINE:String?
    var TAGS:String?
    var YEAR:String?
    var ACTOR_IDS:String?
    var DIRECTOR_IDS:String?
    
    var isFavored: Bool = false  // <--- here
    
    // note the missing isFavored
    enum CodingKeys: String, CodingKey {
        case MOVIE_ID, NAME,ALIAS,ACTORS,COVER,DIRECTORS,DOUBAN_SCORE
        case DOUBAN_VOTES,GENRES,IMDB_ID,LANGUAGES,MINS,OFFICIAL_SITE
        case REGIONS,RELEASE_DATE,SLUG,STORYLINE,TAGS,YEAR,ACTOR_IDS,DIRECTOR_IDS
    }
    
}