2016-09-21 60 views
0

我試圖按照教程(link,我只是將我的應用程序到最新Swift3語法。 不幸的是仍有一些錯誤,我無法修復。 我將不勝感激任何提示。無法將類型'(NSError !, SPTSession!) - > Void'的值轉換爲期望的參數類型'SPTAuthCallback!'

的錯誤: Image

我AppDelegate.swift:

import UIKit 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

    let kClientID = "cfa6ab909e8349bcb78d4924e1d7a32c" 
    let kCallbackURL = "spotifytutorial://returnAfterLogin" 
    let kTokenSwapURL = "http://localhost:1234/swap" 
    let kTokenRefreshServiceURL = "http://localhost:1234/refresh" 

    var window: UIWindow? 


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     // Override point for customization after application launch. 
     return true 
    } 

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { 

     if SPTAuth.defaultInstance().canHandle(url, withDeclaredRedirectURL: URL(string: kCallbackURL)) { 
      SPTAuth.defaultInstance().handleAuthCallback(withTriggeredAuthURL: url, tokenSwapServiceEndpointAt: URL(string: kTokenSwapURL), callback: { (error:NSError!, session:SPTSession!) -> Void in 
       if error != nil { 
        print("AUTHENTICATION ERROR") 
        return 
       } 

       let userDefaults = UserDefaults.standard 

       let sessionData = NSKeyedArchiver.archivedData(withRootObject: session) 

       userDefaults.set(sessionData, forKey: "SpotifySession") 

       userDefaults.synchronize() 

       NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil) 


      }) 
     } 

     return false 

    } 

    func applicationWillResignActive(_ application: UIApplication) { 
     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
     // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
    } 

    func applicationDidEnterBackground(_ application: UIApplication) { 
     // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
    } 

    func applicationWillEnterForeground(_ application: UIApplication) { 
     // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 
    } 

    func applicationDidBecomeActive(_ application: UIApplication) { 
     // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
    } 

    func applicationWillTerminate(_ application: UIApplication) { 
     // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
    } 


} 

我ViewController.swift:

import UIKit 

class ViewController: UIViewController, SPTAudioStreamingPlaybackDelegate { 

    let kClientID = "cfa6ab909e8349bcb78d4924e1d7a32c" 
    let kCallbackURL = "spotifytutorial://returnAfterLogin" 
    let kTokenSwapURL = "http://localhost:1234/swap" 
    let kTokenRefreshServiceURL = "http://localhost:1234/refresh" 

    var session:SPTSession! 
    var player:SPTAudioStreamingController? 

    @IBOutlet weak var artworkImageView: UIImageView! 
    @IBOutlet weak var loginButton: UIButton! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     loginButton.isHidden = true 
     NotificationCenter.default.addObserver(self, selector: #selector(ViewController.updateAfterFirstLogin), name: NSNotification.Name(rawValue: "loginSuccessfull"), object: nil) 

     let userDefaults = UserDefaults.standard 

     if let sessionObj:AnyObject = userDefaults.object(forKey: "SpotifySession") as AnyObject? { // session available 
      let sessionDataObj = sessionObj as! Data 

      let session = NSKeyedUnarchiver.unarchiveObject(with: sessionDataObj) as! SPTSession 

      if !session.isValid() { 
       SPTAuth.defaultInstance().renewSession(session, withServiceEndpointAt: URL(string: kTokenRefreshServiceURL), callback: { (error:NSError!, renewdSession:SPTSession!) -> Void in 
        if error == nil { 
         let sessionData = NSKeyedArchiver.archivedDataWithRootObject(session) 
         userDefaults.setObject(sessionData, forKey: "SpotifySession") 
         userDefaults.synchronize() 

         self.session = renewdSession 
         self.playUsingSession(renewdSession) 
        }else{ 
         println("error refreshing session") 
        } 
       }) 
      }else{ 
       print("session valid") 
       self.session = session 
       playUsingSession(session) 
      } 



     }else{ 
      loginButton.isHidden = false 
     } 


    } 


    func updateAfterFirstLogin() { 
     loginButton.isHidden = true 

     let userDefaults = UserDefaults.standard 

     if let sessionObj:AnyObject = userDefaults.object(forKey: "SpotifySession") as AnyObject? { 
      let sessionDataObj = sessionObj as! Data 
      let firstTimeSession = NSKeyedUnarchiver.unarchiveObject(with: sessionDataObj) as! SPTSession 
      self.session = firstTimeSession 
      playUsingSession(firstTimeSession) 

     } 

    } 


    func playUsingSession(_ sessionObj:SPTSession!){ 
     if player == nil { 
      player = SPTAudioStreamingController(clientId: kClientID) 
      player?.playbackDelegate = self 
     } 

     player?.login(with: sessionObj, callback: { (error:NSError!) -> Void in 
      if error != nil { 
       print("Enabling playback got error \(error)") 
       return 
      } 

      /*SPTRequest.requestItemAtURI(NSURL(string: "spotify:album:4L1HDyfdGIkACuygktO7T7"), withSession: sessionObj, callback: { (error:NSError!, albumObj:AnyObject!) -> Void in 
       if error != nil { 
        println("Album lookup got error \(error)") 
        return 
       } 

       let album = albumObj as SPTAlbum 

       self.player?.playTrackProvider(album, callback: nil) 
      })*/ 

      SPTRequest.performSearch(withQuery: "let it go", queryType: SPTSearchQueryType.queryTypeTrack, offset: 0, session: nil, callback: { (error:NSError!, result:AnyObject!) -> Void in 
       let trackListPage = result as SPTListPage 

       let partialTrack = trackListPage.items.first as SPTPartialTrack 

       SPTRequest.requestItemFromPartialObject(partialTrack, withSession: nil, callback: { (error:NSError!, results:AnyObject!) -> Void in 
        let track = results as SPTTrack 
        self.player?.playTrackProvider(track, callback: nil) 
       }) 


      }) 

     }) 

    } 


    @IBAction func loginWithSpotify(_ sender: AnyObject) { 
     let auth = SPTAuth.defaultInstance() 

     let loginURL = auth?.loginURL(forClientId: kClientID, declaredRedirectURL: URL(string: kCallbackURL), scopes: [SPTAuthStreamingScope]) 

     UIApplication.shared.openURL(loginURL!) 
    } 


    func updateCoverArt(){ 
     if player?.currentTrackMetadata == nil { 
      artworkImageView.image = UIImage() 
      return 
     } 

     let uri = player?.currentTrackMetadata[SPTAudioStreamingMetadataAlbumURI] as! String 

     SPTAlbum.albumWithURI(URL(string: uri), session: session) { (error:NSError!, albumObj:AnyObject!) -> Void in 
      let album = albumObj as SPTAlbum 

      if let imgURL = album.largestCover.imageURL as NSURL! { 
       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {() -> Void in 
        var error:NSError? = nil 
        var coverImage = UIImage() 

        if let imageData = NSData(contentsOfURL: imgURL, options: nil, error: &error){ 
         if error == nil { 
          coverImage = UIImage(data: imageData)! 
         } 
        } 

        dispatch_async(dispatch_get_main_queue(), {() -> Void in 
         self.artworkImageView.image = coverImage 
        }) 


       }) 
      } 

     } 

    } 


    func audioStreaming(_ audioStreaming: SPTAudioStreamingController!, didStartPlayingTrack trackUri: URL!) { 
     updateCoverArt() 
    } 



    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 
+1

你可能不得不改變' NSError'到'Error' – dan

+0

只是一個小小的建議:讓pre-co mpiler通過調用像'functionWithClosure {param1,param2 in ...}'這樣的閉包來告訴你參數的類型是什麼。 –

回答

0

試試這個:

在您的委託:

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { 

    if SPTAuth.defaultInstance().canHandle(url) { 

     SPTAuth.defaultInstance().handleAuthCallback(withTriggeredAuthURL: url, callback: { 
      error, session in 

      if error != nil { 
       print("AUTHENTICATION ERROR \(error)") 
       return 
      } 

      let userDefaults = UserDefaults.standard 

      let sessionData = NSKeyedArchiver.archivedData(withRootObject: session) 

      userDefaults.set(sessionData, forKey: "SpotifySession") 

      userDefaults.synchronize() 

      NotificationCenter.default.post(name: Notification.Name(rawValue: "loginSuccessfull"), object: nil) 
      }) 
    } 
    return false 

} 

並基於控制器:

func loginWithSpotify(sender: AnyObject) { 
    let auth = SPTAuth.defaultInstance()! 

    auth.clientID = clientId 
    auth.redirectURL = URL(string: kCallbackURL) 
    auth.tokenRefreshURL = URL(string: kTokenRefreshServiceURL) 
    auth.tokenSwapURL = URL(string: kTokenSwapURL) 
    auth.requestedScopes = [SPTAuthPlaylistReadPrivateScope ] 

    let loginURL = auth.loginURL 


    UIApplication.shared.openURL(loginURL!) 
} 
相關問題