【问题标题】:How to make a correct local JSON file and correct model using swift如何使用 swift 制作正确的本地 JSON 文件和正确的模型
【发布时间】:2021-10-08 03:43:37
【问题描述】:

我有一个应用程序,我应该将本地 JSON 文件中的所有数据解析为我的标签歌曲。有一个 JSON 文件,一个数组,两个数组。例如,我需要在一个视图控制器中使用“循环数据”,在另一个视图控制器中使用“beatloopsdata”。当我运行它时,我遇到了一个错误,数据已损坏。有我的 JSON 文件:

{
"beatpackdata": [
    {
        "loopsdictionary": [
            {
                "nameOfLoop": "Away we go",
                "nameOfProducer": "Tubular Kingz",
                "countOfLoops": "28",
                "genreOfLoops": "Lo-fi Hip Hop"
            },
            {
                "nameOfLoop": "Test",
                "nameOfProducer": "Testing",
                "countOfLoops": "25",
                "genreOfLoops": "Lo-fi"
            }
        ]
    },
    {
        "beatloopsdictionary": [
            {
                "loopName" : "Alien",
                "instrument" :"Arp",
                "songName" : "alienarpjason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Big Brake",
                "instrument" :"Drums",
                "songName" : "BigBrake_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Bongo Beats",
                "instrument" :"Drums",
                "songName" : "BongoBeats_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Dreaming",
                "instrument" :"Keys",
                "songName" : "Dreaming_Keys_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Funky Groove",
                "instrument" :"Bass",
                "songName" : "FunkyGroove_Bass_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Futurist",
                "instrument" :"Arp",
                "songName" : "Futurist_Arp_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Hoping for change",
                "instrument" :"Arp",
                "songName" : "HopingForChange_Arp_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Manic",
                "instrument" :"Bass",
                "songName" : "Manic_Bass_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Sassy",
                "instrument" :"Drums",
                "songName" : "Sassy_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Serious",
                "instrument" :"Arp",
                "songName" : "Serious_Arp_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Stable Bricks",
                "instrument" :"Bass",
                "songName" : "StableBrick_Bass_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Thump",
                "instrument" :"Drums",
                "songName" : "Thump_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Tropic",
                "instrument" :"Drums",
                "songName" : "TropicVibe_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            }
        ]
    }
]

}

我创建了一个模型,但不确定一切是否正确。我已经尽力了,但这是我第三次使用本地 JSON 文件:

import Foundation

struct BeatData: Codable {
    let beatpackdata: [BeatPackData]
}

struct BeatPackData: Codable {
    let loopdata: [BeatLoopsData]
    let beatloopsdata: [LoopData]
}

struct LoopData: Codable {
    let loop_name: String
    let Instrument: String
    let song_name: String
    let producer: String
}

struct BeatLoopsData: Codable {
    let nameOfLoop: String
    let nameOfProducer: String
    let countOfLoops: String
    let genreOfLoops: String
}

解析函数:

private func parseJSON() {
        guard let path = Bundle.main.path(forResource: "beatpackdata", ofType: "json") else {
            return
        }
        let url = URL(fileURLWithPath: path)
        
        do {
            let jsonData = try Data(contentsOf: url)
            beatPackData = try JSONDecoder().decode(BeatData.self, from: jsonData)
            
            if let beatPackData = beatPackData {
                print(beatPackData)
            }
        }
        catch {
            print(error)
        }
        return
    }
}

【问题讨论】:

  • loopdata 的值显然是一个字典,所以[] 是错误的。将其替换为{}。我会删除所有多余的 ...data 出现,并用 lowerCamelCase 替换snake_case 键。
  • 据我了解,需要移动 JSON 文件,但我应该如何在我的模型中重命名它?
  • let loopdata: BeatLoopsData。你的命名真的很混乱。
  • 完成,我已将模型中的所有内容重命名,但如何修复 JSON 文件?
  • 正如我所说,在键 loopdata 的值中,用大括号替换方括号

标签: ios json swift xcode parsing


【解决方案1】:

我将json数据放入quicktype中,并在代码中使用了生成的数据结构。 所以这是工作代码。您可以告诉老师,您自己完成了学校作业。

import SwiftUI
import Foundation

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct Response: Codable {
    let beatpackdata: [Beatpackdatum]
}

struct Beatpackdatum: Codable {
    let loopsdictionary: [Loopsdictionary]?
    let beatloopsdictionary: [Beatloopsdictionary]?
}

struct Beatloopsdictionary: Codable {
    let loopName, instrument, songName: String
    let producer: String
}

struct Loopsdictionary: Codable {
    let nameOfLoop, nameOfProducer, countOfLoops, genreOfLoops: String
}

struct ContentView: View {
    var body: some View {
        Text("testing testing")
            .onAppear {
                parseJSON()
            }
    }
    
    func parseJSON() {
        guard let path = Bundle.main.path(forResource: "beatpackdata", ofType: "json") else {
            print("\n-------> bundle path error")
            return
        }
        let url = URL(fileURLWithPath: path)
        
        do {
            let jsonData = try Data(contentsOf: url)
            let response = try JSONDecoder().decode(Response.self, from: jsonData)
            print("\n-------> response: \(response)")
        }
        catch {
            print("\n====> error: \(error)" )
        }
        return
    }

}

编辑1:这是我使用的数据,我将这些数据放入我的xcode项目中名为“beatpackdata.json”的文件中。

{
"beatpackdata": [
    {
        "loopsdictionary": [
            {
                "nameOfLoop": "Away we go",
                "nameOfProducer": "Tubular Kingz",
                "countOfLoops": "28",
                "genreOfLoops": "Lo-fi Hip Hop"
            },
            {
                "nameOfLoop": "Test",
                "nameOfProducer": "Testing",
                "countOfLoops": "25",
                "genreOfLoops": "Lo-fi"
            }
        ]
    },
    {
        "beatloopsdictionary": [
            {
                "loopName" : "Alien",
                "instrument" :"Arp",
                "songName" : "alienarpjason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Big Brake",
                "instrument" :"Drums",
                "songName" : "BigBrake_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Bongo Beats",
                "instrument" :"Drums",
                "songName" : "BongoBeats_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Dreaming",
                "instrument" :"Keys",
                "songName" : "Dreaming_Keys_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Funky Groove",
                "instrument" :"Bass",
                "songName" : "FunkyGroove_Bass_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Futurist",
                "instrument" :"Arp",
                "songName" : "Futurist_Arp_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Hoping for change",
                "instrument" :"Arp",
                "songName" : "HopingForChange_Arp_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Manic",
                "instrument" :"Bass",
                "songName" : "Manic_Bass_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Sassy",
                "instrument" :"Drums",
                "songName" : "Sassy_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Serious",
                "instrument" :"Arp",
                "songName" : "Serious_Arp_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Stable Bricks",
                "instrument" :"Bass",
                "songName" : "StableBrick_Bass_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Thump",
                "instrument" :"Drums",
                "songName" : "Thump_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            },
            {
                "loopName" : "Tropic",
                "instrument" :"Drums",
                "songName" : "TropicVibe_Drums_Jason.mp3",
                "producer" : "Stefan Guy"
            }
        ]
    }
]
}

【讨论】:

  • 你能解释一下哪个部分不起作用,我会试着调查一下。你用的是什么系统?
  • 你能检查一下我的json文件,也许有问题?因为我已经放了你所有的代码,但仍然没有从 json 中获取数据。因为我需要将数据放入项目中的标签中。
  • 用我使用的数据更新了我的答案。对我来说效果很好。
  • 我已经用你的代码和数据加载器和有趣的 parseJson 创建了一个模型文件。现在我在视图控制器中输入: let data = DataLoader().beatData 然后尝试这样做: cell.loopNameLabel.text = data[indexPath.row].beatpackdata.beatloopsdictionary[indexPath.row].loopName
  • 我的回答有用吗?你收到打印的回复了吗?如果没有,请告诉我什么不起作用。
【解决方案2】:

现在你的乔恩看起来像

{
  "beatpackdata": {
    "loopsdictionary": [
      {
        "nameOfLoop": "Away we go",
        "nameOfProducer": "Tubular Kingz",
        "countOfLoops": "28",
        "genreOfLoops": "Lo-fi Hip Hop"
      },
      {
        "nameOfLoop": "Test",
        "nameOfProducer": "Testing",
        "countOfLoops": "25",
        "genreOfLoops": "Lo-fi"
      }
    ],
    "beatloopsdictionary": [
      {
        "loopName": "Alien",
        "instrument": "Arp",
        "songName": "alienarpjason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Big Brake",
        "instrument": "Drums",
        "songName": "BigBrake_Drums_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Bongo Beats",
        "instrument": "Drums",
        "songName": "BongoBeats_Drums_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Dreaming",
        "instrument": "Keys",
        "songName": "Dreaming_Keys_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Funky Groove",
        "instrument": "Bass",
        "songName": "FunkyGroove_Bass_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Futurist",
        "instrument": "Arp",
        "songName": "Futurist_Arp_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Hoping for change",
        "instrument": "Arp",
        "songName": "HopingForChange_Arp_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Manic",
        "instrument": "Bass",
        "songName": "Manic_Bass_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Sassy",
        "instrument": "Drums",
        "songName": "Sassy_Drums_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Serious",
        "instrument": "Arp",
        "songName": "Serious_Arp_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Stable Bricks",
        "instrument": "Bass",
        "songName": "StableBrick_Bass_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Thump",
        "instrument": "Drums",
        "songName": "Thump_Drums_Jason.mp3",
        "producer": "Stefan Guy"
      },
      {
        "loopName": "Tropic",
        "instrument": "Drums",
        "songName": "TropicVibe_Drums_Jason.mp3",
        "producer": "Stefan Guy"
      }
    ],
    }
  }

模型文件

struct BeatData: Codable {
    let loopsdictionary: [LoopData]
    let beatloopsdictionary: [BeatLoopsData]
    
    static func objBeatData(fromDict : NSDictionary) -> BeatData?{
        do {
            let decoder = JSONDecoder()
            let data = fromDict.toData(jsonPath: "beatpackdata")
             return try decoder.decode(BeatData.self, from:data)
        } catch let error {
            print(error.localizedDescription)
            return nil
        }
    }
}

struct LoopData: Codable {
    let nameOfLoop: String
    let nameOfProducer: String
    let countOfLoops: String
    let genreOfLoops: String
}

struct BeatLoopsData: Codable {
    let loopName: String
    let instrument: String
    let songName: String
    let producer: String
}

public extension NSDictionary {
   
    func toData(jsonPath : String = "data") -> Data{
        let dataDict = self.value(forKeyPath: jsonPath)
        do{
        let dataJson = try JSONSerialization.data(withJSONObject: dataDict, options: .prettyPrinted)
        return dataJson
        }catch let error{
           print(error.localizedDescription)
        }
       return Data()
    }
}

如何使用

func beatpackdataJsonFile() -> NSDictionary?{
    var tempDict : NSDictionary?
    let path = Bundle.main.path(forResource: "beatpackdata", ofType: "json")
    let jsonData = NSData(contentsOfMappedFile: path!)
    do{
        tempDict = try JSONSerialization.jsonObject(with: jsonData! as Data, options: JSONSerialization.ReadingOptions.allowFragments) as? NSDictionary
        
    }catch let error{
        print("Json Serialization : \(error.localizedDescription)")
         }
    return tempDict
}

//Parse Data
if let dictSuccess = beatpackdataJsonFile() {
    let data = BeatData.objBeatData(fromDict: dictSuccess)
}

【讨论】:

  • 你从哪里得到这个? “toData”因为我有一个错误:“NSDictionary”类型的值没有成员“toData”
  • 嘿,我已经编辑了答案,现在你可以使用它并更新 NSDictionary has no member "toData" 的问题。
  • 看起来不错,会试试看!也许您知道如何将这些数据正确传递给标签?
  • 你必须像 let objData: BeatData 一样创建一个 Model 的实例?然后在你想要的地方使用,比如 objData。循环字典[索引]。 nameOfLoop.
  • 好的,你知道如何解决错误-“索引超出范围”吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-31
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
  • 1970-01-01
相关资源
最近更新 更多