Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SWIFT:在数组中存储JSON数据_Json_Swift_Parsing - Fatal编程技术网

SWIFT:在数组中存储JSON数据

SWIFT:在数组中存储JSON数据,json,swift,parsing,Json,Swift,Parsing,我有以下JSON格式的数据: {"contacts":[{"name":"Bob"},{"name":"Greg"},{"name":"Sally"},{"name":"Will"},{"name":"George"}, {"name":"Charlie"},{"name":"Alice"},{"name":"Albert"},{"name":"Alfred"},{"name":"Bart"}, {"name":"Dan"},{"name":"Dave"},{"name":"Eddie"},{

我有以下JSON格式的数据:

{"contacts":[{"name":"Bob"},{"name":"Greg"},{"name":"Sally"},{"name":"Will"},{"name":"George"},
{"name":"Charlie"},{"name":"Alice"},{"name":"Albert"},{"name":"Alfred"},{"name":"Bart"}, 
{"name":"Dan"},{"name":"Dave"},{"name":"Eddie"},{"name":"Frank"},{"name":"Ralph"},{"name":"Tammy"}, 
{"name":"Tom"},{"name":"James"},{"name":"John"},{"name":"Quincy"},{"name":"Peter"},{"name":"Richard"}, 
{"name":"Zachary"},{"name":"Zbiginew"},{"name":"Tentacool"},{"name":"Tentacruel"},{"name":"Metapod"}, 
{"name":"Meowth"}]}
JSON存储在某个URL中,我想收集信息并将其放入一个数组中,理想情况下,这个数组看起来像
[Bob,Greg,Sally,Will…]

现在我有了密码:

let jsonLocation = "http://raw.myjsondatalocation.com/contact.json"
        guard let url = URL(string: jsonLocation) else {
            return
        }

        URLSession.shared.dataTask(with: url){ (data,response,error) in
            guard let data = data else { return }
            do{
                let decoder = JSONDecoder()
                let ListOfNames = try decoder.decode(Contact.self, from:data).contacts
                // print(myListOfContacts)
                print(ListOfNames[0].name)
            }
            catch let jsonErr{
                print("Error!",jsonErr)
            }
            }.resume()
我使用Codable来解析JSON。这似乎工作得很好,因为它返回一个项目数组,其形式为
[[ContactList.Contact.PersonalInfo(name:“Bob”)…
,当我调用
print(ListOfNames[0].name)
时,它会适当地返回“Bob”,但如果我将其放在URLSession之外,它会说它无法解析

名称数组稍后将放入TableView。我真的不知道如何解决此问题。有人能帮我一下吗?

使用上述网站,粘贴您的json响应。。。 此网站将根据您希望如何处理它,为您提供类或结构代码

结果如下

// MARK: - Contacts
class Contacts: Codable {
    let contacts: [Contact]

    init(contacts: [Contact]) {
        self.contacts = contacts
    }
}

// MARK: - Contact
class Contact: Codable {
    let name: String

    init(name: String) {
        self.name = name
    }
}
使用它,您可以将数据存储到这个类数组中

创建一个数组

var testArr = [Contacts]()
在您发布的代码中

    let jsonLocation = "http://raw.myjsondatalocation.com/contact.json"
    guard let url = URL(string: jsonLocation) else {
        return
    }

    URLSession.shared.dataTask(with: url){ (data,response,error) in
        guard let data = data else { return }
        do{
            let decoder = JSONDecoder()
            let ListOfNames = try decoder.decode(Contact.self, from:data).contacts
            // print(myListOfContacts)
            print(ListOfNames[0].name)
        }
        catch let jsonErr{
            print("Error!",jsonErr)
        }
        }.resume()
您现在需要正确地附加到类数组中。在下面的代码块中可以看到更改

URLSession.shared.dataTask(with: url){ (data,response,error) in
                guard let data = data else { return }
            do{
                let decoder = JSONDecoder()
                let ListOfNames = try decoder.decode(Contact.self, from:data).contacts
                // print(myListOfContacts)
                for x in ListOfNames{
                    self.testArr.append(Contacts(contacts: x))
                }
                dump(self.testArr)
            }
编辑--

不确定这是否有效,但值得一试

URLSession.shared.dataTask(with: url){ (data,response,error) in
                guard let data = data else { return }
            do{
                let decoder = JSONDecoder()
                let jsonData = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
                // print(myListOfContacts)
                for x in jsonData{
                    self.testArr.append(x)
                }
                dump(self.testArr)
            }
我的想法是,获取原始json,循环遍历它,并将原始数据附加到标准字符串数组中

一旦将数据存储在数组中,就可以像通常那样向类数组进行追加

for x in self.testArr{
    self.classArray.append(Contacts(contacts: x))
}

在请求外部打印时,您将得到空值,因为请求是一个异步函数,并且数组只有在从网络接收到数据后才会填充。您需要将请求调用移动到一个函数中,并使用完成块调用它,该块将提供
[Contact]
的数组。以下是一个示例:

func getContacts(completion: @escaping (Contact?) -> Void) {
    let jsonLocation = "http://raw.myjsondatalocation.com/contact.json"
    guard let url = URL(string: jsonLocation) else {
        completion(nil)
        return
    }

    URLSession.shared.dataTask(with: url) { (data,response,error) in
        guard let data = data else { return }
        do{
            let decoder = JSONDecoder()
            let contact = try decoder.decode(Contact.self, from:data)
            completion(contact)
        }
        catch let jsonErr{
            print("Error!",jsonErr)
            completion(nil)
        }
    }.resume()
}
这样称呼它:

getContacts { contact in
    print(contact?.contacts[0].name)
}

假设您正确解码了数据,您可以使用map实现所需的功能。请确保listOfNames变量不以大写字母开头,因为它是一个变量

  • 声明一个[Contact]类型的变量,该变量保存名为arrayOfContactNames的名称数组:

    var arrayOfContactNames:[联系人]=[]

  • 数据解码后,映射名称列表并分配给arrayOfContactNames,如果需要,调用self.tableView.reloadData():


  • listOfNames
    属性声明为
    URLSession
    块外部的
    var
    属性。然后在块内部使用
    listOfNames=try decoder…
    。请注意,按照Swift约定,属性名称以小写开头。不要将结构数组映射到字符串数组。使用
    PersonalInfo
    作为数据源数组。也许你想在将来添加更多个人信息。这回答了你的问题吗?嗨,谢谢你的建议。但是我们必须使用他们给我们的编码表。我尝试在ListOfNames{print(x.name)self.testArr.append(String(x.name))}中使用x我们需要使用他们提供的可编码文件。我们不能使用我们自己的。我声明了一个
    var testArr=[String]()
    ,然后尝试添加以下内容:对于ListOfNames中的x{print(x.name)self.testArr.append(String(x.name))}但它仍然为我返回一个空数组。@PtrickMahny好的,你们能共享那个文件吗?我想不会。这对解决这个问题很有帮助。
        let jsonLocation = "http://raw.myjsondatalocation.com/contact.json"
                guard let url = URL(string: jsonLocation) else {
                    return
                }
    
                URLSession.shared.dataTask(with: url){ (data,response,error) in
                    guard let data = data else { return }
                    do{
                        let decoder = JSONDecoder()
                        let listOfNames = try decoder.decode(Contact.self, from:data).contacts
                        // print(myListOfContacts)
                        print(listOfNames[0].name)
                        arrayOfContactNames = listOfNames.map { $0.name } 
                        // Once your data obtained, reload your tableview on the main thread to populate it
                        DispatchQueue.main.async {
                           self.tableView.reloadData()
                        }
                    }
                    catch let jsonErr{
                        print("Error!",jsonErr)
                    }
                    }.resume()