需要从打开的API获取国家名称

时间:2019-01-10 12:50:17

标签: ios arrays json swift xcode

需要通过以下api调用获取国家/地区名称:

https://restcountries.eu/rest/v1/all

我的代码:

df <- data.frame(sentID = c("A", "A", "B", "B", "B"),
                  partner = c("B", "B", "C", "C", "A"))

df
#>   sentID partner
#> 1      A       B
#> 2      A       B
#> 3      B       C
#> 4      B       C
#> 5      B       A

library(dplyr)

df %>% group_by(sentID) %>% filter(length(unique(partner)) > 1)
#> # A tibble: 3 x 2
#> # Groups:   sentID [1]
#>   sentID partner
#>   <fctr>  <fctr>
#> 1      B       C
#> 2      B       C
#> 3      B       A

在这里出现错误:var arrRes = [] func getCountry() { let Url: String = "https://restcountries.eu/rest/v1/all" Alamofire.request(Url).responseJSON { (responseData) -> Void in do { if let datas = responseData.result.value { let data = (datas as AnyObject).data(using: .utf8)! let parseData = try JSONSerialization.jsonObject(with: data, options: []) for country in parseData { if let name = country["name"] as? String { print(name) } } } } catch let error as NSError { print(error) } } } 下面的'Any' is not convertible to 'AnyObject' ..

我只需要获取名称并追加到我的数组中即可。实现该目标的任何其他想法或解决方案?

6 个答案:

答案 0 :(得分:2)

以此代替do catch语句块。

do {
    if let countries = responseData.result.value as? [[String: Any]] {
        for country in countries {
            if let name = country["name"] as? String {
                print(name)
            }
        }
    }
}
catch let error as NSError {
    print(error)
}

答案 1 :(得分:2)

尝试一下,对我来说很好用。

let urlStr = "https://restcountries.eu/rest/v1/all"
let setFinalURl = urlStr.addingPercentEncoding (withAllowedCharacters: .urlQueryAllowed)!
var request = URLRequest(url: URL(string: setFinalURl)!)
request.httpMethod = HTTPMethod.get.rawValue

Alamofire.request(request).responseJSON
    { (responseObject) -> Void in

        if responseObject.result.isSuccess
        {
            print(responseObject.result.value!)

            if "\(String(describing: responseObject.response!.statusCode))" == "200"
            {
                let result = responseObject.result.value! as AnyObject

                let countryNamesArr = result.value(forKey: "name") as! NSArray
                print(countryNamesArr)
            }
            else
            {
                // handle error
            }
        }
        if responseObject.result.isFailure
        {
            let error : Error = responseObject.result.error!
            print(error.localizedDescription)
        }
}

答案 2 :(得分:1)

只需删除此行

let data = (datas as AnyObject).data(using: .utf8)!

在可选绑定中,只需分配data,因为value的类型为Data?,因此从可选绑定中,您将获得Data

if let data = responseData.result.value

然后别忘了将json向下转换为数组[String:Any]

...jsonObject(with: data, options: []) as? [[String:Any]]

...然后不要忘记解开该数组,否则您将无法在每个循环中对其进行迭代


还要注意,由于有Codable,因此您应使用它而不是JSONSerialization。然后,您可以使用JSONDecoder将自己的json解码为符合协议Decodable的自己的模型。

答案 3 :(得分:1)

您可以尝试

struct Root: Codable {
    let name: String  
}

func getCountry() {

    let urlStr = "https://restcountries.eu/rest/v1/all"
    Alamofire.request(urlStr).responseData { (data) in

        do {
             guard let data = data.data else { return }
             let res  = try JSONDecoder().decode([Root].self,from:data)
             print(res)
        }
        catch {
            print(error)
        }
    }
}

答案 4 :(得分:0)

作为一种简单的方法,您可以像这样实现getCountry()

func getCountry() {
    let url: String = "https://restcountries.eu/rest/v1/all"
    Alamofire.request(url).responseJSON { response in
        if let resultValue = response.result.value, let countryObjects = resultValue as? [[String: Any]] {
            let countryNames = countryObjects.compactMap { $0["name"] as? String }
            print(countryNames)
        }
    }
}

目前,无需使用JSONSerialization来获取国家/地区名称;根据API响应,responseData.result.value是国家(词典)的数组,每个字典都有一个“名称”值,您应该做的是将响应映射到一个字符串数组。 countryNames应该包含您要查找的内容。

使用compactMap的好处是避免使用任何nil名称,因此countryNames应该是[String]而不是[String?]


但是,如果您认为需要将整个响应对象转换为自定义对象(而不是字典),则强烈建议您遵循使用Decodable的方法。

答案 5 :(得分:0)

我的代码,对我来说很好用。

雨燕5

 public func getCountry(completion: @escaping ([String]) -> ()) {
            let url: String = "https://restcountries.eu/rest/v1/all"
            AF.request(url).responseJSON { (responseData) -> Void in
                do {
                    guard let data = responseData.data else { return }
                    let res  = try JSONDecoder().decode([CountryName].self,from:data)
                    completion(self.getCountryName(countryName: res))
                }
                catch {
                    print(error)
                }
            }
        }

 struct CountryName: Codable {
   let name: String
 }

 private func getCountryName(countryName:[CountryName]) -> [String]{
      var country:[String]  = []
      for index in 0...countryName.count - 1{
           country.append(countryName[index].name)
      }
    return country
 }