ios - 在 flickrSearchURLForSearchTerm 中发现 nil

标签 ios swift flickr

在我看来,我发现不错 tutorial关于 Ray Wenderlich 的仪器,但它适用于 Xcode 6+ 和 iOS 8+,因此有一些问题必须改变。

在我更改代码后,我没有任何错误,但一天早上关于无法访问的场景。但是,当我运行该应用程序并尝试在 Flickr 中查找一些“Cats”时,我在以下代码的最后一行中发现了“Found nil”:

//
//  FlickrSearcher.swift
//  flickrSearch
//
//  Created by Richard Turton on 31/07/2014.
//  Copyright (c) 2014 Razeware. All rights reserved.
//

import Foundation
import UIKit

let apiKey = "a3764131ee7cca9d9591c5ad5490b325"

struct FlickrSearchResults {
  let searchTerm : String
  let searchResults : [FlickrPhoto]
}

class FlickrPhoto : Equatable {
  let photoID : String
  let title: String
  private let farm : Int
  private let server : String
  private let secret : String

  typealias ImageLoadCompletion = (image: UIImage?, error: NSError?) -> Void

  init (photoID:String, title:String, farm:Int, server:String, secret:String) {
    self.photoID = photoID
    self.title = title
    self.farm = farm
    self.server = server
    self.secret = secret
  }

  func flickrImageURL(size:String = "m") -> NSURL {
    return NSURL(string: "http://farm\(farm).staticflickr.com/\(server)/\(photoID)_\(secret)_\(size).jpg")!
  }

  func loadThumbnail(completion: ImageLoadCompletion) {
    loadImageFromURL(URL: flickrImageURL("m")) { image, error in
      completion(image: image, error: error)
    }
  }

  func loadLargeImage(completion: ImageLoadCompletion) {
    loadImageFromURL(URL: flickrImageURL("b"), completion: completion)
  }

  func loadImageFromURL(URL URL: NSURL, completion: ImageLoadCompletion) {
    let loadRequest = NSURLRequest(URL: URL)
    NSURLConnection.sendAsynchronousRequest(loadRequest,
      queue: NSOperationQueue.mainQueue()) {
        response, data, error in

        if error != nil {
          completion(image: nil, error: error)
          return
        }

        if data != nil {
          completion(image: UIImage(data: data!), error: nil)
          return
        }

        completion(image: nil, error: nil)
    }
  }
}


extension FlickrPhoto {
  var isFavourite: Bool {
    get {
      return NSUserDefaults.standardUserDefaults().boolForKey(photoID)
    }
    set {
      NSUserDefaults.standardUserDefaults().setBool(newValue, forKey: photoID)
    }
  }
}

func == (lhs: FlickrPhoto, rhs: FlickrPhoto) -> Bool {
  return lhs.photoID == rhs.photoID
}

class Flickr {

  let processingQueue = NSOperationQueue()

  func searchFlickrForTerm(searchTerm: String, completion : (results: FlickrSearchResults?, error : NSError?) -> Void){

    let searchURL = flickrSearchURLForSearchTerm(searchTerm)
    let searchRequest = NSURLRequest(URL: searchURL)

    NSURLConnection.sendAsynchronousRequest(searchRequest, queue: processingQueue) {response, data, error in
      if error != nil {
        completion(results: nil,error: error)
        return
      }

      var resultsDictionary = NSDictionary()
      print("\(resultsDictionary) resultsDic created")

      do {
        resultsDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions(rawValue: 0)) as! NSDictionary
        print(resultsDictionary.count)
      } catch let JSONError as NSError {
        completion(results: nil, error: JSONError)
        print(JSONError)
        return

      }

      switch (resultsDictionary["stat"] as! String) {
      case "ok":
        print("Results processed OK")
      case "fail":
        let APIError = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:resultsDictionary["message"]!])
        completion(results: nil, error: APIError)
        return
      default:
        let APIError = NSError(domain: "FlickrSearch", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey:"Unknown API response"])
        completion(results: nil, error: APIError)
        return
      }

      let photosContainer = resultsDictionary["photos"] as! NSDictionary
      let photosReceived = photosContainer["photo"] as! [NSDictionary]

      let flickrPhotos : [FlickrPhoto] = photosReceived.map {
        photoDictionary in

        let photoID = photoDictionary["id"] as? String ?? ""
        let title = photoDictionary["title"] as? String ?? ""
        let farm = photoDictionary["farm"] as? Int ?? 0
        let server = photoDictionary["server"] as? String ?? ""
        let secret = photoDictionary["secret"] as? String ?? ""

        let flickrPhoto = FlickrPhoto(photoID: photoID, title: title, farm: farm, server: server, secret: secret)

        return flickrPhoto
      }

      dispatch_async(dispatch_get_main_queue(), {
        completion(results:FlickrSearchResults(searchTerm: searchTerm, searchResults: flickrPhotos), error: nil)
      })
    }
  }

  private func flickrSearchURLForSearchTerm(searchTerm:String) -> NSURL {

    let escapedTerm = searchTerm.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())

    let URLString = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=\(apiKey)&text=\(escapedTerm)&per_page=20&format=json&nojsoncallback=1"
    return NSURL(string: URLString)! // error line
  }
}

enter image description here enter image description here 这里有什么问题?

最佳答案

我发现错误了! 你应该打开可选的所以最后一个方法应该是这样的:

private func flickrSearchURLForSearchTerm(searchTerm:String) -> NSURL {

    let escapedTerm = searchTerm.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!

    let URLString = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=\(apiKey)&text=\(escapedTerm)&per_page=20&format=json&nojsoncallback=1"
    print(URLString)
    return NSURL(string: URLString)!
  }

之后应该在 info.plist 文件中允许传输安全:

<key>NSAppTransportSecurity</key>  
     <dict>  
          <key>NSAllowsArbitraryLoads</key><true/>  
     </dict>

之后它工作得很好! 希望有人会使用它!

关于ios - 在 flickrSearchURLForSearchTerm 中发现 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35126356/

相关文章:

javascript - XMLHttpRequest - flickr - 跨源 header

ios - 如何从 SKScene 到 UIViewController?

iphone - iOS : Getting FriendList along with respective name, 使用 FBGraph API 的 id 和图片

ios - Swift:如何将数据传递给嵌入在 ContainerView 中的 PageViewController?

swift - 保持单元格内按钮的选定状态

javascript - flickr api - 使用 JSONP 获取照片

jquery - 加载程序 .gif 过早隐藏

ios - Core Data ios - 如何根据应用程序首次启动加载数据?

Android 相当于 iOS 中的 NSURLProtocol

ios - 歧义使用下标 xcode 7.1