我必须制作一个应用程序,让用户在地图上放置图钉,然后根据图钉的位置从Flickr中提取图片。我的教授给了我们一个FlickrAPI文件供使用,但是我很难理解它在做什么。
import Foundation
class FlickrAPI: NSObject {
static let sharedInstance = FlickrAPI() // Create a Singleton for the class
var photos: Array<String> = []
var errorLevel = 0
// Flickr Constants
let BASE_URL = "https://api.flickr.com/services/rest/"
let METHOD_NAME = "flickr.photos.search"
let API_KEY = "<API Key Here>"
func fetchPhotosFromFlickrBasedOn(Latitude lat: Double, Longitude lng: Double, PageToFetch pageToFetch: Int, completion: @escaping (_ error: Int, _ pg: Int, _ pgs: Int) -> Void) {
// Empty our Photos Array
photos.removeAll(keepingCapacity: true)
// Build Aurgument List
let methodArguments = [
"method": METHOD_NAME,
"api_key": API_KEY,
"lat": String(format: "%f", lat),
"lon": String(format: "%f", lng),
"accuracy": "15", // Accuracy (Street Level)
"radius": "1", // Distance
"radius_units": "km", // in Kilometers,
"safe_search": "1", // Safe (G Rated),
"content_type": "1", // Photos Only
"per_page": "100", // Photos per Page
"page": "\(pageToFetch)",
"extras": "url_m", // Return Photo URLs
"format": "json", // Request JSON data format
"nojsoncallback": "1" // No JSON Callback
]
// Initialize Shared Session
let session = URLSession.shared
let url = URL(string: BASE_URL + escapeUrlParameters(methodArguments))!
let request = URLRequest(url: url)
var page = 0
var pages = 0
// Setup Session Handler
let task = session.dataTask(with: request, completionHandler: {data, response, error in
self.errorLevel = 0 // Initialize Error Level
if error != nil {
self.errorLevel = 1 //***** Network Error
} else {
// Okay to Parse JSON
do {
let parsedResult: AnyObject = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as AnyObject
if let photosDictionary = parsedResult.value(forKey: "photos") as? NSDictionary {
if let photoArray = photosDictionary.value(forKey: "photo") as? [[String: AnyObject]] {
page = photosDictionary["page"] as! Int
pages = photosDictionary["pages"] as! Int
for photoDictionary in photoArray {
if let photoUrl = photoDictionary["url_m"] as? NSString {
let ext = photoUrl.pathExtension
let noExt = photoUrl.deletingPathExtension
let addThumbDesignation = (noExt + "_q_d") as NSString
let thumbUrl = addThumbDesignation.appendingPathExtension(ext)
self.photos.append(thumbUrl!)
} else {
NSLog("***** Could not obtain an Image URL at Index:%d for Owner:%@", self.photos.count, photoDictionary["owner"] as! String)
}
}
} else {
self.errorLevel = 4 //***** No "Photo" Array key present
}
} else {
self.errorLevel = 3 //***** No "Photos" Dictionary key present
}
} catch {
self.errorLevel = 2 //***** Parsing Error
}
completion(self.errorLevel, page, pages)
}
})
task.resume()
}
// Escape URL Parameters
func escapeUrlParameters(_ parms: [String : String]) -> String {
var urlParms = [String]()
for (key, value) in parms {
let escapedValue = value.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
urlParms += [key + "=" + "\(escapedValue!)"]
}
return urlParms.isEmpty ? "" : "?" + urlParms.joined(separator: "&")
}
}
在我的代码中,我具有以下功能:
@IBAction func addPin(_ gestureRecognizer: UILongPressGestureRecognizer) {
var touchPoint = gestureRecognizer.location(in: Map)
var newCoordinates = Map.convert(touchPoint, toCoordinateFrom: Map)
let annotation = MKPointAnnotation()
annotation.coordinate = newCoordinates
Map.addAnnotation(annotation)
flickr.fetchPhotosFromFlickrBasedOn(Latitude: annotation.coordinate.latitude, Longitude: annotation.coordinate.longitude, PageToFetch: 1, completion: {error,pg,pgs in
print("Error: \(error)")
print("Page: \(pg)")
print("Pages: \(pgs)")
})
//flickr.escapeUrlParameters(<#T##parms: [String : String]##[String : String]#>)
}
我知道代码应该发送json信息,我应该使用json信息在我的应用程序上显示图像结果,但是就像我说的那样,我很难理解教授的代码。我的主要问题是在调用函数后,它会跳过拉照片所需的所有操作。很明显,我缺少所需的内容,因此我的代码可以执行所需的内容。
答案 0 :(得分:0)
您在radius
中使用的FlickrAPI
参数指定的半径对Flickr的API无效。它应该是低于50的东西。如果这是您要走的路线,您将不得不尝试一下,看看可以得到的最大收益是什么。
我建议您使用Postman来测试URL,而不是去调试Xcode中的API问题。在使用Xcode进行调用之前,请分组获取面向API调用的便便。这样很容易。在这种情况下,只需在URL的任意位置放置一个断点,在调试器中键入po url
,将URL复制到Postman中,然后查看Postman中返回的内容。像Flickr这样的API都很擅长告诉您发生了什么。另外,不要害怕查看文档。它使生活变得更加轻松。该端点的文档位于here。
进入完成呼叫时,放置另一个断点并键入po photos
。它将打印出字符串数组,这些字符串是照片的URL。
如果您只是点击地图,则可能不需要info.plist中的位置管理器或用途说明。最后,不要在GitHub或SO之类的开放论坛中丢掉API密钥。