7

我的脑袋要爆炸了 :) - 我一直试图从我的服务器获取一个 JSON 字符串到一个字典值,但我无法让它工作。

我正在尝试获取(从我的服务器 - 这是动态的,我希望我的应用能够在需要时从服务器中提取新数据):

{"1":"Location 1","2":"Location 2","3":"Location 3"}

使用 Swift 到 Xcode 中的这个字典:

  var labels = [

        1 : "Location 1",
        2 : "Location 2",
        3 : "Location 3"

    ]

这必须非常直截了当,但对于我的生活,我无法弄清楚......

这是我的 Swift - 我可以让它从服务器中提取信息,但我无法像我需要的那样将它放入字典中

var postEndpoint: String = "http://www.myserver.net/app/campus.php"

    Alamofire.request(.GET, postEndpoint)
        .responseJSON { (request, response, data, error) in
            if let anError = error
            {
                println("error")
                println(error)
            }
            else if let data: AnyObject = data 
            {
                 let post = JSON(data)
                 println(post)
            }
    }

这导致:

{
  "1" : "Location 1",
  "2" : "Location 2",
  "3" : "Location 3"
}

我使用它的最终结果是具有以下代码的 iBeacon 实现:

 let knownBeacons = beacons.filter{ $0.proximity != CLProximity.Unknown }
    if (knownBeacons.count > 0) {
        let closestBeacon = knownBeacons[0] as CLBeacon

        let locationID = post[closestBeacon.minor.integerValue]

        self.locationLabel.text = locationID
        self.view.backgroundColor = self.colors[closestBeacon.minor.integerValue]
    }

我得到的错误是 self.locationLabel.text = locationID 'JSON' is not convertible to 'String',当我使用静态变量标签字典时,我没有收到这个错误。我是否试图错误地从服务器获取数据?我究竟做错了什么???我认为具有未声明类型的 var 标签允许 Swift 弄清楚它需要什么,我如何从 JSON 部分做同样的事情?

4

4 回答 4

9

哦,你离得太近了!

您的问题是您的post字典是 a[String: String]而不是[Int: String]您认为的那样。您有几种方法可以修复它,但目前最简单的方法是执行以下操作:

let locationID = post[String(closestBeacon.minor.integerValue)]!

虽然这肯定会奏效,但更好的解决方案是将您post转换为[Int: String]类型化字典,就像您在responseJSON闭包中所期望的那样。这是如何工作的。

let json = JSON(data)
var post = [Int: String]()

for (key, object) in json {
    post[key.toInt()!] = object.stringValue
}

key如果orobject无法分别转换为Intor ,您可能希望增加一些安全性String,但我将把它留给您。

于 2015-03-05T16:25:48.230 回答
7

如果[String: String]对任何人来说都足够了,他/她可以尝试以下代码:

let responseString = "{\"1\":\"Location 1\",\"2\":\"Location 2\",\"3\":\"Location 3\"}"

if let dataFromString = responseString.data(using: String.Encoding.utf8, allowLossyConversion: false) {

    let json = JSON(data: dataFromString)

    var labels = json.dictionaryObject! as! [String: String]

    print(labels)
}

结果是: ["2": "Location 2", "1": "Location 1", "3": "Location 3"]

于 2016-10-03T08:35:18.673 回答
0

我通过反向工作解决了这个问题。我换了电话。我没有从服务器获取值字典,而是使用我已经从变量中获得的单个变量查询服务器

closestBeacon.minor.integerValue

然后从服务器获取我需要的字符串,这解决了我的问题。仍然有相同数量的服务器调用,因此没有增加额外的开销。有时你只需要跳出你投入的框框思考。

如果有人可以从另一个方向解决这个问题,我仍然很想知道它是如何工作的。

于 2015-03-04T23:41:37.593 回答
0

您还需要递归检查内部 JSON 使用以下函数转换为字典或数组

static func toDictionary(from: JSON) -> Any? {
    if from.type == .array {
        var array = [Any]()
        for _i in 0..<from.count {
            array.append(toDictionary(from: from[_i]) as Any)
        }
        return array
    } else if from.type == .dictionary {
        var dictionary = [String: Any]()
        for (key, value) in from {
            dictionary[key] = toDictionary(from: value)
        }
        return dictionary
    } else {
        return from.stringValue
    }
}
于 2021-03-24T18:39:33.013 回答