如何从API获取信息?斯威夫特4

时间:2019-01-02 14:23:37

标签: swift

我尝试从此API获取个人信息:

https://power.larc.nasa.gov/cgi-bin/v1/DataAccess.py?request=execute&identifier=SinglePoint&parameters=DNR,DIFF,ALLSKY_SFC_SW_DWN&userCommunity=SSE&tempAverage=CLIMATOLOGY&outputList=ASCII&lat=40.39&lon=-3.74&user=anonymous

到目前为止,我已经能够在控制台中打印API结果。我想从中提取经度和纬度(即使我可以从CoreLocation库中获取这2个数据,我仍然想从API中获取它们)以及properties-> parameter部分(ALLSKY_SFC_SW_DWN,DIFF和DNR)。提取此信息是我遇到的困难。

我已经尝试获取API的各个元素,但是我只能获取完整的API内容,而不能获取各个API的内容(以后我希望将其放入数组中)。我尝试使用这种表示法:

if let features = ((NASAjsonResult["features"] as? NSArray)?[0] as? NSDictionary)?["geometry"] as? String {
     print("This is features: \(features)"                              
} else {
     print("ERROR for getting 'features'")
}

但是我总是收到“错误”消息。

import UIKit
import CoreLocation

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, CLLocationManagerDelegate {

//MARK: - Variables and constants
let locationManager = CLLocationManager()
var latit = 0.0
var longit = 0.0
var latitString = ""
var longitString = ""
var locationArray:[String] = []

//MARK: - Labels, tables, maps, etc. on tableView
@IBOutlet var tableView: UITableView!

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "Cell")

    return cell

}

//MARK: - ViewDidLoad()
override func viewDidLoad() {
    super.viewDidLoad()

    // For use when the app is open & in the background
    locationManager.requestAlwaysAuthorization()

    //For use when the app is open
    locationManager.requestWhenInUseAuthorization()

    //Once we have the permission of using the location:
    if CLLocationManager.locationServicesEnabled(){

        locationManager.delegate = self
        locationManager.startUpdatingLocation()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()

    }

    tableView.delegate = self
    tableView.dataSource = self

}

//MARK: - Detect location
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    if let location = locations.first{

        latit = location.coordinate.latitude
        longit = location.coordinate.longitude
        print("Latitude: \(String(format: "%.4f", latit)), Longitude: \(String(format: "%.4f", longit))")
        latitString = String(format: "%.4f", latit)
        longitString = String(format: "%.4f", longit)
        print("Lat Str: \(latitString) | Lon Str: \(longitString)")

        //Adding elements to array.
        self.locationArray.append(latitString)//String(format: "%.4f", latit))
        self.locationArray.append(longitString)//String(format: "%.4f", longit))

        print(locationArray)

        //MARK: - Using NASA API to get DNI, GHI and DHI
        if let NASAurl = URL(string: "https://power.larc.nasa.gov/cgi-bin/v1/DataAccess.py?request=execute&identifier=SinglePoint&parameters=DNR,DIFF,ALLSKY_SFC_SW_DWN&userCommunity=SSE&tempAverage=CLIMATOLOGY&outputList=ASCII&lat=\(latitString)&lon=\(longitString)&user=anonymous"){

            print("This is NASA's url: \(NASAurl)")

            let task = URLSession.shared.dataTask(with: NASAurl) { (data, response, error) in

                if error != nil{

                    print(error!)

                }else{

                    if let urlContent = data{

                        do{

                            let NASAjsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
                            print("This is NASA jsonResult: \(NASAjsonResult)")

                            if let features = ((NASAjsonResult["features"] as? NSArray)?[0] as? NSDictionary)?["geometry"] as? String {

                                print("This is features: \(features)")

                            }else {print("ERROR for features")}



                        }catch{

                            print("NASA JSON Processing Failed.")

                        }

                    }

                }

            }

            task.resume()

        }

    }

}

}

这个项目还远远没有完成,我知道它还有很多错误,但是现在我只想集中精力从API中获取信息。

再次感谢!

2 个答案:

答案 0 :(得分:0)

这是一种从API提供的响应中提取所需信息的方法(不是最漂亮的方法):

guard let NASAjsonResult = NASAjsonResult as? [String : Any] else {
    print("NASAjsonResult is not a Dictionary")
    return
}

guard let features = NASAjsonResult["features"] as? Array<[String : Any]> else {
    print("features is not an Array")
    return
}

guard let singleFeature = features.first else {
    print("There are no features")
    return
}

if let geometry = singleFeature["geometry"] as? [String : Any],
    let coordinates = geometry["coordinates"] as? Array<Double> {

    let latitude = coordinates[0]
    let longitude = coordinates[1]

    print(latitude)
    print(longitude)
}

if let properties = singleFeature["properties"] as? [String : Any],
    let parameter = properties["parameter"] as? [String : Any] {

    let ALLSKY_SFC_SW_DWN = parameter["ALLSKY_SFC_SW_DWN"] as? [String : Double]
    let DIFF = parameter["DIFF"] as? [String : Double]
    let DNR = parameter["DNR"] as? [String : Double]

    print(ALLSKY_SFC_SW_DWN)
    print(DIFF)
    print(DNR)
}

如果需要,您可以在IF块外定义“纬度”,“经度”,“ ALLSKY_SFC_SW_DWN”,“ DIFF”和“ DNR”以在其他地方使用主题,我只是将它们放置在那里以进行打印。

答案 1 :(得分:0)

我将向您展示如何使用Swift 4 Decodable结构获得纬度和经度。

假设d是您从API返回的JSON数据。然后:

struct Outer : Decodable {
    let features: [Feature]
}
struct Feature : Decodable {
    let geometry: Geometry
}
struct Geometry : Decodable {
    let coordinates: [Double]
}
let outer = try! JSONDecoder().decode(Outer.self, from: d)
let lat = outer.features[0].geometry.coordinates[0] // -3.73999
let long = outer.features[0].geometry.coordinates[1] // 40.39001

获取ALLSKY_SFC_SW_DWN,DIFF和DNR是完全并行的,因此在这里我不会为您全部写出来。毕竟,您需要做一些 工作。