我們有幾個SDK旨在使所有技能級別的開發人員儘可能簡單,包括最新手消費政府API(http://usdepartmentoflabor.github.io/DOLAPI/code.html#sdks)。我現在試圖在Swift上取得一個開始,我將在一個簡單的應用程序的上下文中開始使用它,它有一個目的:證明SDK的工作原理。調用Web API時發生混淆錯誤
我遇到的麻煩是它崩潰的原因,我無法解釋(完整的來源是在https://github.com/MikePulsiferDOL/test-app)。
import Foundation
protocol GovDataRequestProtocol {
func didCompleteWithError(errorMessage: String)
func didCompleteWithArray(results: NSArray)
}
class GovDataRequest {
var delegate: GovDataRequestProtocol? = nil
var activeRequests = Int[]()
var APIKey = ""
var APIHost = ""
var APIURL = ""
init(APIKey: String, APIHost: String, APIURL:String) {
self.APIKey = APIKey
self.APIHost = APIHost
self.APIURL = APIURL
}
func callAPIMethod (#method: String, arguments: Dictionary<String,String>, timeOut: Double) {
// Construct the base url based on the provided information
var url = APIHost + APIURL + "/" + method
// Start building the query string
var queryString = ""
// Where appropriate, add the key
switch APIHost {
case "http://api.dol.gov":
queryString = "?KEY=" + APIKey
case "http://api.census.gov", "http://pillbox.nlm.nih.gov":
queryString = "?key=" + APIKey
case "http://api.eia.gov", "http://developer.nrel.gov", "http://api.stlouisfed.org", "http://healthfinder.gov":
queryString = "?api_key=" + APIKey
case "http://www.ncdc.noaa.gov":
queryString = "?token=" + APIKey
default:
// do nothing for now
println("doing nothing for now")
}
//Construct the arguments part of the query string
for (argKey, argValue) in arguments {
switch APIHost {
case "http://api.dol.gov":
// DOL's V1 API has specific formatting requirements for arguments in the query string
switch argKey {
case "top", "skip", "select", "orderby", "filter":
queryString += "&$" + argKey + "=" + argValue
case "format", "query", "region", "locality", "skipcount":
queryString += "&" + argKey + "=" + argValue
default:
println("nothing to see here")
}
case "http://go.usa.gov":
// go.usa.gov requires that the apiKey be the 2nd argument
if countElements(queryString) == 0 {
queryString += "?" + argKey + "=" + argValue + "&apiKey=" + APIKey
} else {
queryString += "&" + argKey + "=" + argValue
}
default:
if countElements(queryString) == 0 {
queryString += "?" + argKey + "=" + argValue
} else {
queryString += "&" + argKey + "=" + argValue
}
}
}
//If there are arguments, append them to the url
if countElements(queryString) > 0 {
url += queryString
}
//DOT FMCSA requires that the key be placed at the end.
if APIHost == "https://mobile.fmcsa.dot.gov" {
if countElements(queryString) > 0 {
url += "&webKey=" + APIKey
} else {
url += "?webKey=" + APIKey
}
}
/*
ASSUMPTION: data retrieved is in JSON format.
TODO: consider situation when XML is received.
*/
// Send the request to the API and parse the JSON
var urlToPackage = url.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
println(urlToPackage)
var urlToSend: NSURL = NSURL(string: urlToPackage)
var session = NSURLSession.sharedSession()
var request = NSMutableURLRequest(URL:urlToSend)
//request.setTimeoutInterval(timeOut)
request.addValue("application/json",forHTTPHeaderField:"Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
println("Task completed")
if(error) {
// if there is an error in the request, print it to the console
//self.delegate?.didCompleteWithError("Error, Will Robinson")
//println(error.localizedDescription)
println("oops!")
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err?) {
// If there is an error parson JSON, print it to the console
NSLog ("Error parsing the JSON")
}
var results: NSArray = jsonResult["results"] as NSArray
self.delegate?.didCompleteWithArray(results)
})
task.resume()
}
}
視圖控制器:
import UIKit
class ViewController: UIViewController, GovDataRequestProtocol {
var firstRequest: GovDataRequest = GovDataRequest(APIKey: "", APIHost: "http://data.fcc.gov", APIURL: "/lpfmapi/rest/v1/lat/36")
//var firstRequest: GovDataRequest = GovDataRequest(APIKey: "", APIHost: "https://itunes.apple.com", APIURL: "/search")
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.firstRequest.delegate = self
//var arguments = Dictionary<String, String>()
var arguments = ["format": "json", "secondchannel": "true"]
//var arguments = ["term": "Angry Birds", "media": "software"]
var timeOut = 60.0
firstRequest.callAPIMethod(method: "long/-119", arguments: arguments, timeOut: timeOut)
//firstRequest.callAPIMethod(method: "", arguments: arguments, timeOut: timeOut)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func didCompleteWithError (errorMessage: String) {
NSLog("error")
}
func didCompleteWithArray (results:NSArray) {
println("success!")
//Let's see what we've got
for item : AnyObject in results {
if let oneItem = item as? NSDictionary {
println("Dictionary!")
} else {
println("Not a Dictionary!")
}
}
}
}
當我使用iTunes的API來進行測試,它的工作原理。如果使用FCC,那麼它會在底部附近的代碼的錯誤處理部分崩潰(EXC_BAD_INSTRUCTION(code = EXCI386_INVOP,subcode = 0x0))。
如果我將錯誤處理代碼註釋掉,它會在發送請求的地方崩潰(在var任務...)。如您所見,我打印發送的URL(urlToPackage)。我將這個輸出結果輸入到chrome中,以驗證URL是否正確形成。
想法?
感謝
這很有道理。你知道他們對另一組眼睛說什麼。謝謝 –