FlickrAPI故障理解

时间:2018-12-07 00:11:25

标签: swift flickr

我必须制作一个应用程序,让用户在地图上放置图钉,然后根据图钉的位置从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信息在我的应用程序上显示图像结果,但是就像我说的那样,我很难理解教授的代码。我的主要问题是在调用函数后,它会跳过拉照片所需的所有操作。很明显,我缺少所需的内容,因此我的代码可以执行所需的内容。

1 个答案:

答案 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密钥。