├── README.md ├── SpotifyTest-Bridging-Header.h ├── SpotifyTest.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── sethr.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── Seth.xcuserdatad │ └── xcschemes │ │ ├── SpotifyTest.xcscheme │ │ └── xcschememanagement.plist │ └── sethr.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── SpotifyTest.xcscheme │ └── xcschememanagement.plist └── SpotifyTest ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json └── background.imageset │ ├── Contents.json │ └── backdrop.png ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── LoginViewController.swift ├── SpotifyAudioPlayback.framework ├── Headers │ ├── SPTAudioPlaybackTypes.h │ ├── SPTAudioStreamingController.h │ ├── SPTAudioStreamingController_ErrorCodes.h │ ├── SPTCircularBuffer.h │ ├── SPTCoreAudioController.h │ ├── SPTDiskCache.h │ ├── SPTDiskCaching.h │ ├── SPTPlaybackMetadata.h │ ├── SPTPlaybackState.h │ ├── SpPlaybackEvent.h │ └── SpotifyAudioPlayback.h ├── Info.plist └── SpotifyAudioPlayback ├── SpotifyAuthentication.framework ├── Headers │ ├── SPTAuth.h │ ├── SPTAuthViewController.h │ ├── SPTConnectButton.h │ ├── SPTEmbeddedImages.h │ ├── SPTSession.h │ ├── SPTStoreViewController.h │ └── SpotifyAuthentication.h ├── Info.plist └── SpotifyAuthentication ├── SpotifyMetadata.framework ├── Headers │ ├── SPTAlbum.h │ ├── SPTArtist.h │ ├── SPTBrowse.h │ ├── SPTFeaturedPlaylistList.h │ ├── SPTFollow.h │ ├── SPTImage.h │ ├── SPTJSONDecoding.h │ ├── SPTListPage.h │ ├── SPTMetadataTypes.h │ ├── SPTPartialAlbum.h │ ├── SPTPartialArtist.h │ ├── SPTPartialObject.h │ ├── SPTPartialPlaylist.h │ ├── SPTPartialTrack.h │ ├── SPTPlaylistList.h │ ├── SPTPlaylistSnapshot.h │ ├── SPTPlaylistTrack.h │ ├── SPTRequest.h │ ├── SPTSavedTrack.h │ ├── SPTSearch.h │ ├── SPTTrack.h │ ├── SPTTrackProvider.h │ ├── SPTUser.h │ ├── SPTYourMusic.h │ └── SpotifyMetadata.h ├── Info.plist └── SpotifyMetadata ├── ViewController.swift └── WebViewController.swift /README.md: -------------------------------------------------------------------------------- 1 | # SpotifyInSwift 2 | This is the latest Spotify Demo written in Swift 3. I will try to keep it up to date. 3 | 4 | I spent a while looking for this online, and I was only able to come up with bits and pieces with how fast Spotify's SDK is changing, and with Swift changing at a fast pace as well. I hope this helps out anyone else trying to add Spotify to their project, and only ask that you give me credit for my work if you use my code. I have no license attatched to my demo itself, so... enjoy! 5 | 6 | The code still has some refining to be done. I spent a while trying to get a session to activate properly by changing the code around reducing its quality slightly. Take special note of the plist. It may have extraneous parts, but some of it will likely be necessary to get the project working. 7 | 8 | 9 | # Links 10 | 11 | [Spotify](https://www.spotify.com/) 12 | 13 | [Spotify iOS SDK Info](https://developer.spotify.com/technologies/spotify-ios-sdk/) 14 | 15 | [Spotify GitHub](https://github.com/spotify/ios-sdk) 16 | 17 | [Objective C Demo](https://github.com/spotify/ios-sdk/tree/master/Demo%20Projects/Simple%20Track%20Playback) 18 | -------------------------------------------------------------------------------- /SpotifyTest-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #ifndef SpotifyTest_Bridging_Header_h 6 | #define SpotifyTest_Bridging_Header_h 7 | 8 | #import 9 | #import 10 | #import 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/project.xcworkspace/xcuserdata/sethr.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest.xcodeproj/project.xcworkspace/xcuserdata/sethr.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/xcuserdata/Seth.xcuserdatad/xcschemes/SpotifyTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/xcuserdata/Seth.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SpotifyTest.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5D8898C91DC2D009003170BE 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/xcuserdata/sethr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/xcuserdata/sethr.xcuserdatad/xcschemes/SpotifyTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SpotifyTest.xcodeproj/xcuserdata/sethr.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SpotifyTest.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5D8898C91DC2D009003170BE 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SpotifyTest/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SpotifyTest 4 | // 5 | // Created by Seth Rininger on 10/27/16. 6 | // Copyright © 2016 Seth Rininger. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let appDelegate = UIApplication.shared.delegate as! AppDelegate 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate, SPTAudioStreamingDelegate { 15 | 16 | var window: UIWindow? 17 | var session: SPTSession? 18 | var player: SPTAudioStreamingController? 19 | let kClientId = "ca5c4490e38f41818a6d32a14a0ad2f3" 20 | let kCallbackURL = "spotifytest://returnAfterLogin" 21 | let kTokenSwapURL = "http://localhost:1234/swap" 22 | let kTokenRefreshServiceURL = "http://localhost:1234/refresh" 23 | let kSessionUserDefaultsKey = "SpotifySession" 24 | 25 | func delay(_ delay:Double, closure:@escaping ()->()) { 26 | DispatchQueue.main.asyncAfter( 27 | deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure) 28 | } 29 | 30 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 31 | 32 | SPTAuth.defaultInstance().clientID = kClientId 33 | SPTAuth.defaultInstance().redirectURL = URL(string:kCallbackURL) 34 | //SPTAuth.defaultInstance().tokenSwapURL = URL(string:kTokenSwapURL) 35 | SPTAuth.defaultInstance().requestedScopes = [SPTAuthStreamingScope] 36 | //SPTAuth.defaultInstance().tokenRefreshURL = URL(string: kTokenRefreshServiceURL)! 37 | SPTAuth.defaultInstance().sessionUserDefaultsKey = kSessionUserDefaultsKey 38 | 39 | return true 40 | } 41 | 42 | func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { 43 | // Ask SPTAuth if the URL given is a Spotify authentication callback 44 | 45 | print("The URL: \(url)") 46 | if SPTAuth.defaultInstance().canHandle(url) { 47 | SPTAuth.defaultInstance().handleAuthCallback(withTriggeredAuthURL: url) { error, session in 48 | // This is the callback that'll be triggered when auth is completed (or fails). 49 | if error != nil { 50 | print("*** Auth error: \(error)") 51 | return 52 | } 53 | else { 54 | SPTAuth.defaultInstance().session = session 55 | } 56 | NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "sessionUpdated"), object: self) 57 | } 58 | } 59 | return false 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /SpotifyTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /SpotifyTest/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SpotifyTest/Assets.xcassets/background.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "backdrop.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /SpotifyTest/Assets.xcassets/background.imageset/backdrop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/Assets.xcassets/background.imageset/backdrop.png -------------------------------------------------------------------------------- /SpotifyTest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SpotifyTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSApplicationQueriesSchemes 6 | 7 | spotify-action 8 | 9 | NSAppTransportSecurity 10 | 11 | NSAllowsArbitraryLoads 12 | 13 | NSExceptionDomains 14 | 15 | cloudfront.net 16 | 17 | NSIncludesSubdomains 18 | 19 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 20 | 21 | 22 | 23 | 24 | CFBundleDevelopmentRegion 25 | en 26 | CFBundleExecutable 27 | $(EXECUTABLE_NAME) 28 | CFBundleIdentifier 29 | $(PRODUCT_BUNDLE_IDENTIFIER) 30 | CFBundleInfoDictionaryVersion 31 | 6.0 32 | CFBundleName 33 | $(PRODUCT_NAME) 34 | CFBundlePackageType 35 | APPL 36 | CFBundleShortVersionString 37 | 1.0 38 | CFBundleSignature 39 | ???? 40 | CFBundleURLTypes 41 | 42 | 43 | CFBundleTypeRole 44 | Editor 45 | CFBundleURLName 46 | com.spotify.spotify-action 47 | CFBundleURLSchemes 48 | 49 | SpotifyTest 50 | 51 | 52 | 53 | CFBundleVersion 54 | 1 55 | LSRequiresIPhoneOS 56 | 57 | UILaunchStoryboardName 58 | LaunchScreen 59 | UIMainStoryboardFile 60 | Main 61 | UIRequiredDeviceCapabilities 62 | 63 | armv7 64 | 65 | UISupportedInterfaceOrientations 66 | 67 | UIInterfaceOrientationPortrait 68 | UIInterfaceOrientationLandscapeLeft 69 | UIInterfaceOrientationLandscapeRight 70 | 71 | UISupportedInterfaceOrientations~ipad 72 | 73 | UIInterfaceOrientationPortrait 74 | UIInterfaceOrientationPortraitUpsideDown 75 | UIInterfaceOrientationLandscapeLeft 76 | UIInterfaceOrientationLandscapeRight 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /SpotifyTest/LoginViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SpotifyTest 4 | // 5 | // Created by Seth Rininger on 10/27/16. 6 | // Copyright © 2016 Seth Rininger. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WebKit 11 | 12 | class LoginViewController: UIViewController, SPTStoreControllerDelegate, WebViewControllerDelegate { 13 | 14 | @IBOutlet weak var statusLabel: UILabel! 15 | var authViewController: UIViewController? 16 | var firstLoad: Bool! 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | NotificationCenter.default.addObserver(self, selector: #selector(self.sessionUpdatedNotification), name: NSNotification.Name(rawValue: "sessionUpdated"), object: nil) 21 | self.statusLabel.text = "" 22 | self.firstLoad = true 23 | } 24 | 25 | override func viewWillAppear(_ animated: Bool) { 26 | super.viewWillAppear(animated) 27 | let auth = SPTAuth.defaultInstance() 28 | // Uncomment to turn off native/SSO/flip-flop login flow 29 | //auth.allowNativeLogin = NO; 30 | // Check if we have a token at all 31 | if auth!.session == nil { 32 | self.statusLabel.text = "" 33 | return 34 | } 35 | // Check if it's still valid 36 | if auth!.session.isValid() && self.firstLoad { 37 | // It's still valid, show the player. 38 | self.showPlayer() 39 | return 40 | } 41 | // Oh noes, the token has expired, if we have a token refresh service set up, we'll call tat one. 42 | self.statusLabel.text = "Token expired." 43 | if auth!.hasTokenRefreshService { 44 | self.renewTokenAndShowPlayer() 45 | return 46 | } 47 | // Else, just show login dialog 48 | } 49 | 50 | override var prefersStatusBarHidden: Bool { 51 | return true 52 | } 53 | 54 | func getAuthViewController(withURL url: URL) -> UIViewController { 55 | let webView = WebViewController(url: url) 56 | webView.delegate = self 57 | 58 | return UINavigationController(rootViewController: webView) 59 | } 60 | 61 | func sessionUpdatedNotification(_ notification: Notification) { 62 | self.statusLabel.text = "" 63 | let auth = SPTAuth.defaultInstance() 64 | self.presentedViewController?.dismiss(animated: true, completion: { _ in }) 65 | if auth!.session != nil && auth!.session.isValid() { 66 | self.statusLabel.text = "" 67 | self.showPlayer() 68 | } 69 | else { 70 | self.statusLabel.text = "Login failed." 71 | print("*** Failed to log in") 72 | } 73 | } 74 | 75 | func showPlayer() { 76 | self.firstLoad = false 77 | self.statusLabel.text = "Logged in." 78 | self.performSegue(withIdentifier: "ShowPlayer", sender: nil) 79 | } 80 | 81 | internal func productViewControllerDidFinish(_ viewController: SPTStoreViewController) { 82 | self.statusLabel.text = "App Store Dismissed." 83 | viewController.dismiss(animated: true, completion: { _ in }) 84 | } 85 | 86 | func openLoginPage() { 87 | self.statusLabel.text = "Logging in..." 88 | let auth = SPTAuth.defaultInstance() 89 | if SPTAuth.supportsApplicationAuthentication() { 90 | UIApplication.shared.openURL(auth!.spotifyAppAuthenticationURL()) 91 | } else { 92 | self.authViewController = self.getAuthViewController(withURL: SPTAuth.defaultInstance().spotifyWebAuthenticationURL()) 93 | self.definesPresentationContext = true 94 | self.present(self.authViewController!, animated: true, completion: { _ in }) 95 | } 96 | } 97 | 98 | func renewTokenAndShowPlayer() { 99 | self.statusLabel.text = "Refreshing token..." 100 | SPTAuth.defaultInstance().renewSession(SPTAuth.defaultInstance().session) { error, session in 101 | SPTAuth.defaultInstance().session = session 102 | if error != nil { 103 | self.statusLabel.text = "Refreshing token failed." 104 | print("*** Error renewing session: \(error)") 105 | return 106 | } 107 | self.showPlayer() 108 | } 109 | } 110 | 111 | func webViewControllerDidFinish(_ controller: WebViewController) { 112 | // User tapped the close button. Treat as auth error 113 | } 114 | 115 | @IBAction func loginButtonWasPressed(_ sender: SPTConnectButton) { 116 | self.openLoginPage() 117 | } 118 | 119 | @IBAction func showSpotifyAppStoreClicked(_ sender: UIButton) { 120 | self.statusLabel.text = "Presenting App Store..." 121 | let storeVC = SPTStoreViewController(campaignToken: "your_campaign_token", store: self) 122 | self.present(storeVC!, animated: true, completion: { _ in }) 123 | } 124 | 125 | @IBAction func clearCookiesClicked(_ sender: UIButton) { 126 | let storage = HTTPCookieStorage.shared 127 | for cookie: HTTPCookie in storage.cookies! { 128 | if (cookie.domain as NSString).range(of: "spotify.").length > 0 || (cookie.domain as NSString).range(of: "facebook.").length > 0 { 129 | storage.deleteCookie(cookie) 130 | } 131 | } 132 | UserDefaults.standard.synchronize() 133 | self.statusLabel.text! = "Cookies cleared." 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTAudioPlaybackTypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** Defines a callback block for an operation that has a chance of generating an error. 20 | 21 | If the operation was successful, `error` will be `nil`, otherwise it will contain an `NSError` 22 | object describing the failure.*/ 23 | typedef void (^SPTErrorableOperationCallback)(NSError *error); -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTAudioStreamingController_ErrorCodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** The operation was successful. */ 20 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeNoError; 21 | 22 | /** The operation failed due to an unspecified issue. */ 23 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeFailed; 24 | 25 | /** Audio streaming could not be initialised. */ 26 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeInitFailed; 27 | 28 | /** Audio streaming could not be initialized because of an incompatible API version. */ 29 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeWrongAPIVersion; 30 | 31 | /** An unexpected NULL pointer was passed as an argument to a function. */ 32 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeNullArgument; 33 | 34 | /** An unexpected argument value was passed to a function. */ 35 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeInvalidArgument; 36 | 37 | /** Audio streaming has not yet been initialised for this application. */ 38 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeUninitialized; 39 | 40 | /** Audio streaming has already been initialised for this application. */ 41 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeAlreadyInitialized; 42 | 43 | /** Login to Spotify failed because of invalid credentials. */ 44 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeBadCredentials; 45 | 46 | /** The operation requires a Spotify Premium account. */ 47 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeNeedsPremium; 48 | 49 | /** The Spotify user is not allowed to log in from this country. */ 50 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeTravelRestriction; 51 | 52 | /** The application has been banned by Spotify. */ 53 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeApplicationBanned; 54 | 55 | /** An unspecified login error occurred. */ 56 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeGeneralLoginError; 57 | 58 | /** The operation is not supported. */ 59 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeUnsupported; 60 | 61 | /** The operation is not supported if the device is not the active playback device. */ 62 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeNotActiveDevice; 63 | 64 | /** An unspecified playback error occurred. */ 65 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeGeneralPlaybackError; 66 | 67 | /** The application is rate-limited if it requests the playback of too many tracks within a given amount of time. */ 68 | FOUNDATION_EXPORT NSInteger const SPTErrorCodePlaybackRateLimited; 69 | 70 | /** The track you're trying to play is unavailable for the current user, or was unable to start. */ 71 | FOUNDATION_EXPORT NSInteger const SPTErrorCodeTrackUnavailable; 72 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTCircularBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** This class is a simple implementation of a circular buffer, designed to match the behaviour of the iOS SDK. 18 | 19 | This class gets around the problem of filling the buffer too far ahead by having a maximum size. Once that 20 | size is reached, you cannot add more data without reading some out or clearing it and starting again. When 21 | used with the iOS SDK, this isn't a problem as we can ask the library to re-deliver audio data at a later time. 22 | */ 23 | 24 | #import 25 | 26 | @interface SPTCircularBuffer : NSObject 27 | 28 | /** Initialize a new buffer. 29 | 30 | Initial size will be zero, with a maximum size as provided. 31 | 32 | @param size The maximum size of the buffer, in bytes. 33 | @return Returns the newly created SPTCircularBuffer. 34 | */ 35 | -(id)initWithMaximumLength:(NSUInteger)size; 36 | 37 | /** Clears all data from the buffer. */ 38 | -(void)clear; 39 | 40 | /** Attempt to copy new data into the buffer. 41 | 42 | Data is copied using the following heuristic: 43 | 44 | - If dataLength <= (maximumLength - length), copy all data. 45 | - Otherwise, copy (maximumLength - length) bytes. 46 | 47 | @param data A buffer containing the data to be copied in. 48 | @param dataLength The length of the data, in bytes. 49 | @return Returns the amount of data copied into the buffer, in bytes. If this number is 50 | smaller than dataLength, only this number of bytes was copied in from the start of the given buffer. 51 | */ 52 | -(NSUInteger)attemptAppendData:(const void *)data ofLength:(NSUInteger)dataLength; 53 | 54 | /** Attempt to copy new data into the buffer. 55 | 56 | Data is copied using the following heuristic: 57 | 58 | - If dataLength <= (maximumLength - length), copy all data. 59 | - Otherwise, copy (maximumLength - length) bytes. 60 | - Number of bytes copied will be rounded to the largest number less than dataLength that can be 61 | integrally be divided by chunkSize. 62 | 63 | @param data A buffer containing the data to be copied in. 64 | @param dataLength The length of the data, in bytes. 65 | @param chunkSize Ensures the number of bytes copies in is a multiple of this number. 66 | @return Returns the amount of data copied into the buffer, in bytes. If this number is 67 | smaller than dataLength, only this number of bytes was copied in from the start of the given buffer. 68 | */ 69 | -(NSUInteger)attemptAppendData:(const void *)data ofLength:(NSUInteger)dataLength chunkSize:(NSUInteger)chunkSize; 70 | 71 | /** Read data out of the buffer into a pre-allocated buffer. 72 | 73 | @param desiredLength The desired number of bytes to copy out. 74 | @param outBuffer A pointer to a buffer, which must be malloc'ed with at least `desiredLength` bytes. 75 | @return Returns the amount of data copied into the given buffer, in bytes. 76 | */ 77 | -(NSUInteger)readDataOfLength:(NSUInteger)desiredLength intoAllocatedBuffer:(void **)outBuffer; 78 | 79 | /** Returns the amount of data currently in the buffer, in bytes. */ 80 | @property (readonly) NSUInteger length; 81 | 82 | /** Returns the maximum amount of data that the buffer can hold, in bytes. */ 83 | @property (readonly, nonatomic) NSUInteger maximumLength; 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTCoreAudioController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // This class encapsulates a Core Audio graph that includes 18 | // an audio format converter, a mixer for iOS volume control and a standard output. 19 | // Clients just need to set the various properties and not worry about the details. 20 | 21 | #import 22 | #import 23 | 24 | #if TARGET_OS_IPHONE 25 | #import 26 | #endif 27 | 28 | @class SPTCoreAudioController; 29 | @class SPTCoreAudioDevice; 30 | 31 | /** Provides delegate callbacks for SPTCoreAudioController. */ 32 | 33 | @protocol SPTCoreAudioControllerDelegate 34 | 35 | @optional 36 | 37 | /** Called repeatedly during audio playback when audio is pushed to the system's audio output. 38 | 39 | This can be used to keep track of how much audio has been played back for progress indicators and so on. 40 | 41 | @param controller The SPTCoreAudioController that pushed audio. 42 | @param audioDuration The duration of the audio that was pushed to the output device. 43 | */ 44 | -(void)coreAudioController:(SPTCoreAudioController *)controller didOutputAudioOfDuration:(NSTimeInterval)audioDuration; 45 | 46 | @end 47 | 48 | /** Provides an audio pipeline from SPTAudioStreamingController to the system's audio output. */ 49 | 50 | @interface SPTCoreAudioController : NSObject 51 | 52 | ///---------------------------- 53 | /// @name Control 54 | ///---------------------------- 55 | 56 | /** 57 | Completely empties all audio that's buffered for playback. 58 | 59 | This should be called when you need cancel all pending audio in order to, 60 | for example, play a new track. 61 | */ 62 | -(void)clearAudioBuffers; 63 | 64 | /** 65 | Attempts to deliver the passed audio frames passed to the audio output pipeline. 66 | 67 | @param audioFrames A buffer containing the audio frames. 68 | @param frameCount The number of frames included in the buffer. 69 | @param audioDescription A description of the audio contained in `audioFrames`. 70 | @return Returns the number of frames actually delievered to the audio pipeline. If this is less than `frameCount`, 71 | you need to retry delivery again later as the internal buffers are full. 72 | */ 73 | -(NSInteger)attemptToDeliverAudioFrames:(const void *)audioFrames ofCount:(NSInteger)frameCount streamDescription:(AudioStreamBasicDescription)audioDescription; 74 | 75 | /** Returns the number of bytes in the audio buffer. */ 76 | -(uint32_t)bytesInAudioBuffer; 77 | 78 | ///---------------------------- 79 | /// @name Customizing the audio pipeline 80 | ///---------------------------- 81 | 82 | /** 83 | Connects the given `AUNode` instances together to complete the audio pipeline for playback. 84 | 85 | If you wish to customise the audio pipeline, you can do so by overriding this method and inserting your 86 | own `AUNode` instances between `sourceNode` and `destinationNode`. 87 | 88 | This method will be called whenever the audio pipeline needs to be (re)built. 89 | 90 | @warning If you override this method and connect the nodes yourself, do not call the `super` 91 | implementation. You can, however, conditionally decide whether to customise the queue and call `super` 92 | if you want the default behaviour. 93 | 94 | @param sourceOutputBusNumber The bus on which the source node will be providing audio data. 95 | @param sourceNode The `AUNode` which will provide audio data for the graph. 96 | @param destinationInputBusNumber The bus on which the destination node expects to receive audio data. 97 | @param destinationNode The `AUNode` which will carry the audio data to the system's audio output. 98 | @param graph The `AUGraph` containing the given nodes. 99 | @param error A pointer to an NSError instance to be filled with an `NSError` should a problem occur. 100 | @return `YES` if the connection was made successfully, otherwise `NO`. 101 | */ 102 | -(BOOL)connectOutputBus:(UInt32)sourceOutputBusNumber ofNode:(AUNode)sourceNode toInputBus:(UInt32)destinationInputBusNumber ofNode:(AUNode)destinationNode inGraph:(AUGraph)graph error:(NSError **)error; 103 | 104 | /** 105 | Called when custom nodes in the pipeline should be disposed. 106 | 107 | If you inserted your own `AUNode` instances into the audio pipeline, override this method to 108 | perform any cleanup needed. 109 | 110 | This method will be called whenever the audio pipeline is being torn down. 111 | 112 | @param graph The `AUGraph` that is being disposed. 113 | */ 114 | -(void)disposeOfCustomNodesInGraph:(AUGraph)graph; 115 | 116 | ///---------------------------- 117 | /// @name Properties 118 | ///---------------------------- 119 | 120 | /** 121 | Returns the volume of audio playback, between `0.0` and `1.0`. 122 | 123 | This property only applies to audio played back through this class, not the system audio volume. 124 | */ 125 | @property (readwrite, nonatomic) double volume; 126 | 127 | /** Whether audio output is enabled. */ 128 | @property (readwrite, nonatomic) BOOL audioOutputEnabled; 129 | 130 | /** Returns the receiver's delegate. */ 131 | @property (readwrite, nonatomic, weak) id delegate; 132 | 133 | #if !TARGET_OS_IPHONE 134 | 135 | /** Returns the available audio output devices. Mac only. */ 136 | @property (readonly, nonatomic, copy) NSArray *availableOutputDevices; 137 | 138 | /** Returns the current output device. Set to `nil` to use the system default. Mac only. */ 139 | @property (readwrite, nonatomic, strong) SPTCoreAudioDevice *currentOutputDevice; 140 | 141 | #endif 142 | 143 | #if TARGET_OS_IPHONE 144 | 145 | /** Current background playback task reference. */ 146 | @property (readwrite, nonatomic) UIBackgroundTaskIdentifier backgroundPlaybackTask; 147 | 148 | #endif 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTDiskCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTDiskCaching.h" 19 | 20 | /** 21 | * @brief The `SPTDiskCache` class implements the `SPTDiskCaching` protocol and provides a caching mechanism based on memory mapped files. 22 | */ 23 | @interface SPTDiskCache : NSObject 24 | 25 | /** 26 | * @brief Initialize the disk cache with capacity. 27 | * @param capacity The maximum capacity of the disk cache, in bytes. 28 | */ 29 | - (instancetype)initWithCapacity:(NSUInteger)capacity; 30 | 31 | @property (nonatomic, readonly) NSUInteger capacity; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTDiskCaching.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** 20 | @brief The `SPTDiskCaching` protocol is implemented by classes that handle caching of Spotify data to persistent storage. 21 | 22 | Methods of this protocol will be called from within Spotify SDK when it requires access to persistent storage for caching. 23 | 24 | */ 25 | @protocol SPTDiskCaching 26 | 27 | /** 28 | Creates a disk cache of certain size or changes the size of an existing cache. 29 | 30 | This method will be called when a new cache needs to be created or when the size of an existing cache needs to be changed. The cache should be accessible via other 'SPTDiskCaching' methods when using the same key as provided in this method. 31 | 32 | @param key An alphanumeric string, through which the cache is identified and accessed via 'SPTDiskCaching' methods. 33 | @param size The requested amount of bytes in the cache. 34 | @return `YES` if the cache of requested size has been allocated successfully, otherwise `NO`. 35 | */ 36 | - (BOOL)allocateCacheWithKey:(NSString *)key 37 | size:(NSUInteger)size; 38 | 39 | /** 40 | Reads data from the existing disk cache. 41 | 42 | This method will be called whenever a data needs to be read from the existing disk cache. The cache is identified by its key. 43 | 44 | @param key The identifier of the cache. 45 | @param length The amount of bytes to be read from the cache. 46 | @param offset The amount of bytes to be skipped from the beginning of the cache before reading starts. 47 | @return An instance of NSData containing the data read from the cache; 'nil' if reading failed. 48 | */ 49 | - (NSData *)readCacheDataWithKey:(NSString *)key 50 | length:(NSUInteger)length 51 | offset:(NSUInteger)offset; 52 | 53 | /** 54 | Writes data to the existing disk cache. 55 | 56 | This method will be called whenever a data needs to be written to the existing disk cache. The cache is identified by its key. 57 | 58 | @param key The identifier of the cache. 59 | @param data Bytes to be written to the cache. 60 | @param offset The amount of bytes to be skipped from the beginning of the cache before writing starts. 61 | @return `YES` if writing to the cache has been successful, otherwise 'NO'. 62 | */ 63 | - (BOOL)writeCacheDataWithKey:(NSString *)key 64 | data:(NSData *)data 65 | offset:(NSUInteger)offset; 66 | 67 | /** 68 | Closes the existing disk cache. 69 | 70 | This method will be called when a cache is no longer needed and can be deleted. 71 | 72 | @param key The identifier of the cache. 73 | 74 | */ 75 | - (void)closeCacheWithKey:(NSString *)key; 76 | 77 | @end 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTPlaybackMetadata.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | 20 | @interface SPTPlaybackTrack : NSObject 21 | 22 | @property (readonly, nonnull) NSString *name; 23 | @property (readonly, nonnull) NSString *uri; 24 | @property (readonly, nonnull) NSString *playbackSourceUri; 25 | @property (readonly, nonnull) NSString *playbackSourceName; 26 | @property (readonly, nonnull) NSString *artistName; 27 | @property (readonly, nonnull) NSString *artistUri; 28 | @property (readonly, nonnull) NSString *albumName; 29 | @property (readonly, nonnull) NSString *albumUri; 30 | 31 | /// The URL of the album cover art of the track. 32 | @property (nullable, nonatomic, copy, readonly) NSString *albumCoverArtURL; 33 | 34 | @property (readonly) NSTimeInterval duration; 35 | @property (readonly) NSUInteger indexInContext; 36 | 37 | - (instancetype _Nullable)initWithName:(NSString* _Nonnull)name 38 | uri:(NSString* _Nonnull)uri 39 | playbackSourceUri:(NSString* _Nonnull)playbackSourceUri 40 | playbackSourceName:(NSString* _Nonnull)playbackSourceName 41 | artistName:(NSString* _Nonnull)artistName 42 | artistUri:(NSString* _Nonnull)artistUri 43 | albumName:(NSString* _Nonnull)albumName 44 | albumUri:(NSString* _Nonnull)albumUri 45 | albumCoverArtURL:(NSString * _Nullable)albumCoverArtURL 46 | duration:(NSTimeInterval)duration 47 | indexInContext:(NSUInteger)indexInContext; 48 | 49 | @end 50 | 51 | 52 | @interface SPTPlaybackMetadata: NSObject 53 | 54 | @property (readonly, nullable) SPTPlaybackTrack *prevTrack; 55 | @property (readonly, nullable) SPTPlaybackTrack *currentTrack; 56 | @property (readonly, nullable) SPTPlaybackTrack *nextTrack; 57 | 58 | - (instancetype _Nullable)initWithPrevTrack:(SPTPlaybackTrack* _Nullable)prevTrack 59 | currentTrack:(SPTPlaybackTrack* _Nullable)currentTrack 60 | nextTrack:(SPTPlaybackTrack* _Nullable)nextTrack; 61 | 62 | @end -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SPTPlaybackState.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | 18 | /** 19 | Represent aggregated playar state. 20 | The next substates are exposed: 21 | -isPlaying 22 | -isRepeating 23 | -isShuffling 24 | -isActiveDevice 25 | -positionMs 26 | */ 27 | @interface SPTPlaybackState : NSObject 28 | 29 | @property (nonatomic, readonly) BOOL isPlaying; 30 | @property (nonatomic, readonly) BOOL isRepeating; 31 | @property (nonatomic, readonly) BOOL isShuffling; 32 | @property (nonatomic, readonly) BOOL isActiveDevice; 33 | @property (nonatomic, readonly) NSTimeInterval position; 34 | 35 | - (instancetype _Nullable)initWithIsPlaying:(BOOL)isPlaying 36 | isRepeating:(BOOL)isRepeating 37 | isShuffling:(BOOL)isShuffling 38 | isActiveDevice:(BOOL)isActiveDevice 39 | position:(NSTimeInterval)position; 40 | @end 41 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SpPlaybackEvent.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | typedef enum : NSUInteger { 18 | /** 19 | * \brief Playback has started or has resumed 20 | * \see SpPlaybackPlay, SpPlaybackIsPlaying, \ref observing 21 | */ 22 | SPPlaybackNotifyPlay, 23 | 24 | /** 25 | * \brief Playback has been paused 26 | * 27 | * If the device is the active speaker (according to SpPlaybackIsActiveDevice()), 28 | * the application should stop playing audio immediately. 29 | * 30 | * \note The application is not supposed to discard audio data that has been 31 | * delivered by SpCallbackPlaybackAudioData() but that has not been played yet. 32 | * This audio data still needs to be played when playback resumes 33 | * (#SPPlaybackNotifyPlay). 34 | * 35 | * \see SpPlaybackPause, SpPlaybackIsPlaying, \ref observing 36 | */ 37 | SPPlaybackNotifyPause, 38 | 39 | /** 40 | * \brief The current track or its metadata has changed 41 | * 42 | * This event occurs when playback of a new/different track starts. If your 43 | * application displays metadata of the current track, use SpGetMetadata() to 44 | * reload the metadata when you receive this event. 45 | * 46 | * 47 | * Note : SPPlaybackNotifyTrackChanged is only sent if the current 48 | * track was changed. SPPlaybackNotifyMetadataChanged is a more general 49 | * event that can be used to detect all kinds of UI changes. If you 50 | * display information about the previous and next tracks you should 51 | * use SPPlaybackNotifyMetadataChanged to detect updates to those 52 | * as well. For example, if the upcoming track is changed then 53 | * SPPlaybackNotifyTrackChanged will not be sent but 54 | * SPPlaybackNotifyMetadataChanged will be. 55 | * 56 | */ 57 | SPPlaybackNotifyTrackChanged, 58 | 59 | /** 60 | * \brief Playback has skipped to the next track 61 | * 62 | * This event occurs when SpPlaybackSkipToNext() was invoked or when 63 | * the user skipped to the next track using Spotify Connect. It does not 64 | * occur when playback goes to a new track after the previous track has 65 | * reached the end. 66 | * 67 | * \see SpPlaybackSkipToNext 68 | * \deprecated Use SPPlaybackNotifyMetadataChanged instead. 69 | */ 70 | SPPlaybackNotifyNext, 71 | 72 | /** 73 | * \brief Playback as skipped to the previous track 74 | * \see SpPlaybackSkipToPrev 75 | * \deprecated Use SPPlaybackNotifyMetadataChanged instead. 76 | */ 77 | SPPlaybackNotifyPrev, 78 | 79 | /** 80 | * \brief "Shuffle" was switched on 81 | * 82 | * \see SpPlaybackEnableShuffle, SpPlaybackIsShuffled, \ref observing 83 | */ 84 | SPPlaybackNotifyShuffleOn, 85 | 86 | /** 87 | * \brief "Shuffle" was switched off 88 | * 89 | * \see SpPlaybackEnableShuffle, SpPlaybackIsShuffled, \ref observing 90 | */ 91 | SPPlaybackNotifyShuffleOff, 92 | 93 | /** 94 | * \brief "Repeat" was switched on 95 | * 96 | * \see SpPlaybackEnableRepeat, SpPlaybackIsRepeated, SpPlaybackGetRepeatMode \ref observing 97 | */ 98 | SPPlaybackNotifyRepeatOn, 99 | 100 | /** 101 | * \brief "Repeat" was switched off 102 | * 103 | * \see SpPlaybackEnableRepeat, SpPlaybackIsRepeated, \ref observing 104 | */ 105 | SPPlaybackNotifyRepeatOff, 106 | 107 | /** 108 | * \brief This device has become the active playback device 109 | * 110 | * This event occurs when the users moves playback to this device using 111 | * Spotify Connect, or when playback is moved to this device as a side-effect 112 | * of invoking one of the SpPlayback...() functions. 113 | * 114 | * When this event occurs, it may be a good time to initialize the audio 115 | * pipeline of the application. You should not unpause when you receive this 116 | * event -- wait for SPPlaybackNotifyPlay. 117 | * 118 | * \see SpPlaybackIsActiveDevice 119 | */ 120 | SPPlaybackNotifyBecameActive, 121 | 122 | /** 123 | * \brief This device is no longer the active playback device 124 | * 125 | * This event occurs when the user moves playback to a different device using 126 | * Spotify Connect. 127 | * 128 | * When this event occurs, the application should stop producing audio 129 | * immediately. The application should not take any other action. Specifically, 130 | * the application must not invoke any of the SpPlayback...() functions 131 | * unless requested by some subsequent user interaction. 132 | * 133 | * \see SpPlaybackIsActiveDevice 134 | */ 135 | SPPlaybackNotifyBecameInactive, 136 | 137 | /** 138 | * \brief This device has temporarily lost permission to stream audio from Spotify 139 | * 140 | * A user can only stream audio on one of her devices at any given time. 141 | * If playback is started on a different device, this event may occur. 142 | * If the other device is Spotify Connect-enabled, the event 143 | * SPPlaybackNotifyBecameInactive may occur instead of or in addition to this 144 | * event. 145 | * 146 | * When this event occurs, the application should stop producing audio 147 | * immediately. The application should not take any other action. Specifically, 148 | * the application must not invoke any of the SpPlayback...() functions 149 | * unless requested by some subsequent user interaction. 150 | */ 151 | SPPlaybackNotifyLostPermission, 152 | 153 | /** 154 | * \brief The application should flush its audio buffers 155 | * 156 | * This event occurs for example when seeking to a different position within 157 | * a track. If possible, the application should discard all samples that it 158 | * has received in SpCallbackPlaybackAudioData() but that it has not played yet. 159 | */ 160 | SPPlaybackEventAudioFlush, 161 | 162 | /** 163 | * \brief The library will not send any more audio data 164 | * 165 | * This event occurs when the library reaches the end of a playback context 166 | * and has no more audio to deliver. This occurs, for instance, at the end 167 | * of a playlist when repeat is disabled. When the application receives this 168 | * event, it should finish playing out all of its buffered audio, including 169 | * padding with silence if necessary, until it can report samples_buffered 170 | * as 0 to SpCallbackPlaybackAudioData(). 171 | */ 172 | SPPlaybackNotifyAudioDeliveryDone, 173 | 174 | /** 175 | * \brief Playback changed to a different Spotify context 176 | * 177 | * This event occurs when playback starts or changes to a different context 178 | * than was playing before, such as a change in album or playlist. This is 179 | * an informational event that does not require action, but may be used to 180 | * update the UI display, such as whether the user is playing from a preset. 181 | * 182 | * \deprecated Use SPPlaybackNotifyMetadataChanged instead. 183 | */ 184 | SPPlaybackNotifyContextChanged, 185 | 186 | /** 187 | * \brief Application accepted all samples from the current track 188 | * 189 | * This is an informative event that indicates that all samples from the 190 | * current track have been delivered to and accepted by the application. 191 | * The track has not finished yet (\see SPPlaybackNotifyTrackChanged). 192 | * No action is necessary by the application, but this event may be used 193 | * to store track boundary information if desired. 194 | */ 195 | SPPlaybackNotifyTrackDelivered, 196 | 197 | /** 198 | * \brief Metadata is changed 199 | * 200 | * This event occurs when playback starts or changes to a different context, 201 | * when a track switch occurs, etc. This is an informational event that does 202 | * not require action, but should be used to keep the UI display updated with 203 | * the latest metadata information. 204 | * 205 | */ 206 | SPPlaybackNotifyMetadataChanged, 207 | } SpPlaybackEvent; 208 | 209 | typedef enum : NSUInteger { 210 | /** \brief The operation was successful. */ 211 | SPErrorOk = 0, 212 | 213 | /** \brief The operation failed due to an unspecified issue. */ 214 | SPErrorFailed, 215 | 216 | /** 217 | * \brief The library could not be initialized. 218 | * \see SpInit 219 | */ 220 | SPErrorInitFailed, 221 | 222 | /** 223 | * \brief The library could not be initialized because of an incompatible API version. 224 | * 225 | * When calling SpInit(), you are required to set the field SpConfig::api_version 226 | * to SP_API_VERSION. This error indicates that the library that the application 227 | * is linked against was built for a different SP_API_VERSION. There might be 228 | * an issue with the include or library paths in the build environment, 229 | * or the wrong SDK shared object is loaded at runtime. 230 | * 231 | * \see SpInit, SpConfig::api_version 232 | */ 233 | SPErrorWrongAPIVersion, 234 | 235 | /** 236 | * \brief An unexpected NULL pointer was passed as an argument to a function. 237 | */ 238 | SPErrorNullArgument, 239 | 240 | /** \brief An unexpected argument value was passed to a function. */ 241 | SPErrorInvalidArgument, 242 | 243 | /** \brief A function was invoked before SpInit() or after SpFree() was called. */ 244 | SPErrorUninitialized, 245 | 246 | /** \brief SpInit() was called more than once. */ 247 | SPErrorAlreadyInitialized, 248 | 249 | /** 250 | * \brief Login to Spotify failed because of invalid credentials. 251 | * \see SpConnectionLoginPassword, SpConnectionLoginBlob, SpConnectionLoginZeroConf 252 | */ 253 | SPErrorLoginBadCredentials, 254 | 255 | /** \brief The operation requires a Spotify Premium account */ 256 | SPErrorNeedsPremium, 257 | 258 | /** \brief The Spotify user is not allowed to log in from this country. */ 259 | SPErrorTravelRestriction, 260 | 261 | /** 262 | * \brief The application has been banned by Spotify. 263 | * 264 | * This most likely means that the application key specified in SpConfig::app_key 265 | * has been revoked. 266 | */ 267 | SPErrorApplicationBanned, 268 | 269 | /** 270 | * \brief An unspecified login error occurred. 271 | * 272 | * In order to help debug the issue, the application should register the callback 273 | * SpCallbackDebugMessage(), which receives additional information 274 | * about the error. 275 | */ 276 | SPErrorGeneralLoginError, 277 | 278 | /** 279 | * \brief The operation is not supported. 280 | */ 281 | SPErrorUnsupported, 282 | 283 | /** 284 | * \brief The operation is not supported if the device is not the active playback 285 | * device. 286 | * \see SpPlaybackIsActiveDevice 287 | */ 288 | SPErrorNotActiveDevice, 289 | 290 | /** 291 | * \brief The API has been rate-limited. 292 | * 293 | * The API is rate-limited if it is asked to perform too many actions 294 | * in a short amount of time. 295 | */ 296 | SPErrorAPIRateLimited, 297 | 298 | /** 299 | * \brief Error range reserved for playback-related errors. 300 | */ 301 | SPErrorPlaybackErrorStart = 1000, 302 | 303 | /** \brief An unspecified playback error occurred. 304 | * 305 | * In order to help debug the issue, the application should register the callback 306 | * SpCallbackDebugMessage(), which receives additional information 307 | * about the error. 308 | */ 309 | SPErrorGeneralPlaybackError, 310 | 311 | /** 312 | * \brief The application has been rate-limited. 313 | * 314 | * The application is rate-limited if it requests the playback of too many 315 | * tracks within a given amount of time. 316 | */ 317 | SPErrorPlaybackRateLimited, 318 | 319 | /** 320 | * \brief The Spotify user has reached a capping limit that is in effect 321 | * in this country and/or for this track. 322 | */ 323 | SPErrorPlaybackCappingLimitReached, 324 | 325 | /** 326 | * \brief Cannot change track while ad is playing. 327 | */ 328 | SPErrorAdIsPlaying, 329 | 330 | /** 331 | * \brief The track is (temporarily) corrupt in the Spotify catalogue. 332 | * 333 | * This track will be skipped because it cannot be downloaded. This is a 334 | * temporary issue with the Spotify catalogue that will be resolved. The 335 | * error is for informational purposes only. No action is required. 336 | */ 337 | SPErrorCorruptTrack, 338 | 339 | /** 340 | * \brief Unable to read all tracks from the playing context. 341 | * 342 | * This could be caused by temporary communication or server problems, or 343 | * by the underlying context being removed or shortened during playback (for 344 | * instance, the user deleted all tracks in the playlist while listening.) 345 | */ 346 | SPErrorContextFailed, 347 | 348 | /* 349 | * \brief The item that was being prefetched was unavailable, and cannot be fetched. 350 | * This could be due to an invalid URI, changes in track availability, or geographical limitations. 351 | * This is a permanent error, and the item should not be tried again. 352 | */ 353 | SPErrorPrefetchItemUnavailable, 354 | 355 | /** 356 | * \brief An item is already actively being prefetched. You must stop the current prefetch request to start another one. 357 | * This error is only relevant for builds with offline storage enabled. 358 | */ 359 | SPAlreadyPrefetching, 360 | 361 | /** 362 | * \brief A permanent error was encountered while writing to a registered file storage callback. 363 | * This error is only relevant for builds with offline storage enabled. 364 | */ 365 | SPStorageWriteError, 366 | 367 | /** 368 | * \brief Prefetched item was not fully downloaded or failed. If error happens prefetch can be retried. 369 | * This error is only relevant for builds with offline storage enabled. 370 | */ 371 | SPPrefetchDownloadFailed, 372 | } SpErrorCode; 373 | 374 | NSError * NSErrorFromSPErrorCode(SpErrorCode code); 375 | 376 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Headers/SpotifyAudioPlayback.h: -------------------------------------------------------------------------------- 1 | // 2 | // Spotify Audio Playback Framework.h 3 | // Spotify Audio Playback Framework 4 | // 5 | // Created by Dmytro Ankudinov on 27/09/16. 6 | // Copyright © 2016 Spotify AB. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Spotify Audio Playback Framework. 12 | FOUNDATION_EXPORT double SpotifyAudioPlaybackVersionNumber; 13 | 14 | //! Project version string for Spotify Audio Playback Framework. 15 | FOUNDATION_EXPORT const unsigned char SpotifyAudioPlaybackVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | 25 | #if !TARGET_OS_IPHONE 26 | #import 27 | #endif 28 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/SpotifyAudioPlayback.framework/Info.plist -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAudioPlayback.framework/SpotifyAudioPlayback: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/SpotifyAudioPlayback.framework/SpotifyAudioPlayback -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SPTAuth.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | ///---------------------------- 20 | /// @name Scope constants, see: https://developer.spotify.com/web-api/using-scopes/ 21 | ///---------------------------- 22 | 23 | /** Scope that lets you stream music. */ 24 | FOUNDATION_EXPORT NSString * const SPTAuthStreamingScope; 25 | 26 | /** Scope that lets you read private playlists of the authenticated user. */ 27 | FOUNDATION_EXPORT NSString * const SPTAuthPlaylistReadPrivateScope; 28 | 29 | /** Scope that lets you read users collaborative playlists */ 30 | FOUNDATION_EXPORT NSString * const SPTAuthPlaylistReadCollaborativeScope; 31 | 32 | /** Scope that lets you modify public playlists of the authenticated user. */ 33 | FOUNDATION_EXPORT NSString * const SPTAuthPlaylistModifyPublicScope; 34 | 35 | /** Scope that lets you modify private playlists of the authenticated user. */ 36 | FOUNDATION_EXPORT NSString * const SPTAuthPlaylistModifyPrivateScope; 37 | 38 | /** Scope that lets you follow artists and users on behalf of the authenticated user. */ 39 | FOUNDATION_EXPORT NSString * const SPTAuthUserFollowModifyScope; 40 | 41 | /** Scope that lets you get a list of artists and users the authenticated user is following. */ 42 | FOUNDATION_EXPORT NSString * const SPTAuthUserFollowReadScope; 43 | 44 | /** Scope that lets you read user's Your Music library. */ 45 | FOUNDATION_EXPORT NSString * const SPTAuthUserLibraryReadScope; 46 | 47 | /** Scope that lets you modify user's Your Music library. */ 48 | FOUNDATION_EXPORT NSString * const SPTAuthUserLibraryModifyScope; 49 | 50 | /** Scope that lets you read the private user information of the authenticated user. */ 51 | FOUNDATION_EXPORT NSString * const SPTAuthUserReadPrivateScope; 52 | 53 | /** Scope that lets you read users top played artists and tracks. */ 54 | FOUNDATION_EXPORT NSString * const SPTAuthUserReadTopScope; 55 | 56 | /** Scope that lets you get the birthdate of the authenticated user. */ 57 | FOUNDATION_EXPORT NSString * const SPTAuthUserReadBirthDateScope; 58 | 59 | /** Scope that lets you get the email address of the authenticated user. */ 60 | FOUNDATION_EXPORT NSString * const SPTAuthUserReadEmailScope; 61 | 62 | 63 | FOUNDATION_EXPORT NSString * const SPTAuthSessionUserDefaultsKey; 64 | 65 | 66 | @class SPTSession; 67 | 68 | /** 69 | This class provides helper methods for authenticating users against the Spotify OAuth 70 | authentication service. 71 | */ 72 | @interface SPTAuth : NSObject 73 | 74 | /** The authentication result callback 75 | @param error An `NSError` object if an error occurred, is `nil` if no error. 76 | @param session An `SPTSession` object containing information about the user. 77 | */ 78 | typedef void (^SPTAuthCallback)(NSError *error, SPTSession *session); 79 | 80 | ///---------------------------- 81 | /// @name Convenience Getters 82 | ///---------------------------- 83 | 84 | /** 85 | Returns a pre-created `SPTAuth` instance for convenience. 86 | 87 | @return A pre-created default `SPTAuth` instance. 88 | */ 89 | + (SPTAuth *)defaultInstance; 90 | 91 | 92 | ///---------------------------- 93 | /// @name Environment settings 94 | ///---------------------------- 95 | 96 | /** 97 | Your client ID. 98 | */ 99 | @property (strong, readwrite) NSString *clientID; 100 | 101 | /** 102 | Your redirect URL. 103 | */ 104 | @property (strong, readwrite) NSURL *redirectURL; 105 | 106 | /** 107 | Required scopes for the app, used by authentication steps 108 | */ 109 | @property (strong, readwrite) NSArray *requestedScopes; 110 | 111 | /** 112 | The current session, Note: setting this will persist it in `NSUserDefaults standardUserDefaults` if 113 | a `sessionUserDefaultsKey` is set. 114 | */ 115 | @property (strong, readwrite) SPTSession *session; 116 | 117 | /** 118 | User defaults key, if you want to automatically save the session from user defaults when it changes. 119 | */ 120 | @property (strong, readwrite) NSString *sessionUserDefaultsKey; 121 | 122 | /** 123 | Your token swap URL, if not specified the authentication flow will be limited to implicit grant flow. 124 | */ 125 | @property (strong, readwrite) NSURL *tokenSwapURL; 126 | 127 | /** 128 | Your token refresh URL, if not specified the refresh token flow will be disabled. 129 | */ 130 | @property (strong, readwrite) NSURL *tokenRefreshURL; 131 | 132 | /** 133 | Returns true if there's a valid token swap url specified. 134 | */ 135 | @property (readonly) BOOL hasTokenSwapService; 136 | 137 | /** 138 | Returns true if there's a valid token refresh url specified. 139 | */ 140 | @property (readonly) BOOL hasTokenRefreshService; 141 | 142 | ///---------------------------- 143 | /// @name Starting Authentication 144 | ///---------------------------- 145 | 146 | /** 147 | Returns a URL that, when opened, will begin the Spotify authentication process. 148 | 149 | @warning You must open this URL with the system handler to have the auth process 150 | happen in Safari. Displaying this inside your application is against the Spotify ToS. 151 | 152 | @param clientId Your client ID as declared in the Spotify Developer Centre. 153 | @param redirectURL Your callback URL as declared in the Spotify Developer Centre. 154 | @param scopes The custom scopes to request from the auth API. 155 | @param responseType Authentication response code type, defaults to "code", use "token" if you want to bounce directly to the app without refresh tokens. 156 | 157 | @return The URL to pass to `UIApplication`'s `-openURL:` method. 158 | */ 159 | + (NSURL *)loginURLForClientId:(NSString *)clientId 160 | withRedirectURL:(NSURL *)redirectURL 161 | scopes:(NSArray *)scopes 162 | responseType:(NSString *)responseType; 163 | 164 | /** 165 | Returns a URL that, when opened, will begin the Spotify authentication process. 166 | 167 | @warning You must open this URL with the system handler to have the auth process 168 | happen in Safari. Displaying this inside your application is against the Spotify ToS. 169 | 170 | @param clientId Your client ID as declared in the Spotify Developer Centre. 171 | @param redirectURL Your callback URL as declared in the Spotify Developer Centre. 172 | @param scopes The custom scopes to request from the auth API. 173 | @param responseType Authentication response code type, defaults to "code", use "token" if you want to bounce directly to the app without refresh tokens. 174 | @param campaignId A Spotify-provided campaign token. 175 | @return The URL to pass to `UIApplication`'s `-openURL:` method. 176 | */ 177 | + (NSURL *)loginURLForClientId:(NSString *)clientId 178 | withRedirectURL:(NSURL *)redirectURL 179 | scopes:(NSArray *)scopes 180 | responseType:(NSString *)responseType 181 | campaignId:(NSString *)campaignId; 182 | 183 | ///---------------------------- 184 | /// @name Handling Authentication Callback URLs 185 | ///---------------------------- 186 | 187 | /** 188 | Returns a https:// URL that you can use to retrieve an access token. 189 | 190 | Display this URL within a SFSafariViewController on iOS 9 and up, or UIWebView. 191 | 192 | This is the preffered mode of authentication. 193 | 194 | @note This will always display an option to switch user. 195 | 196 | @return https:// URL for authenticating and authorising with the Spotify service 197 | */ 198 | - (NSURL *)spotifyWebAuthenticationURL; 199 | 200 | /** 201 | Returns a spotify-action:// URL that you can use to retrieve an access token 202 | if `-[SPTAuth supportsApplicationAuthentication]` returns YES. 203 | 204 | Pass this URL to `-[UIApplication openURL:]` to launch the Spotify application on the device. 205 | 206 | @note This will authenticate and authorise for the user currently logged in to the Spotfiy application. There might be no option to switch user. 207 | 208 | @return spotify-action:// URL for initiating a Spotfiy Client SSO attempt. 209 | */ 210 | - (NSURL *)spotifyAppAuthenticationURL; 211 | 212 | /** 213 | Find out if the given URL appears to be a Spotify authentication URL. 214 | 215 | This method is useful if your application handles multiple URL types. You can pass every URL 216 | you receive through here to filter them. 217 | 218 | @param callbackURL The complete callback URL as triggered in your application. 219 | @return Returns `YES` if the callback URL appears to be a Spotify auth callback, otherwise `NO`. 220 | */ 221 | - (BOOL)canHandleURL:(NSURL *)callbackURL; 222 | 223 | /** 224 | Handle a Spotify authentication callback URL, returning a Spotify username and OAuth credential. 225 | 226 | This URL is obtained when your application delegate's `application:openURL:sourceApplication:annotation:` 227 | method is triggered. Use `-[SPTAuth canHandleURL:]` to easily filter out other URLs that may be 228 | triggered. 229 | 230 | @param url The complete callback URL as triggered in your application. 231 | @param block The callback block to be triggered when authentication succeeds or fails. 232 | */ 233 | - (void)handleAuthCallbackWithTriggeredAuthURL:(NSURL *)url callback:(SPTAuthCallback)block; 234 | 235 | /** 236 | Check if "flip-flop" application authentication is supported. 237 | @return YES if supported, NO otherwise. 238 | */ 239 | + (BOOL)supportsApplicationAuthentication; 240 | 241 | /** 242 | Check if Spotify application is installed. 243 | @return YES if installed, NO otherwise. 244 | */ 245 | + (BOOL)spotifyApplicationIsInstalled; 246 | 247 | 248 | ///---------------------------- 249 | /// @name Renewing Sessions 250 | ///---------------------------- 251 | 252 | /** 253 | Request a new access token using an existing SPTSession object containing a refresh token. 254 | 255 | If no token refresh service has been specified the callback will return `nil` as session. 256 | 257 | @param session An SPTSession object with a valid refresh token. 258 | @param block The callback block that will be invoked when the request has been performed. 259 | */ 260 | - (void)renewSession:(SPTSession *)session callback:(SPTAuthCallback)block; 261 | 262 | 263 | @end 264 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SPTAuthViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | 20 | @class SPTAuth; 21 | @class SPTSession; 22 | @class SPTAuthViewController; 23 | 24 | /** A ViewController for managing the login flow inside your app. */ 25 | __deprecated_msg("Use `SFSafariViewController` or a `WKWebView` to present the `SPTAuth.loginURL`") 26 | @protocol SPTAuthViewDelegate 27 | 28 | /** 29 | The user logged in successfully. 30 | 31 | @param authenticationViewController The view controller. 32 | @param session The session object with the new credentials. (Note that the session object in 33 | the `SPTAuth` object passed upon initialization is also updated) 34 | */ 35 | - (void) authenticationViewController:(SPTAuthViewController *)authenticationViewController didLoginWithSession:(SPTSession *)session; 36 | 37 | /** 38 | An error occured while logging in 39 | 40 | @param authenticationViewController The view controller. 41 | @param error The error (Note that the session object in the `SPTAuth` object passed upon initialization 42 | is cleared.) 43 | */ 44 | - (void) authenticationViewController:(SPTAuthViewController *)authenticationViewController didFailToLogin:(NSError *)error; 45 | 46 | /** 47 | User closed the login dialog. 48 | @param authenticationViewController The view controller. 49 | */ 50 | - (void) authenticationViewControllerDidCancelLogin:(SPTAuthViewController *)authenticationViewController; 51 | 52 | @end 53 | 54 | /** 55 | A authentication view controller 56 | 57 | To present the authentication dialog on top of your view controller, do like this: 58 | 59 | ``` 60 | authvc.modalPresentationStyle = UIModalPresentationOverCurrentContext; 61 | authvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; 62 | self.modalPresentationStyle = UIModalPresentationCurrentContext; 63 | self.definesPresentationContext = YES; 64 | [self presentViewController:authvc animated:NO completion:nil]; 65 | ``` 66 | */ 67 | __deprecated_msg("Use `SFSafariViewController` or a `WKWebView` to present the `SPTAuth.loginURL`") 68 | @interface SPTAuthViewController : UIViewController 69 | 70 | /** 71 | The delegate which will receive the result of the authentication. 72 | */ 73 | @property (nonatomic, assign) id delegate; 74 | 75 | /** 76 | Creates an authentication view controller for the default application using the authentication information from 77 | `SPTAuth.defaultInstance` 78 | 79 | @return The authentication view controller. 80 | */ 81 | + (SPTAuthViewController*) authenticationViewController; 82 | 83 | /** 84 | Creates an authentication view controller for a specific application. 85 | 86 | @param auth The authentication object, containing the app configuration, pass `nil` if you want to use the 87 | authentication information from `SPTAuth.defaultInstance` 88 | @return The authentication view controller. 89 | */ 90 | + (SPTAuthViewController*) authenticationViewControllerWithAuth:(SPTAuth *)auth; 91 | 92 | /** 93 | Removes all authentication related cookies from the UIWebView. 94 | 95 | @param callback Called when cookies are cleared. 96 | */ 97 | - (void) clearCookies:(void (^)())callback; 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SPTConnectButton.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | @interface SPTConnectButton : UIControl 20 | @end 21 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SPTEmbeddedImages.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "SPTConnectButton.h" 18 | 19 | @interface SPTEmbeddedImages : NSObject 20 | 21 | +(UIImage *)buttonImage; 22 | 23 | +(UIImage *)closeImage; 24 | 25 | +(UIImage *)newButtonImage; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SPTSession.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** 20 | @brief SPTSession is a class that represents a user session authenticated through the Spotify OAuth service. 21 | @discussion For persisting the session, you may use `NSKeyedArchiver` to obtain an `NSData` instance, which can 22 | be stored securely using Keychain Services. 23 | @note A session is valid for a certain period of time, and may be renewed without user intervention using `SPTAuth`. 24 | @see SPTAuth 25 | */ 26 | @interface SPTSession : NSObject 27 | 28 | ///---------------------------- 29 | /// @name Initialisation 30 | ///---------------------------- 31 | 32 | /** 33 | @brief The deignated initializer for `SPTSession`. 34 | @param userName The username of the user. 35 | @param accessToken The access token of the user. 36 | @param expirationDate The expiration date of the access token. 37 | @return An initialized `SPTSession` object. 38 | */ 39 | - (instancetype)initWithUserName:(NSString *)userName accessToken:(NSString *)accessToken expirationDate:(NSDate *)expirationDate; 40 | 41 | /** 42 | @brief The deignated initializer for `SPTSession`. 43 | @param userName The username of the user. 44 | @param accessToken The access token of the user. 45 | @param encryptedRefreshToken The encrypted refresh token of the user. 46 | @param expirationDate The expiration date of the access token. 47 | @return An initialized `SPTSession` object. 48 | */ 49 | - (instancetype)initWithUserName:(NSString *)userName accessToken:(NSString *)accessToken encryptedRefreshToken:(NSString *)encryptedRefreshToken expirationDate:(NSDate *)expirationDate; 50 | 51 | /** 52 | @brief Initializer that takes an `NSTimeInterval` until the access token expires, instead of an `NSDate`. 53 | @param userName The username of the user. 54 | @param accessToken The access token of the user. 55 | @param timeInterval The time interval until the access token expires. 56 | @return An initialized `SPTSession` object. 57 | */ 58 | - (instancetype)initWithUserName:(NSString *)userName accessToken:(NSString *)accessToken expirationTimeInterval:(NSTimeInterval)timeInterval; 59 | 60 | ///---------------------------- 61 | /// @name Properties 62 | ///---------------------------- 63 | 64 | /** 65 | @brief Returns whether the session is still valid. 66 | @discussion Determining validity is done by comparing the current date and time with the expiration date of the `SPTSession` object. 67 | @return `YES` if valid, otherwise `NO`. 68 | */ 69 | - (BOOL)isValid; 70 | 71 | /** @brief The canonical username of the authenticated user. */ 72 | @property (nonatomic, copy, readonly) NSString *canonicalUsername; 73 | 74 | /** @brief The access token of the authenticated user. */ 75 | @property (nonatomic, copy, readonly) NSString *accessToken; 76 | 77 | /** @brief The encrypted refresh token. */ 78 | @property (nonatomic, copy, readonly) NSString *encryptedRefreshToken; 79 | 80 | /** @brief The expiration date of the access token. */ 81 | @property (nonatomic, copy, readonly) NSDate *expirationDate; 82 | 83 | /** @brief The access token type. */ 84 | @property (nonatomic, copy, readonly) NSString *tokenType; 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SPTStoreViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | 20 | @protocol SPTStoreControllerDelegate; 21 | 22 | /** 23 | A Store View Controller to allow a user to download the Spotify iOS app. 24 | 25 | To present the store controller on top of your view controller: 26 | 27 | ``` 28 | SPTStoreViewController *storeVC = [[SPTStoreViewController alloc] initWithCampaignToken:@"your_campaign_token" storeDelegate:self]; 29 | [self presentViewController:storeVC animated:YES completion:nil]; 30 | ``` 31 | */ 32 | @interface SPTStoreViewController : SKStoreProductViewController 33 | 34 | /// The Spotify-provided campaign token. Must be less than 40-bytes. 35 | @property (nonatomic, copy, readonly) NSString *campaignToken; 36 | 37 | /* 38 | * The designated initializer. Returns an instance of `SPTStoreViewController` presenting the Spotify iOS app. 39 | * @param campaignToken The Spotify-provided campaign token. Must be less than 40-bytes. 40 | * @param storeDelegate The delegate which will be called after a dismiss action is taken in the store view controller. 41 | */ 42 | - (instancetype)initWithCampaignToken:(NSString *)campaignToken 43 | storeDelegate:(id)storeDelegate NS_DESIGNATED_INITIALIZER; 44 | 45 | /// Unavailable, use the designated initializer. 46 | - (instancetype)init NS_UNAVAILABLE; 47 | /// Unavailable, use the designated initializer. 48 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil NS_UNAVAILABLE; 49 | /// Unavailable, use the designated initializer. 50 | - (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; 51 | /// Unavailable, use the designated initializer. 52 | + (instancetype)new NS_UNAVAILABLE; 53 | 54 | @end 55 | 56 | 57 | @protocol SPTStoreControllerDelegate 58 | 59 | /** 60 | Called when the user requests the page to be dismissed. 61 | 62 | ``` 63 | - (void)productViewControllerDidFinish:(SPTStoreViewController *)viewController { 64 | [viewController dismissViewControllerAnimated:YES completion:nil]; 65 | } 66 | ``` 67 | */ 68 | - (void)productViewControllerDidFinish:(SPTStoreViewController *)viewController; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Headers/SpotifyAuthentication.h: -------------------------------------------------------------------------------- 1 | // 2 | // Spotify Authentication Framework.h 3 | // Spotify Authentication Framework 4 | // 5 | // Created by Dmytro Ankudinov on 26/09/16. 6 | // Copyright © 2016 Spotify AB. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Spotify Authentication Framework. 12 | FOUNDATION_EXPORT double SpotifyAuthenticationVersionNumber; 13 | 14 | //! Project version string for Spotify Authentication Framework. 15 | FOUNDATION_EXPORT const unsigned char SpotifyAuthenticationVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import 20 | #import 21 | 22 | #if TARGET_OS_IPHONE 23 | #import 24 | #import 25 | #import 26 | #import 27 | #endif 28 | 29 | 30 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/SpotifyAuthentication.framework/Info.plist -------------------------------------------------------------------------------- /SpotifyTest/SpotifyAuthentication.framework/SpotifyAuthentication: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/SpotifyAuthentication.framework/SpotifyAuthentication -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTAlbum.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTJSONDecoding.h" 19 | #import "SPTRequest.h" 20 | #import "SPTTrackProvider.h" 21 | #import "SPTPartialAlbum.h" 22 | 23 | @class SPTImage; 24 | @class SPTPartialArtist; 25 | @class SPTListPage; 26 | 27 | /** This class represents an album on the Spotify service. 28 | 29 | API Docs: https://developer.spotify.com/web-api/get-album/ 30 | 31 | API Console: https://developer.spotify.com/web-api/console/albums/ 32 | 33 | API Model: https://developer.spotify.com/web-api/object-model/#album-object-full 34 | 35 | Example usage: 36 | 37 | ``` 38 | [SPTAlbum albumWithURI:[NSURL URLWithString:@"spotify:album:58Dbqi6VBskSmnSsbXbgrs"] 39 | accessToken:accessToken 40 | market:@"UK" 41 | callback:^(NSError *error, id object) { 42 | if (error != nil) { handle error } 43 | NSLog(@"Got album %@", object); 44 | }]; 45 | ``` 46 | */ 47 | @interface SPTAlbum : SPTPartialAlbum 48 | 49 | 50 | 51 | 52 | 53 | ///---------------------------- 54 | /// @name Properties 55 | ///---------------------------- 56 | 57 | /** Any external IDs of the album, such as the UPC code. */ 58 | @property (nonatomic, readonly, copy) NSDictionary *externalIds; 59 | 60 | /** An array of artists for this album, as `SPTPartialArtist` objects. */ 61 | @property (nonatomic, readonly) NSArray *artists; 62 | 63 | /** The tracks contained by this album, as a page of `SPTPartialTrack` objects. */ 64 | @property (nonatomic, readonly) SPTListPage *firstTrackPage; 65 | 66 | /** The release year of the album if known, otherwise `0`. */ 67 | @property (nonatomic, readonly) NSInteger releaseYear; 68 | 69 | /** Day-accurate release date of the track if known, otherwise `nil`. */ 70 | @property (nonatomic, readonly) NSDate *releaseDate; 71 | 72 | /** Returns a list of genre strings for the album. */ 73 | @property (nonatomic, readonly, copy) NSArray *genres; 74 | 75 | /** The popularity of the album as a value between 0.0 (least popular) to 100.0 (most popular). */ 76 | @property (nonatomic, readonly) double popularity; 77 | 78 | 79 | 80 | 81 | 82 | ///---------------------------- 83 | /// @name API Request Factories 84 | ///---------------------------- 85 | 86 | /** Create a request for getting an album. 87 | 88 | API Docs: https://developer.spotify.com/web-api/get-album/ 89 | 90 | Try it: https://developer.spotify.com/web-api/console/get-album/ 91 | 92 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 93 | 94 | @param uri The Spotify URI of the album to request. 95 | @param accessToken An optional access token. Can be `nil`. 96 | @param market An optional market parameter. Can be `nil`. 97 | @param error An optional `NSError` that will be set if an error occured. 98 | @return A `NSURLRequest` for requesting the album 99 | */ 100 | + (NSURLRequest*)createRequestForAlbum:(NSURL *)uri 101 | withAccessToken:(NSString *)accessToken 102 | market:(NSString *)market 103 | error:(NSError **)error; 104 | 105 | /** Create a request for getting multiple albums. 106 | 107 | API Docs: https://developer.spotify.com/web-api/get-several-albums/ 108 | 109 | Try it: https://developer.spotify.com/web-api/console/get-several-albums/ 110 | 111 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 112 | 113 | @param uris An array of Spotify URIs. A maxiumum of 20 URIs can be supplied per request. 114 | @param accessToken An optional access token. Can be `nil`. 115 | @param market An optional market parameter. Can be `nil`. 116 | @param error An optional `NSError` that will be set if an error occured. 117 | @return A `NSURLRequest` for requesting the albums 118 | */ 119 | + (NSURLRequest*)createRequestForAlbums:(NSArray *)uris 120 | withAccessToken:(NSString *)accessToken 121 | market:(NSString *)market 122 | error:(NSError **)error; 123 | 124 | 125 | 126 | 127 | 128 | ///--------------------------- 129 | /// @name API Response Parsers 130 | ///--------------------------- 131 | 132 | /** Parse an API Response into an `SPTAlbum` object. 133 | 134 | @param data The API response data 135 | @param response The API response object 136 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 137 | @return an `SPTAlbum` object, or nil if the parsing failed. 138 | */ 139 | + (instancetype)albumFromData:(NSData *)data 140 | withResponse:(NSURLResponse *)response 141 | error:(NSError **)error; 142 | 143 | /** Parse an JSON object structure into an `SPTAlbum` object. 144 | 145 | @param decodedObject The decoded JSON structure to parse. 146 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 147 | @return an `SPTAlbum` object, or nil if the parsing failed. 148 | */ 149 | + (instancetype)albumFromDecodedJSON:(id)decodedObject 150 | error:(NSError **)error; 151 | 152 | /** Parse an JSON object structure into an array of `SPTAlbum` object. 153 | 154 | @param decodedObject The decoded JSON structure to parse. 155 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 156 | @return an `SPTAlbum` object, or nil if the parsing failed. 157 | */ 158 | + (NSArray*)albumsFromDecodedJSON:(id)decodedObject 159 | error:(NSError **)error; 160 | 161 | 162 | 163 | 164 | 165 | ///-------------------------- 166 | /// @name Convenience Methods 167 | ///-------------------------- 168 | 169 | /** Request the album at the given Spotify URI. 170 | 171 | This is a convenience method on top of the [SPTAlbum createRequestForAlbum:withAccessToken:market:error:] and the shared SPTRequest handler. 172 | 173 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 174 | 175 | @param uri The Spotify URI of the album to request. 176 | @param accessToken An optional access token. Can be `nil`. 177 | @param market An optional market parameter. Can be `nil`. 178 | @param block The block to be called when the operation is complete. The block will pass a SPTAlbum object on success, otherwise an error. 179 | */ 180 | + (void)albumWithURI:(NSURL *)uri 181 | accessToken:(NSString *)accessToken 182 | market:(NSString *)market 183 | callback:(SPTRequestCallback)block; 184 | 185 | /** Request multiple albums given an array of Spotify URIs. 186 | 187 | This is a convenience method on top of the [SPTAlbum createRequestForAlbums:withAccessToken:market:error:] and the shared SPTRequest handler. 188 | 189 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 190 | 191 | @param uris An array of Spotify URIs. 192 | @param accessToken An optional access token. Can be `nil`. 193 | @param market An optional market parameter. Can be `nil`. 194 | @param block The block to be called when the operation is complete. The block will pass an array of SPTAlbum objects on success, otherwise an error. 195 | */ 196 | + (void)albumsWithURIs:(NSArray *)uris 197 | accessToken:(NSString *)accessToken 198 | market:(NSString *)market 199 | callback:(SPTRequestCallback)block; 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | ///-------------------- 213 | /// @name Miscellaneous 214 | ///-------------------- 215 | 216 | /** Checks if the Spotify URI is a valid Spotify Album URI. 217 | 218 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 219 | 220 | @param uri The Spotify URI to check. 221 | */ 222 | + (BOOL)isAlbumURI:(NSURL*)uri; 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | @end 231 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTArtist.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTJSONDecoding.h" 19 | #import "SPTRequest.h" 20 | #import "SPTPartialArtist.h" 21 | #import "SPTAlbum.h" 22 | 23 | @class SPTImage; 24 | 25 | /** This class represents an artist on the Spotify service. 26 | 27 | API Docs: https://developer.spotify.com/web-api/get-artist/ 28 | 29 | API Console: https://developer.spotify.com/web-api/console/get-artist 30 | 31 | API Model: https://developer.spotify.com/web-api/object-model/#artist-object-full 32 | */ 33 | @interface SPTArtist : SPTPartialArtist 34 | 35 | 36 | 37 | 38 | ///---------------------------- 39 | /// @name Properties 40 | ///---------------------------- 41 | 42 | /** Any external IDs of the track, such as the ISRC code. */ 43 | @property (nonatomic, readonly, copy) NSDictionary *externalIds; 44 | 45 | /** Returns a list of genre strings for the artist. */ 46 | @property (nonatomic, readonly, copy) NSArray *genres; 47 | 48 | /** Returns a list of artist images in various sizes, as `SPTImage` objects. */ 49 | @property (nonatomic, readonly, copy) NSArray *images; 50 | 51 | /** Convenience method that returns the smallest available artist image. */ 52 | @property (nonatomic, readonly) SPTImage *smallestImage; 53 | 54 | /** Convenience method that returns the largest available artist image. */ 55 | @property (nonatomic, readonly) SPTImage *largestImage; 56 | 57 | /** The popularity of the artist as a value between 0.0 (least popular) to 100.0 (most popular). */ 58 | @property (nonatomic, readonly) double popularity; 59 | 60 | /** The number of followers this artist has. */ 61 | @property (nonatomic, readonly) long followerCount; 62 | 63 | 64 | 65 | 66 | 67 | ///---------------------------- 68 | /// @name API Request Factories 69 | ///---------------------------- 70 | 71 | /** Create a request for fetching an artist 72 | 73 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 74 | 75 | @param uri The Spotify URI of the artist to request. 76 | @param accessToken An optional access token. Can be `nil`. 77 | @param error An optional `NSError` that will be set if an error occured. 78 | @return A NSURLRequest for requesting the album 79 | */ 80 | + (NSURLRequest*)createRequestForArtist:(NSURL *)uri 81 | withAccessToken:(NSString *)accessToken 82 | error:(NSError **)error; 83 | 84 | /** Create a request for fetching a multiple artists 85 | 86 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 87 | 88 | @param uris An array of Spotify URIs. 89 | @param accessToken An optional access token. Can be `nil`. 90 | @param error An optional `NSError` that will be set if an error occured. 91 | @return A NSURLRequest for requesting the albums 92 | */ 93 | + (NSURLRequest*)createRequestForArtists:(NSArray *)uris 94 | withAccessToken:(NSString *)accessToken 95 | error:(NSError **)error; 96 | 97 | /** Request the artist's albums. 98 | 99 | The territory parameter of this method can be `nil` to specify "any country", but expect a lot of 100 | duplicates as the Spotify catalog often has different albums for each country. Pair this with an 101 | `SPTUser`'s `territory` property for best results. 102 | 103 | @param artist The Spotify URI of the artist. 104 | @param type The type of albums to get. 105 | @param accessToken An optional access token. Can be `nil`. 106 | @param market An ISO 3166 country code of the territory to get albums for, or `nil`. 107 | @param error An optional `NSError` that will be set if an error occured. 108 | */ 109 | + (NSURLRequest*)createRequestForAlbumsByArtist:(NSURL*)artist 110 | ofType:(SPTAlbumType)type 111 | withAccessToken:(NSString *)accessToken 112 | market:(NSString *)market 113 | error:(NSError **)error; 114 | 115 | /** Request the artist's top tracks. 116 | 117 | The territory parameter of this method is required. Pair this with an 118 | `SPTUser`'s `territory` property for best results. 119 | 120 | @param artist The Spotify URI of the artist. 121 | @param accessToken An optional access token. Can be `nil`. 122 | @param market An ISO 3166 country code of the territory to get top tracks for. 123 | @param error An optional `NSError` that will be set if an error occured. 124 | */ 125 | + (NSURLRequest*)createRequestForTopTracksForArtist:(NSURL *)artist 126 | withAccessToken:(NSString *)accessToken 127 | market:(NSString *)market 128 | error:(NSError **)error; 129 | 130 | /** Request the artist's related artists. 131 | 132 | @param artist The Spotify URI of the artist. 133 | @param accessToken An optional access token. Can be `nil`. 134 | @param error An optional `NSError` that will be set if an error occured. 135 | */ 136 | + (NSURLRequest*)createRequestForArtistsRelatedTo:(NSURL *)artist 137 | withAccessToken:(NSString *)accessToken 138 | error:(NSError **)error; 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | ///--------------------------- 148 | /// @name API Response Parsers 149 | ///--------------------------- 150 | 151 | /** Parse an API response into an `SPTArtist` object. 152 | 153 | @param data The API response data. 154 | @param response The API response object. 155 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 156 | @return an `SPTAlbum` object, or nil if the parsing failed. 157 | */ 158 | + (instancetype)artistFromData:(NSData *)data 159 | withResponse:(NSURLResponse *)response 160 | error:(NSError **)error; 161 | 162 | /** Parse an JSON object structure into an array of `SPTAlbum` object. 163 | 164 | @param decodedObject The decoded JSON structure to parse. 165 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 166 | @return an `SPTAlbum` object, or nil if the parsing failed. 167 | */ 168 | + (instancetype)artistFromDecodedJSON:(id)decodedObject 169 | error:(NSError **)error; 170 | 171 | /** Parse an API response into an array of `SPTArtist` objects. 172 | 173 | @param data The API response data. 174 | @param response The API response object. 175 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 176 | @return an `SPTAlbum` object, or nil if the parsing failed. 177 | */ 178 | + (NSArray*)artistsFromData:(NSData *)data 179 | withResponse:(NSURLResponse *)response 180 | error:(NSError **)error; 181 | 182 | /** Parse an JSON object structure into an array of `SPTAlbum` object. 183 | 184 | @param decodedObject The decoded JSON structure to parse. 185 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 186 | @return an `SPTAlbum` object, or nil if the parsing failed. 187 | */ 188 | + (NSArray*)artistsFromDecodedJSON:(id)decodedObject 189 | error:(NSError **)error; 190 | 191 | 192 | 193 | 194 | 195 | ///-------------------------- 196 | /// @name Convenience Methods 197 | ///-------------------------- 198 | 199 | /** Request the artist at the given Spotify URI. 200 | 201 | This is a convenience method on top of the `+createRequestForArtist:withAccessToken:error:` and `SPTRequest performRequest:callback:` 202 | 203 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 204 | 205 | @param uri The Spotify URI of the artist to request. 206 | @param accessToken An optional access token. Can be `nil`. 207 | @param block The block to be called when the operation is complete. The block will pass a Spotify SDK metadata object on success, otherwise an error. 208 | */ 209 | +(void)artistWithURI:(NSURL *)uri accessToken:(NSString *)accessToken callback:(SPTRequestCallback)block; 210 | 211 | /** Request multiple artists given an array of Spotify URIs. 212 | 213 | This is a convenience method on top of the `+createRequestForArtists:withAccessToken:error:` and `SPTRequest performRequest:callback:` 214 | 215 | @note This method takes an array Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 216 | 217 | @param uris An array of Spotify URIs. 218 | @param accessToken An optional access token. Can be `nil`. 219 | @param block The block to be called when the operation is complete. The block will pass an array of `SPTArtist` objects on success, otherwise an error. 220 | */ 221 | +(void)artistsWithURIs:(NSArray *)uris accessToken:(NSString *)accessToken callback:(SPTRequestCallback)block; 222 | 223 | /** Request the artist's albums. 224 | 225 | The territory parameter of this method can be `nil` to specify "any country", but expect a lot of 226 | duplicates as the Spotify catalog often has different albums for each country. Pair this with an 227 | `SPTUser`'s `territory` property for best results. 228 | 229 | @param type The type of albums to get. 230 | @param accessToken An optional access token. Can be `nil`. 231 | @param territory An ISO 3166 country code of the territory to get albums for, or `nil`. 232 | @param block The block to be called when the operation is complete. The block will pass an 233 | `SPTListPage` object on success, otherwise an error. 234 | */ 235 | -(void)requestAlbumsOfType:(SPTAlbumType)type 236 | withAccessToken:(NSString *)accessToken 237 | availableInTerritory:(NSString *)territory 238 | callback:(SPTRequestCallback)block; 239 | 240 | /** Request the artist's top tracks. 241 | 242 | The territory parameter of this method is required. Pair this with an 243 | `SPTUser`'s `territory` property for best results. 244 | 245 | @param territory An ISO 3166 country code of the territory to get top tracks for. 246 | @param accessToken An optional access token. Can be `nil`. 247 | @param block The block to be called when the operation is complete. The block will pass an 248 | `NSArray` object containing `SPTTrack`s on success, otherwise an error. 249 | */ 250 | -(void)requestTopTracksForTerritory:(NSString *)territory 251 | withAccessToken:(NSString *)accessToken 252 | callback:(SPTRequestCallback)block; 253 | 254 | /** Request the artist's related artists. 255 | 256 | @param accessToken An optional access token. Can be `nil`. 257 | @param block The block to be called when the operation is complete. The block will pass an 258 | `NSArray` object containing `SPTArtist`s on success, otherwise an error. 259 | */ 260 | -(void)requestRelatedArtistsWithAccessToken:(NSString *)accessToken 261 | callback:(SPTRequestCallback)block; 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | ///-------------------- 272 | /// @name Miscellaneous 273 | ///-------------------- 274 | 275 | /** Checks if the Spotify URI is a valid Spotify Artist URI. 276 | 277 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 278 | 279 | @param uri The Spotify URI to check. 280 | @return True if a valid artist URI. 281 | */ 282 | + (BOOL)isArtistURI:(NSURL *)uri; 283 | 284 | /** Get the identifier part of an Spotify Artist URI. 285 | 286 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 287 | 288 | @param uri The Spotify URI to check. 289 | @return The identifier part of the artist URI. 290 | */ 291 | + (NSString *)identifierFromURI:(NSURL *)uri; 292 | 293 | @end 294 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTBrowse.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTListPage.h" 19 | 20 | /** This class provides helpers for using the browse features in the Spotify API 21 | 22 | API Docs: https://developer.spotify.com/web-api/browse-endpoints/ 23 | 24 | API Console: https://developer.spotify.com/web-api/console/browse/ 25 | */ 26 | @interface SPTBrowse : NSObject 27 | 28 | 29 | 30 | 31 | 32 | 33 | ///---------------------------- 34 | /// @name API Request Factories 35 | ///---------------------------- 36 | 37 | /** Get a list of featured playlists 38 | 39 | Parse the response into an `SPTFeaturedPlaylistList` using `SPTFeaturedPlaylistList playlistListFromData:withResponse:error` 40 | 41 | See https://developer.spotify.com/web-api/get-list-featured-playlists/ for more information on parameters 42 | 43 | @param country A ISO 3166-1 country code to get playlists for, or `nil` to get global recommendations. 44 | @param limit The number of results to return, max 50. 45 | @param offset The index at which to start returning results. 46 | @param locale The locale of the user, for localized recommendations, `nil` will default to American English. 47 | @param timestamp The time of day to get recommendations for (without timezone), or `nil` for current local time 48 | @param accessToken An authenticated access token. Must be valid and authorized. 49 | @param error An optional error value, will be set if the creation of the request failed. 50 | @return The request 51 | */ 52 | + (NSURLRequest *)createRequestForFeaturedPlaylistsInCountry:(NSString *)country 53 | limit:(NSInteger)limit 54 | offset:(NSInteger)offset 55 | locale:(NSString *)locale 56 | timestamp:(NSDate*)timestamp 57 | accessToken:(NSString *)accessToken 58 | error:(NSError **)error; 59 | 60 | /** Get a list of new releases. 61 | 62 | Parse the response into an `SPTListPage` of `SPTAlbum`'s using `SPTListPage listPageFromData:withResponse:error` 63 | 64 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 65 | 66 | @param country A ISO 3166-1 country code to get releases for, or `nil` for global releases. 67 | @param limit The number of results to return, max 50. 68 | @param offset The index at which to start returning results. 69 | @param accessToken An authenticated access token. Must be valid and authorized. 70 | @param error An optional error value, will be set if the creation of the request failed. 71 | */ 72 | + (NSURLRequest *)createRequestForNewReleasesInCountry:(NSString *)country 73 | limit:(NSInteger)limit 74 | offset:(NSInteger)offset 75 | accessToken:(NSString *)accessToken 76 | error:(NSError **)error; 77 | 78 | 79 | 80 | 81 | 82 | 83 | ///--------------------------- 84 | /// @name API Response Parsers 85 | ///--------------------------- 86 | 87 | /** Parse the response from createRequestForNewReleasesInCountry into a list of new releases 88 | 89 | @param data The API response data 90 | @param response The API response object 91 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 92 | @return The list of new releases as an `SPTListPage` object 93 | */ 94 | + (SPTListPage *)newReleasesFromData:(NSData *)data 95 | withResponse:(NSURLResponse *)response 96 | error:(NSError **)error; 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | ///-------------------------- 109 | /// @name Convenience methods 110 | ///-------------------------- 111 | 112 | /** Get a list of featured playlists 113 | 114 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 115 | 116 | See https://developer.spotify.com/web-api/get-list-featured-playlists/ for more information on parameters 117 | 118 | @param country A ISO 3166-1 country code to get playlists for, or `nil` to get global recommendations. 119 | @param limit The number of results to return, max 50. 120 | @param offset The index at which to start returning results. 121 | @param locale The locale of the user, for localized recommendations, `nil` will default to American English. 122 | @param timestamp The time of day to get recommendations for (without timezone), or `nil` for current local time 123 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-modify` scope. 124 | @param accessTokenType The string that describes how the access token may be used. Should always be equal to "Bearer". 125 | @param block The block to be called when the operation is complete, containing a `SPTFeaturedPlaylistList` 126 | */ 127 | + (void)requestFeaturedPlaylistsForCountry:(NSString *)country 128 | limit:(NSInteger)limit 129 | offset:(NSInteger)offset 130 | locale:(NSString *)locale 131 | timestamp:(NSDate*)timestamp 132 | accessToken:(NSString *)accessToken 133 | accessTokenType:(NSString *)accessTokenType 134 | callback:(SPTRequestCallback)block; 135 | 136 | /** Get a list of new releases. 137 | 138 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 139 | 140 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 141 | 142 | @param country A ISO 3166-1 country code to get releases for, or `nil` for global releases. 143 | @param limit The number of results to return, max 50. 144 | @param offset The index at which to start returning results. 145 | @param accessToken An authenticated access token. Must be valid and authorized. 146 | @param block The block to be called when the operation is complete, containing a `SPTListPage` 147 | */ 148 | + (void)requestNewReleasesForCountry:(NSString *)country 149 | limit:(NSInteger)limit 150 | offset:(NSInteger)offset 151 | accessToken:(NSString *)accessToken 152 | callback:(SPTRequestCallback)block; 153 | 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTFeaturedPlaylistList.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTListPage.h" 19 | 20 | /** This object represents a list of featured playlists created from the `SPTBrowse` class 21 | 22 | API Docs: https://developer.spotify.com/web-api/get-list-featured-playlists/ 23 | 24 | See: `SPTBrowse` 25 | */ 26 | @interface SPTFeaturedPlaylistList : SPTListPage 27 | 28 | 29 | 30 | 31 | 32 | ///----------------- 33 | /// @name Properties 34 | ///----------------- 35 | 36 | /** If there's a message associated with the paginated list. */ 37 | @property (nonatomic, readonly) NSString *message; 38 | 39 | 40 | 41 | 42 | 43 | 44 | ///--------------------------- 45 | /// @name API Response Parsers 46 | ///--------------------------- 47 | 48 | + (instancetype)featuredPlaylistListFromData:(NSData *)data 49 | withResponse:(NSURLResponse *)response 50 | error:(NSError **)error; 51 | 52 | + (instancetype)featuredPlaylistListFromDecodedJSON:(id)decodedObject 53 | error:(NSError **)error; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTFollow.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTRequest.h" 19 | 20 | /** This class provides helpers for using the follow features in the Spotify API. 21 | 22 | API Docs: https://developer.spotify.com/web-api/web-api-follow-endpoints/ 23 | 24 | API Console: https://developer.spotify.com/web-api/console/follow/ 25 | 26 | Example of following a user: 27 | 28 | ``` 29 | NSURLRequest *req = [SPTFollow createRequestForFollowingUsers:@[@"possan"]] withAccessToken:@"" error:nil]; 30 | [[SPTRequest sharedHandler] performRequest:req callback:^(NSError *error, NSURLResponse *response, NSData *data) { 31 | long statusCode = ((NSHTTPURLResponse*)response).statusCode; 32 | switch (statusCode) { 33 | case 204: 34 | NSLog(@"Successfully followed user."); 35 | break; 36 | case 401: 37 | case 403: 38 | NSLog(@"Failed to follow user, are you sure your token is valid and have the correct scopes?"); 39 | break; 40 | default: 41 | NSLog(@"Unknown error"); 42 | break; 43 | } 44 | }]; 45 | ``` 46 | 47 | Example of checking if a user is following a playlist: 48 | 49 | ``` 50 | NSError *err2 = nil; 51 | NSURLRequest *req2 = [SPTFollow createRequestForCheckingIfUsers:@[@"possan"] 52 | areFollowingPlaylist:[NSURL URLWithString:@"spotify:user:eldloppa:playlist:4irwclB6noltFaHhqZSWRu"] 53 | withAccessToken:auth.session.accessToken 54 | error:&err2]; 55 | NSLog(@"created request %@", req2); 56 | [[SPTRequest sharedHandler] performRequest:req2 callback:^(NSError *error, NSURLResponse *response, NSData *data) { 57 | NSLog(@"error=%@, response=%@, data=%@", error, response, data); 58 | NSArray *arr = [SPTFollow followingResultFromData:data withResponse:response error:nil]; 59 | NSLog(@"is following? %@", [arr objectAtIndex:0]); 60 | }]; 61 | ``` 62 | 63 | */ 64 | @interface SPTFollow : NSObject 65 | 66 | 67 | 68 | 69 | 70 | 71 | ///---------------------------- 72 | /// @name API Request Factories 73 | ///---------------------------- 74 | 75 | /** Create a request for making the current user follow a list of artist. 76 | 77 | See https://developer.spotify.com/web-api/follow-artists-users/ for more information on parameters 78 | 79 | @param artistUris An array of `NSURL`s for artist to follow. 80 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 81 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 82 | @return The created `NSURLRequest`. 83 | */ 84 | + (NSURLRequest*)createRequestForFollowingArtists:(NSArray*)artistUris 85 | withAccessToken:(NSString *)accessToken 86 | error:(NSError **)error; 87 | 88 | 89 | 90 | /** Create a request for making the current user unfollow a list of artists. 91 | 92 | See https://developer.spotify.com/web-api/unfollow-artists-users/ for more information on parameters 93 | 94 | @param artistUris An array of `NSURL`s for artists to unfollow. 95 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 96 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 97 | @return The created `NSURLRequest`. 98 | */ 99 | + (NSURLRequest*)createRequestForUnfollowingArtists:(NSArray*)artistUris 100 | withAccessToken:(NSString *)accessToken 101 | error:(NSError **)error; 102 | 103 | 104 | 105 | /** Create a request to check if the current user is following a list of artists. 106 | 107 | Parse the response in to an `NSArray` of booleans using `parseFollowingResultData:withResponse:error` 108 | 109 | See https://developer.spotify.com/web-api/check-current-user-follows/ for more information on parameters 110 | 111 | @param artistUris An array of `NSURL`s for artists to check. 112 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 113 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 114 | @return The created `NSURLRequest`. 115 | */ 116 | + (NSURLRequest*)createRequestForCheckingIfFollowingArtists:(NSArray*)artistUris 117 | withAccessToken:(NSString *)accessToken 118 | error:(NSError **)error; 119 | 120 | 121 | 122 | 123 | 124 | /** Create a request to make the current user follow a list of users. 125 | 126 | See https://developer.spotify.com/web-api/follow-artists-users/ for more information on parameters 127 | 128 | @param usernames An array of `NSString`s containing spotify usernames to follow. 129 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 130 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 131 | @return The created `NSURLRequest`. 132 | */ 133 | + (NSURLRequest*)createRequestForFollowingUsers:(NSArray*)usernames 134 | withAccessToken:(NSString *)accessToken 135 | error:(NSError **)error; 136 | 137 | 138 | 139 | /** Create a request to make the current user unfollow a list of users. 140 | 141 | See https://developer.spotify.com/web-api/unfollow-artists-users/ for more information on parameters 142 | 143 | @param usernames An array of `NSString`s containing spotify usernames to unfollow. 144 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 145 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 146 | @return The created `NSURLRequest`. 147 | */ 148 | + (NSURLRequest*)createRequestForUnfollowingUsers:(NSArray*)usernames 149 | withAccessToken:(NSString *)accessToken 150 | error:(NSError **)error; 151 | 152 | 153 | 154 | /** Create a request to check if the current user is following a list of users. 155 | 156 | Parse the response in to an `NSArray` of booleans using `parseFollowingResultData:withResponse:error` 157 | 158 | See https://developer.spotify.com/web-api/check-current-user-follows/ for more information on parameters 159 | 160 | @param username A `NSString`s containing spotify username to check. 161 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 162 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 163 | @return The created `NSURLRequest`. 164 | */ 165 | + (NSURLRequest*)createRequestForCheckingIfFollowingUsers:(NSArray*)username 166 | withAccessToken:(NSString *)accessToken 167 | error:(NSError **)error; 168 | 169 | 170 | 171 | 172 | /** Create a request for following a playlist. 173 | 174 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 175 | 176 | @param playlistUri The playlist URI to follow. 177 | @param secret Follow this playlist secretly. 178 | @param accessToken An authenticated access token. Must be valid and authorized with the `playlist-modify-private` or `playlist-modify-public` scope depending on if you're following it publicly or not. 179 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 180 | @return The created `NSURLRequest`. 181 | */ 182 | + (NSURLRequest*)createRequestForFollowingPlaylist:(NSURL *)playlistUri 183 | withAccessToken:(NSString *)accessToken 184 | secret:(BOOL)secret 185 | error:(NSError **)error; 186 | 187 | 188 | 189 | /** Create a request to check if a user is following a specific playlist. 190 | 191 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 192 | 193 | @param playlistUri A playlist URI. 194 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 195 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 196 | @return The created `NSURLRequest`. 197 | */ 198 | + (NSURLRequest*)createRequestForUnfollowingPlaylist:(NSURL *)playlistUri 199 | withAccessToken:(NSString *)accessToken 200 | error:(NSError **)error; 201 | 202 | 203 | 204 | /** Create a request to check if a user is following a specific playlist. 205 | 206 | Parse the response in to an `NSArray` of booleans using `SPTFollow parseFollowingResultData:withResponse:error` 207 | 208 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 209 | 210 | @param usernames A list of spotify usernames. 211 | @param playlistUri A playlist URI. 212 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-follow-modify` scope. 213 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 214 | @return The created `NSURLRequest`. 215 | */ 216 | + (NSURLRequest*)createRequestForCheckingIfUsers:(NSArray *)usernames 217 | areFollowingPlaylist:(NSURL*)playlistUri 218 | withAccessToken:(NSString *)accessToken 219 | error:(NSError **)error; 220 | 221 | 222 | 223 | 224 | 225 | ///--------------------------- 226 | /// @name API Response Parsers 227 | ///--------------------------- 228 | 229 | /** Parse the result of a "am i following this entity"-query into an array of booleans 230 | 231 | @param data The API response data 232 | @param response The API response object 233 | @param error An optional pointer to a `NSError` that receives an error if request creation failed. 234 | @return An `NSArray` of booleans 235 | */ 236 | + (NSArray*)followingResultFromData:(NSData *)data 237 | withResponse:(NSURLResponse *)response 238 | error:(NSError **)error; 239 | 240 | @end 241 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTImage.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import 19 | 20 | /** This class represents an image from the Spotify service. It could be an 21 | album's cover art or a user image, for example. 22 | 23 | API Model: https://developer.spotify.com/web-api/object-model/#image-object 24 | */ 25 | @interface SPTImage : NSObject 26 | 27 | 28 | 29 | 30 | ///---------------------------- 31 | /// @name Properties 32 | ///---------------------------- 33 | 34 | /** The image's size as reported from the backed. 35 | 36 | @warning This property may be `CGSizeZero` if the size of the image is unknown 37 | by the backend. This is particularly the case with images not owned by Spotify, for 38 | example if a user's image is taken from their Facebook account. 39 | */ 40 | @property (nonatomic, readonly) CGSize size; 41 | 42 | /** The HTTP URL to the image. */ 43 | @property (nonatomic, readonly, copy) NSURL *imageURL; 44 | 45 | 46 | 47 | 48 | 49 | 50 | ///------------------------------- 51 | /// @name Response parsing methods 52 | ///------------------------------- 53 | 54 | + (instancetype)imageFromDecodedJSON:(id)decodedObject 55 | error:(NSError **)error; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTJSONDecoding.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** An object that supports decoding from JSON. */ 20 | @protocol SPTJSONObject 21 | 22 | /** Initialise the object with the given decoded JSON response from the web API 23 | (typically an `NSDictionary`, but not always). 24 | 25 | @param decodedObject The decoded representation of the object. 26 | @param error An error pointer that will contain an error if a problem occurred. 27 | @return Returns the initalised object, or `nil` if a problem occurred. 28 | */ 29 | -(id)initWithDecodedJSONObject:(id)decodedObject error:(NSError **)error; 30 | 31 | /** Returns the original decoded object (typically an `NSDictionary`, but not always) 32 | that was used to create the object. Useful for serialising. */ 33 | @property (nonatomic, readonly, copy) id decodedJSONObject; 34 | 35 | @end 36 | 37 | /** Helper class for decoding JSON from the Spotify web API. You shouldn't need to use this 38 | in your application — use `SPTRequest` instead. */ 39 | @interface SPTJSONDecoding : NSObject 40 | 41 | ///---------------------------- 42 | /// @name JSON Decoding 43 | ///---------------------------- 44 | 45 | /** Convert an object decoded from JSON into a Spotify SDK metadata object. 46 | 47 | @param decodedJson The object decoded from JSON. 48 | @param error A pointer to an error object that will be filled if an error occurs. 49 | @return The generated object, or `nil` if an error occurs. 50 | */ 51 | +(id)SPObjectFromDecodedJSON:(id)decodedJson error:(NSError **)error; 52 | 53 | /** Convert an object from the given JSON data into a Spotify SDK metadata object. 54 | 55 | @param json The JSON data. 56 | @param error A pointer to an error object that will be filled if an error occurs. 57 | @return The generated object, or `nil` if an error occurs. 58 | */ 59 | +(id)SPObjectFromEncodedJSON:(NSData *)json error:(NSError **)error; 60 | 61 | 62 | /** Convert an object decoded from JSON into a partial Spotify SDK metadata object. 63 | 64 | @param decodedJson The object decoded from JSON. 65 | @param error A pointer to an error object that will be filled if an error occurs. 66 | @return The generated object, or `nil` if an error occurs. 67 | */ 68 | +(id)partialSPObjectFromDecodedJSON:(id)decodedJson error:(NSError **)error; 69 | 70 | /** Convert an object from the given JSON data into a partial Spotify SDK metadata object. 71 | 72 | @param json The JSON data. 73 | @param error A pointer to an error object that will be filled if an error occurs. 74 | @return The generated object, or `nil` if an error occurs. 75 | */ 76 | +(id)partialSPObjectFromEncodedJSON:(NSData *)json error:(NSError **)error; 77 | 78 | @end 79 | 80 | /** Base object for JSON based models. */ 81 | @interface SPTJSONObjectBase : NSObject 82 | 83 | @property (nonatomic, readwrite, copy) id decodedJSONObject; 84 | 85 | @end 86 | 87 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTListPage.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTRequest.h" 19 | #import "SPTTrackProvider.h" 20 | 21 | /** This class represents a page within a paginated list. 22 | 23 | For the sake of conserving resources, lists that have the potential to be very large 24 | (such as search results, a playlist or album's tracks, etc) are not delivered as a whole 25 | from the Spotify backend - instead, such lists are paginated. This class allows you 26 | to work with those pages. 27 | 28 | API Model: https://developer.spotify.com/web-api/object-model/#paging-object 29 | */ 30 | @interface SPTListPage : NSObject 31 | 32 | 33 | 34 | 35 | 36 | ///----------------- 37 | /// @name Properties 38 | ///----------------- 39 | 40 | /** The range of the receiver within the source list. */ 41 | @property (nonatomic, readonly) NSRange range; 42 | 43 | /** The length of the source list. */ 44 | @property (nonatomic, readonly) NSUInteger totalListLength; 45 | 46 | /** Returns `YES` if there is at least one page in the source list after the receiver, otherwise `NO`. */ 47 | @property (nonatomic, readonly) BOOL hasNextPage; 48 | 49 | /** Returns `YES` if there is at least one page in the source list before the receiver, otherwise `NO`. */ 50 | @property (nonatomic, readonly) BOOL hasPreviousPage; 51 | 52 | /** Returns the API url to the next page of items if it exist, otherwise `nil`. */ 53 | @property (nonatomic, readonly, copy) NSURL *nextPageURL; 54 | 55 | /** Returns the API url to the previous page of items if it exist, otherwise `nil`. */ 56 | @property (nonatomic, readonly, copy) NSURL *previousPageURL; 57 | 58 | /** Returns `YES` if the page contains every single item in the source list, otherwise `NO`. */ 59 | @property (nonatomic, readonly) BOOL isComplete; 60 | 61 | /** The items contained in the page the receiver represents. */ 62 | @property (nonatomic, readonly, copy) NSArray *items; 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | ///---------------------------- 81 | /// @name API Request Factories 82 | ///---------------------------- 83 | 84 | /** Create a request for fetching the next page in the source list. 85 | 86 | @param accessToken An authenticated access token. Must be valid and authorized. 87 | @param error An optional `NSError` that will be set if an error occured. 88 | */ 89 | - (NSURLRequest*)createRequestForNextPageWithAccessToken:(NSString *)accessToken error:(NSError**)error; 90 | 91 | /** Create a request for fetching the previous page in the source list. 92 | 93 | @param accessToken An authenticated access token. Must be valid and authorized. 94 | @param error An optional `NSError` that will be set if an error occured. 95 | */ 96 | - (NSURLRequest*)createRequestForPreviousPageWithAccessToken:(NSString *)accessToken error:(NSError**)error; 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | ///--------------------------- 105 | /// @name API Response Parsers 106 | ///--------------------------- 107 | 108 | /** Create a SPTListPage from a API response 109 | 110 | @param data The API Response data 111 | @param response The API Response object 112 | @param hasPartialChildren True if api response provides partial entities, not full ones. 113 | @param rootObjectKey The name of the entity with the actual content, or `nil` if the same as the root. 114 | @param error An optional pointer to a `NSError` object that will be set if an error occured. 115 | @return A `SPTListPage`, or nil if an error occured. 116 | */ 117 | + (instancetype)listPageFromData:(NSData *)data 118 | withResponse:(NSURLResponse *)response 119 | expectingPartialChildren:(BOOL)hasPartialChildren 120 | rootObjectKey:(NSString *)rootObjectKey 121 | error:(NSError **)error; 122 | 123 | /** Create a SPTListPage from a decoded JSON structure 124 | 125 | @param decodedObject The JSON root entity 126 | @param hasPartialChildren True if api response provides partial entities, not full ones. 127 | @param rootObjectKey The name of the entity with the actual content, or `nil` if the same as the root. 128 | @param error An optional pointer to a `NSError` object that will be set if an error occured. 129 | @return A `SPTListPage`, or nil if an error occured. 130 | */ 131 | + (instancetype)listPageFromDecodedJSON:(id)decodedObject 132 | expectingPartialChildren:(BOOL)hasPartialChildren 133 | rootObjectKey:(NSString *)rootObjectKey 134 | error:(NSError **)error; 135 | 136 | 137 | 138 | 139 | 140 | 141 | ///---------------------------- 142 | /// @name Navigation and Manipulation 143 | ///---------------------------- 144 | 145 | /** Create a new page by adding a page to the receiver. 146 | 147 | @warning The added page *must* start immediately after the receiver - that is, 148 | `nextPage.range.location` must equal `self.range.location + self.range.length`. 149 | 150 | @param nextPage The page to add to the receiver. 151 | @return A new `SPTListPage` containing the union of the receiver and nextPage. 152 | */ 153 | - (instancetype)pageByAppendingPage:(SPTListPage *)nextPage; 154 | 155 | /** Request the next page in the source list. 156 | 157 | @param accessToken An authenticated access token. Must be valid and authorized. 158 | @param block The block to be called when the operation is complete. This block will pass an error if the operation 159 | failed, otherwise the next `SPTListPage` in the source list. 160 | */ 161 | - (void)requestNextPageWithAccessToken:(NSString *)accessToken callback:(SPTRequestCallback)block; 162 | 163 | /** Request the previous page in the source list. 164 | 165 | @param accessToken An authenticated access token. Must be valid and authorized. 166 | @param block The block to be called when the operation is complete. This block will pass an error if the operation 167 | failed, otherwise the previous `SPTListPage` in the source list. 168 | */ 169 | - (void)requestPreviousPageWithAccessToken:(NSString *)accessToken callback:(SPTRequestCallback)block; 170 | 171 | 172 | 173 | 174 | @end 175 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTMetadataTypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** Defines a callback block for an operation that has a chance of generating an error. 20 | 21 | If the operation was successful, `error` will be `nil`, otherwise it will contain an `NSError` 22 | object describing the failure.*/ 23 | typedef void (^SPTMetadataErrorableOperationCallback)(NSError *error); -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPartialAlbum.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTPartialObject.h" 19 | #import "SPTJSONDecoding.h" 20 | 21 | /// Defines the various types albums can be in relation to a given artist. 22 | typedef NS_ENUM(NSUInteger, SPTAlbumType) { 23 | /// Specifies that the given album is a "standard" album. 24 | SPTAlbumTypeAlbum, 25 | /// Specifies that the given album is a single. 26 | SPTAlbumTypeSingle, 27 | /// Specifies that the given album is a compilation album. 28 | SPTAlbumTypeCompilation, 29 | /// Specifies that the given album is an "appears on" album that the artist appears on, but didn't author. 30 | SPTAlbumTypeAppearsOn 31 | }; 32 | 33 | @class SPTImage; 34 | 35 | /** Represents a "partial" album on the Spotify service. You can promote this to a full album object using `SPTAlbum`. 36 | 37 | API Model: https://developer.spotify.com/web-api/object-model/#album-object-simplified 38 | */ 39 | @interface SPTPartialAlbum : SPTJSONObjectBase 40 | 41 | 42 | 43 | 44 | 45 | ///---------------------------- 46 | /// @name Properties 47 | ///---------------------------- 48 | 49 | /** The id of the track. */ 50 | @property (nonatomic, readonly, copy) NSString *identifier; 51 | 52 | /** The name of the album. */ 53 | @property (nonatomic, readonly, copy) NSString *name; 54 | 55 | /** The Spotify URI of the album. */ 56 | @property (nonatomic, readonly, copy) NSURL *uri; 57 | 58 | /** A playable Spotify URI for this album. */ 59 | @property (nonatomic, readonly, copy) NSURL *playableUri; 60 | 61 | /** The HTTP open.spotify.com URL of the album. */ 62 | @property (nonatomic, readonly, copy) NSURL *sharingURL; 63 | 64 | /** Returns a list of album covers in various sizes, as `SPTImage` objects. */ 65 | @property (nonatomic, readonly, copy) NSArray *covers; 66 | 67 | /** Convenience method that returns the smallest available cover image. */ 68 | @property (nonatomic, readonly) SPTImage *smallestCover; 69 | 70 | /** Convenience method that returns the largest available cover image. */ 71 | @property (nonatomic, readonly) SPTImage *largestCover; 72 | 73 | /** Returns the album type of this album. */ 74 | @property (nonatomic, readonly) SPTAlbumType type; 75 | 76 | /** An array of ISO 3166 country codes in which the album is available. */ 77 | @property (nonatomic, readonly, copy) NSArray *availableTerritories; 78 | 79 | 80 | 81 | 82 | 83 | ///------------------------------ 84 | /// @name Parsers / Deserializers 85 | ///------------------------------ 86 | 87 | + (instancetype)partialAlbumFromDecodedJSON:(id)decodedObject 88 | error:(NSError **)error; 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPartialArtist.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTPartialObject.h" 19 | #import "SPTJSONDecoding.h" 20 | 21 | /** Represents a "partial" artist on the Spotify service. You can promote this 22 | to a full artist object using `SPTArtist`. 23 | 24 | API Model: https://developer.spotify.com/web-api/object-model/#artist-object-simplified 25 | */ 26 | @interface SPTPartialArtist : SPTJSONObjectBase 27 | 28 | 29 | 30 | 31 | 32 | ///----------------- 33 | /// @name Properties 34 | ///----------------- 35 | 36 | /** The id of the artist. */ 37 | @property (nonatomic, readonly, copy) NSString *identifier; 38 | 39 | /** A playable Spotify URI for this artist. */ 40 | @property (nonatomic, readonly, copy) NSURL *playableUri; 41 | 42 | /** The HTTP open.spotify.com URL of the artist. */ 43 | @property (nonatomic, readonly, copy) NSURL *sharingURL; 44 | 45 | 46 | 47 | 48 | 49 | ///------------------------------ 50 | /// @name Parsers / Deserializers 51 | ///------------------------------ 52 | 53 | + (instancetype)partialArtistFromDecodedJSON:(id)decodedObject 54 | error:(NSError **)error; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPartialObject.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** Represents the base class of a "partial" object on the Spotify service.. */ 20 | @protocol SPTPartialObject 21 | 22 | ///---------------------------- 23 | /// @name Properties 24 | ///---------------------------- 25 | 26 | /** The name of the object. */ 27 | @property (nonatomic, readonly, copy) NSString *name; 28 | 29 | /** The Spotify URI of the object. */ 30 | @property (nonatomic, readonly, copy) NSURL *uri; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPartialPlaylist.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTPartialObject.h" 19 | #import "SPTJSONDecoding.h" 20 | #import "SPTTrackProvider.h" 21 | #import "SPTImage.h" 22 | 23 | @class SPTUser; 24 | 25 | /** Represents a "partial" playlist on the Spotify service. You can promote this 26 | to a full playlist object using `SPTPlaylistSnapshot`. 27 | 28 | API Model: https://developer.spotify.com/web-api/object-model/#playlist-object-simplified 29 | 30 | Playlist Guide: https://developer.spotify.com/web-api/working-with-playlists/ 31 | */ 32 | @interface SPTPartialPlaylist : SPTJSONObjectBase 33 | 34 | 35 | 36 | 37 | 38 | ///---------------------------- 39 | /// @name Properties 40 | ///---------------------------- 41 | 42 | /** The name of the playlist. */ 43 | @property (nonatomic, readonly, copy) NSString *name; 44 | 45 | /** The Spotify URI of the playlist. */ 46 | @property (nonatomic, readonly, copy) NSURL *uri; 47 | 48 | /** The playable Spotify URI for the playlist. */ 49 | @property (nonatomic, readonly, copy) NSURL *playableUri; 50 | 51 | /** The owner of the playlist. */ 52 | @property (nonatomic, readonly) SPTUser *owner; 53 | 54 | /** `YES` if the playlist is collaborative (i.e., can be modified by anyone), otherwise `NO`. */ 55 | @property (nonatomic, readonly) BOOL isCollaborative; 56 | 57 | /** `YES` if the playlist is public (i.e., can be seen by anyone), otherwise `NO`. */ 58 | @property (nonatomic, readonly) BOOL isPublic; 59 | 60 | /** The number of tracks in the playlist. */ 61 | @property (nonatomic, readonly) NSUInteger trackCount; 62 | 63 | /** Returns a list of playlist image in various sizes, as `SPTImage` objects. 64 | 65 | Will be `nil` if the playlist doesn't have a custom image. 66 | */ 67 | @property (nonatomic, readonly, copy) NSArray *images; 68 | 69 | /** Convenience method that returns the smallest available playlist image. 70 | 71 | Will be `nil` if the playlist doesn't have a custom image. 72 | */ 73 | @property (nonatomic, readonly) SPTImage *smallestImage; 74 | 75 | /** Convenience method that returns the largest available playlist image. 76 | 77 | Will be `nil` if the playlist doesn't have a custom image. 78 | */ 79 | @property (nonatomic, readonly) SPTImage *largestImage; 80 | 81 | 82 | 83 | 84 | ///------------------------------ 85 | /// @name Parsers / Deserializers 86 | ///------------------------------ 87 | 88 | + (instancetype)partialPlaylistFromDecodedJSON:(id)decodedObject 89 | error:(NSError **)error; 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPartialTrack.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTJSONDecoding.h" 19 | #import "SPTPartialObject.h" 20 | #import "SPTTrackProvider.h" 21 | #import "SPTPartialAlbum.h" 22 | 23 | /** Represents a "partial" track on the Spotify service. You can promote this 24 | to a full track object using `SPTTrack`. 25 | 26 | API Model: https://developer.spotify.com/web-api/object-model/#track-object-simplified 27 | 28 | API Docs: https://developer.spotify.com/web-api/track-endpoints/ 29 | */ 30 | @interface SPTPartialTrack : SPTJSONObjectBase 31 | 32 | 33 | 34 | 35 | 36 | ///---------------------------- 37 | /// @name Properties 38 | ///---------------------------- 39 | 40 | /** The id of the track. */ 41 | @property (nonatomic, readonly, copy) NSString *identifier; 42 | 43 | /** The name of the track. */ 44 | @property (nonatomic, readonly, copy) NSString *name; 45 | 46 | /** A playable Spotify URI for this track. */ 47 | @property (nonatomic, readonly, copy) NSURL *playableUri; 48 | 49 | /** The HTTP open.spotify.com URL of the track. */ 50 | @property (nonatomic, readonly, copy) NSURL *sharingURL; 51 | 52 | /** The duration of the track. */ 53 | @property (nonatomic, readonly) NSTimeInterval duration; 54 | 55 | /** The artists of the track, as `SPTPartialArtist` objects. */ 56 | @property (nonatomic, readonly, copy) NSArray *artists; 57 | 58 | /** The disc number of the track. I.e., if it's the first disc on the album this will be `1`. */ 59 | @property (nonatomic, readonly) NSInteger discNumber; 60 | 61 | /** Returns `YES` if the track is flagged as explicit, otherwise `NO`. */ 62 | @property (nonatomic, readonly) BOOL flaggedExplicit; 63 | 64 | /** Returns `YES` if the track is flagged as playable, otherwise `NO`, if no market is passed to the api call, this will default to `YES`. */ 65 | @property (nonatomic, readonly) BOOL isPlayable; 66 | 67 | /** Returns `YES` if the track has a playable status, only available if market passed to the api call. */ 68 | @property (nonatomic, readonly) BOOL hasPlayable; 69 | 70 | /** An array of ISO 3166 country codes in which the album is available. */ 71 | @property (nonatomic, readonly, copy) NSArray *availableTerritories; 72 | 73 | /** The HTTP URL of a 30-second preview MP3 of the track. */ 74 | @property (nonatomic, readonly, copy) NSURL *previewURL; 75 | 76 | /** The track number of the track. I.e., if it's the first track on the album this will be `1`. */ 77 | @property (nonatomic, readonly) NSInteger trackNumber; 78 | 79 | /** The album this track belongs to. */ 80 | @property (nonatomic, readonly, strong) SPTPartialAlbum *album; 81 | 82 | 83 | 84 | ///------------------------------- 85 | /// @name Response parsing methods 86 | ///------------------------------- 87 | 88 | /** 89 | Convert a parsed HTTP response into an SPTPartialTrack object 90 | 91 | @param decodedObject The decoded JSON object structure. 92 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 93 | */ 94 | + (instancetype)partialTrackFromDecodedJSON:(id)decodedObject 95 | error:(NSError **)error; 96 | 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPlaylistList.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTPlaylistSnapshot.h" 19 | #import "SPTListPage.h" 20 | 21 | /** The callback that gets called after a playlist creation, will contain your newly created playlist. */ 22 | typedef void (^SPTPlaylistCreationCallback)(NSError *error, SPTPlaylistSnapshot *playlist); 23 | 24 | /** This class represents a user's list of playlists, and also contains methods for listing and creating new playlists on behalf of a user. 25 | 26 | API Docs: https://developer.spotify.com/web-api/playlist-endpoints/ 27 | 28 | API Console: https://developer.spotify.com/web-api/console/playlists/ 29 | 30 | Playlist Guide: https://developer.spotify.com/web-api/working-with-playlists/ 31 | 32 | */ 33 | @interface SPTPlaylistList : SPTListPage 34 | 35 | 36 | 37 | 38 | ///------------------------- 39 | /// @name Creating playlists 40 | ///------------------------- 41 | 42 | /** 43 | Create a new playlist and add it to the this playlist list. 44 | 45 | See: https://developer.spotify.com/web-api/create-playlist/ 46 | 47 | @param name The name of the newly-created playlist. 48 | @param username The user to create the playlist for. (Needs to be the currently authenticated user) 49 | @param isPublic Whether the newly-created playlist is public. 50 | @param accessToken An authenticated access token. Must be valid and authorized with the `playlist-modify-public` or `playlist-modify-private` scope as necessary. 51 | @param block The callback block to be fired when playlist creation is completed (or fails). 52 | */ 53 | + (void)createPlaylistWithName:(NSString *)name 54 | forUser:(NSString *)username 55 | publicFlag:(BOOL)isPublic 56 | accessToken:(NSString *)accessToken 57 | callback:(SPTPlaylistCreationCallback)block; 58 | 59 | 60 | 61 | ///--------------------------------- 62 | /// @name Listing a user's playlists 63 | ///--------------------------------- 64 | 65 | /** Get the a user's playlist list. 66 | 67 | See: https://developer.spotify.com/web-api/get-list-users-playlists/ 68 | 69 | @param username The username of the user to get playlists for. 70 | @param accessToken An authenticated access token. Must be valid and authorized with the unspecified or `playlist-read-private` scope as necessary. 71 | @param block The block to be called when the operation is complete. The block will pass an `SPTPlaylistList` object on success, otherwise an error. 72 | */ 73 | + (void)playlistsForUser:(NSString *)username 74 | withAccessToken:(NSString *)accessToken 75 | callback:(SPTRequestCallback)block; 76 | 77 | ///------------------------------------------------ 78 | /// @name Playlist listing request creation methods 79 | ///------------------------------------------------ 80 | 81 | /** 82 | Create a request for creating a new playlist and add it to the current users' playlists. 83 | 84 | See: https://developer.spotify.com/web-api/create-playlist/ 85 | 86 | @param name The name of the newly-created playlist. 87 | @param username The username of the user to create the playlist for. (Must be the current user) 88 | @param isPublic Whether the newly-created playlist is public. 89 | @param accessToken An authenticated access token. Must be valid and authorized with the `playlist-modify-public` or `playlist-modify-private` scope as necessary. 90 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 91 | */ 92 | + (NSURLRequest*)createRequestForCreatingPlaylistWithName:(NSString *)name 93 | forUser:(NSString *)username 94 | withPublicFlag:(BOOL)isPublic 95 | accessToken:(NSString *)accessToken 96 | error:(NSError **)error; 97 | 98 | /** Get the a user's playlist list. 99 | 100 | Example: 101 | 102 | ``` 103 | // Getting the first two pages of a playlists for a user 104 | NSURLRequest *playlistrequest = [SPTPlaylistList createRequestForGettingPlaylistsForUser:@"possan" withAccessToken:accessToken error:nil]; 105 | [[SPTRequest sharedHandler] performRequest:playlistrequest callback:^(NSError *error, NSURLResponse *response, NSData *data) { 106 | if (error != nil) { Handle error } 107 | SPTPlaylistList *playlists = [SPTPlaylistList playlistListFromData:data withResponse:response error:nil]; 108 | NSLog(@"Got possan's playlists, first page: %@", playlists); 109 | NSURLRequest *playlistrequest2 = [playlists createRequestForNextPageWithAccessToken:accessToken error:nil]; 110 | [[SPTRequest sharedHandler] performRequest:playlistrequest2 callback:^(NSError *error2, NSURLResponse *response2, NSData *data2) { 111 | if (error2 != nil) { Handle error } 112 | SPTPlaylistList *playlists2 = [SPTPlaylistList playlistListFromData:data2 withResponse:response2 error:nil]; 113 | NSLog(@"Got possan's playlists, second page: %@", playlists2); 114 | }]; 115 | }]; 116 | ``` 117 | 118 | See: https://developer.spotify.com/web-api/get-list-users-playlists/ 119 | 120 | @param username The username of the user to get playlists for. 121 | @param accessToken An authenticated access token. Must be valid and authorized with the unspecified or `playlist-read-private` scope as necessary. 122 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 123 | */ 124 | + (NSURLRequest*)createRequestForGettingPlaylistsForUser:(NSString *)username 125 | withAccessToken:(NSString *)accessToken 126 | error:(NSError **)error; 127 | 128 | 129 | 130 | 131 | 132 | ///------------------------------ 133 | /// @name Parsers / Deserializers 134 | ///------------------------------ 135 | 136 | /** 137 | Parse the response of an API call into an `SPTPlaylistList` object 138 | 139 | @param data The API response data 140 | @param response The API response object 141 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 142 | */ 143 | + (instancetype)playlistListFromData:(NSData*)data 144 | withResponse:(NSURLResponse*)response 145 | error:(NSError **)error; 146 | 147 | /** 148 | Parse a decoded JSON object into an `SPTPlaylistList` object 149 | 150 | @param decodedObject The decoded JSON object 151 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 152 | */ 153 | + (instancetype)playlistListFromDecodedJSON:(id)decodedObject 154 | error:(NSError **)error; 155 | 156 | @end 157 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTPlaylistTrack.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import "SPTTrack.h" 18 | 19 | @class SPTUser; 20 | 21 | /** Represents a track in a playlist on the Spotify service. */ 22 | @interface SPTPlaylistTrack : SPTTrack 23 | 24 | /** The date when the track was added. */ 25 | @property (nonatomic, readonly, copy) NSDate *addedAt; 26 | 27 | /** The user who added the track. */ 28 | @property (nonatomic, readonly) SPTUser *addedBy; 29 | @end 30 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTRequest.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTPartialObject.h" 19 | 20 | /** Callback for requests 21 | 22 | @param error An optional error indicating that the operation failed, or `nil` if it succeeded. 23 | @param object The result of the operation 24 | */ 25 | typedef void (^SPTRequestCallback)(NSError *error, id object); 26 | 27 | /** Callback for `SPTRequestHandlerProtocol` 28 | 29 | @param error An optional error indicating that the request failed, or `nil` if it succeeded. 30 | @param response The `NSURLResponse` for the request 31 | @param data An `NSData` containing the result of the request 32 | */ 33 | typedef void (^SPTRequestDataCallback)(NSError *error, NSURLResponse *response, NSData *data); 34 | 35 | /// Defines types of result objects that can be searched for. 36 | typedef NS_ENUM(NSUInteger, SPTSearchQueryType) { 37 | /// Specifies that all search results will be of type `SPTTrack`. 38 | SPTQueryTypeTrack = 0, 39 | /// Specifies that all search results will be of type `SPTArtist`. 40 | SPTQueryTypeArtist, 41 | /// Specifies that all search results will be of type `SPTAlbum`. 42 | SPTQueryTypeAlbum, 43 | /// Specifies that all search results will be of type `SPTPartialPlaylist`. 44 | SPTQueryTypePlaylist, 45 | }; 46 | 47 | FOUNDATION_EXPORT NSString * const SPTMarketFromToken; 48 | 49 | /** Protocol for request handlers 50 | */ 51 | @protocol SPTRequestHandlerProtocol 52 | 53 | /** 54 | Make a request 55 | 56 | @param request The NSURLRequest object for the request. 57 | @param block The callback to call when data has been received. 58 | */ 59 | -(void)performRequest:(NSURLRequest *)request callback:(SPTRequestDataCallback)block; 60 | 61 | @end 62 | 63 | 64 | 65 | /** This class provides convenience methods for talking to the Spotify Web API and wraps a customizable handler for requests which are used by those convenience methods. 66 | 67 | All the functions for direct access to the api inside this class has been deprecated and moved out to their respective classes, for getting track metadata, look at `SPTTrack`, for getting featured playlists in browse, look at `SPTBrowse` and so on. 68 | 69 | All model classes provide both convenience methods for getting content in the callback fashion, but also provides methods named `createRequestFor...` for creating `NSURLRequests` for calling the api directly with the request handler of choice, this allows you to do caching, cancellation and scheduling of calls in your own way. The model classes also provides methods for parsing a API Response back into a usable object, those are called `...fromData:withResponse:error`, pluralized methods for getting multiple entities at once are also available when appropriate. 70 | 71 | 72 | Example of using the API request creation / API response parser paradigm: 73 | 74 | ``` 75 | // Getting the first two pages of a playlists for a user 76 | NSURLRequest *playlistrequest = [SPTPlaylistList createRequestForGettingPlaylistsForUser:@"possan" withAccessToken:accessToken error:nil]; 77 | [[SPTRequest sharedHandler] performRequest:playlistrequest callback:^(NSError *error, NSURLResponse *response, NSData *data) { 78 | if (error != nil) { Handle error } 79 | SPTPlaylistList *playlists = [SPTPlaylistList playlistListFromData:data withResponse:response error:nil]; 80 | NSLog(@"Got possan's playlists, first page: %@", playlists); 81 | NSURLRequest *playlistrequest2 = [playlists createRequestForNextPageWithAccessToken:accessToken error:nil]; 82 | [[SPTRequest sharedHandler] performRequest:playlistrequest2 callback:^(NSError *error2, NSURLResponse *response2, NSData *data2) { 83 | if (error2 != nil) { Handle error } 84 | SPTPlaylistList *playlists2 = [SPTPlaylistList playlistListFromData:data2 withResponse:response2 error:nil]; 85 | NSLog(@"Got possan's playlists, second page: %@", playlists2); 86 | }]; 87 | }]; 88 | ``` 89 | 90 | Example without response body: 91 | 92 | ``` 93 | // Following a user 94 | NSURLRequest *req = [SPTFollow createRequestForFollowingUsers:@[@"possan"]] withAccessToken:accessToken error:nil]; 95 | [[SPTRequest sharedHandler] performRequest:req callback:^(NSError *error, NSURLResponse *response, NSData *data) { 96 | long statusCode = ((NSHTTPURLResponse*)response).statusCode; 97 | switch (statusCode) { 98 | case 204: 99 | NSLog(@"Successfully followed user."); 100 | break; 101 | case 401: 102 | case 403: 103 | NSLog(@"Failed to follow user, are you sure your token is valid and have the correct scopes?"); 104 | break; 105 | default: 106 | NSLog(@"Bork bork!"); 107 | break; 108 | } 109 | }]; 110 | ``` 111 | 112 | Example of using convenience methods: 113 | 114 | ``` 115 | // Getting multiple artists 116 | [SPTArtist artistsWithURIs:@[ 117 | [NSURL URLWithString:@"spotify:artist:30Y7JOpiNgAGEhnkYPdI1P"], 118 | [NSURL URLWithString:@"spotify:artist:0jO0TlgxW9Il5JphAWzhR4"], 119 | [NSURL URLWithString:@"spotify:artist:0AKlaf8M1k8NjJp1uCOlTA"] 120 | ] 121 | accessToken:accessToken callback:^(NSError *error, id object) { 122 | NSLog(@"Got artists: %@", object); 123 | }]; 124 | ``` 125 | 126 | API Console: https://developer.spotify.com/web-api/console 127 | 128 | */ 129 | @interface SPTRequest : NSObject 130 | 131 | 132 | 133 | 134 | 135 | ///---------------------- 136 | /// @name Request handler 137 | ///---------------------- 138 | 139 | /** 140 | Get a request handler 141 | */ 142 | + (id)sharedHandler; 143 | 144 | /** 145 | Override the default request handler, this is where you'd implement your own if you want to, or use AFNetworking or similar 146 | 147 | @param handler New handler for requests 148 | */ 149 | + (void)setSharedHandler:(id)handler; 150 | 151 | ///------------------------------- 152 | /// @name Request creation helpers 153 | ///------------------------------- 154 | 155 | /** Helper function for creates an authenticated `NSURLRequest` for a Spotify API resource. 156 | 157 | @param url The HTTPS URL to request, this is a Spotify API URL, not a spotify URI. 158 | @param accessToken A valid access token, or `nil` if authentication isn't needed. 159 | @param httpMethod The HTTP method to use eg. `GET` `POST` etc. 160 | @param values The arguments to send to the URL 161 | @param encodeAsJSON Encode arguments as an JSON object in the body of the request instead of QueryString encoding them. 162 | @param dataAsQueryString Send arguments as a part of the query string instead of in the body of the request. 163 | @param error An optional `NSError` that will receive an error if request creation failed. 164 | @return A `NSURLRequest` 165 | */ 166 | 167 | + (NSURLRequest *)createRequestForURL:(NSURL *)url 168 | withAccessToken:(NSString *)accessToken 169 | httpMethod:(NSString *)httpMethod 170 | values:(id)values 171 | valueBodyIsJSON:(BOOL)encodeAsJSON 172 | sendDataAsQueryString:(BOOL)dataAsQueryString 173 | error:(NSError **)error; 174 | 175 | 176 | @end 177 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTSavedTrack.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTTrack.h" 19 | 20 | /** This class represents a track in the Your Music Library. 21 | 22 | API Model: https://developer.spotify.com/web-api/object-model/#saved-track-object 23 | */ 24 | @interface SPTSavedTrack : SPTTrack 25 | 26 | ///---------------------------- 27 | /// @name Properties 28 | ///---------------------------- 29 | 30 | /** The date when the track was saved. */ 31 | @property (nonatomic, readonly, copy) NSDate *addedAt; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTSearch.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTRequest.h" 19 | #import "SPTListPage.h" 20 | 21 | /** This class provides helpers for using the search features in the Spotify API, See: https://developer.spotify.com/web-api/console/search/ */ 22 | @interface SPTSearch : NSObject 23 | 24 | 25 | 26 | 27 | 28 | ///---------------------------- 29 | /// @name Search 30 | ///---------------------------- 31 | 32 | /** Performs a search with a given query, offset and market filtering 33 | 34 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 35 | 36 | @param searchQuery The query to pass to the search. 37 | @param searchQueryType The type of search to do. 38 | @param offset The index at which to start returning results. 39 | @param accessToken A valid access token, or `nil`. 40 | @param market Either a ISO 3166-1 country code to filter the results to, or "from_token" (`SPTMarketFromToken`) to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 41 | @param block The block to be called when the operation is complete. The block will pass an `SPTListPage` containing results on success, otherwise an error. 42 | */ 43 | +(void)performSearchWithQuery:(NSString *)searchQuery 44 | queryType:(SPTSearchQueryType)searchQueryType 45 | offset:(NSInteger)offset 46 | accessToken:(NSString *)accessToken 47 | market:(NSString *)market 48 | callback:(SPTRequestCallback)block; 49 | 50 | /** Create a request for searching with a given query, offset and market filtering 51 | 52 | @param searchQuery The query to pass to the search. 53 | @param searchQueryType The type of search to do. 54 | @param offset The index at which to start returning results. 55 | @param accessToken A valid access token, or `nil`. 56 | @param market Either a ISO 3166-1 country code to filter the results to, or "from_token" (`SPTMarketFromToken`) to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 57 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 58 | */ 59 | +(NSURLRequest*)createRequestForSearchWithQuery:(NSString *)searchQuery 60 | queryType:(SPTSearchQueryType)searchQueryType 61 | offset:(NSInteger)offset 62 | accessToken:(NSString *)accessToken 63 | market:(NSString *)market 64 | error:(NSError**)error; 65 | 66 | /** Performs a search with a given query and market filtering 67 | 68 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 69 | 70 | @param searchQuery The query to pass to the search. 71 | @param searchQueryType The type of search to do. 72 | @param accessToken A valid access token, or `nil`. 73 | @param market Either a ISO 3166-1 country code to filter the results to, or `from_token` to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 74 | @param block The block to be called when the operation is complete. The block will pass an `SPTListPage` containing results on success, otherwise an error. 75 | */ 76 | +(void)performSearchWithQuery:(NSString *)searchQuery 77 | queryType:(SPTSearchQueryType)searchQueryType 78 | accessToken:(NSString *)accessToken 79 | market:(NSString *)market 80 | callback:(SPTRequestCallback)block; 81 | 82 | /** Createa a query for searching with a given query and market filtering 83 | 84 | @param searchQuery The query to pass to the search. 85 | @param searchQueryType The type of search to do. 86 | @param accessToken A valid access token, or `nil`. 87 | @param market Either a ISO 3166-1 country code to filter the results to, or `from_token` to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 88 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 89 | */ 90 | + (NSURLRequest*)createRequestForSearchWithQuery:(NSString *)searchQuery 91 | queryType:(SPTSearchQueryType)searchQueryType 92 | accessToken:(NSString *)accessToken 93 | market:(NSString *)market 94 | error:(NSError**)error; 95 | 96 | /** Performs a search with a given query and offset 97 | 98 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 99 | 100 | @param searchQuery The query to pass to the search. 101 | @param searchQueryType The type of search to do. 102 | @param offset The index at which to start returning results. 103 | @param accessToken A valid access token, or `nil`. 104 | @param block The block to be called when the operation is complete. The block will pass an `SPTListPage` containing results on success, otherwise an error. 105 | */ 106 | + (void)performSearchWithQuery:(NSString *)searchQuery 107 | queryType:(SPTSearchQueryType)searchQueryType 108 | offset:(NSInteger)offset 109 | accessToken:(NSString *)accessToken 110 | callback:(SPTRequestCallback)block; 111 | 112 | /** Create a request for searching with a given query and offset 113 | 114 | @param searchQuery The query to pass to the search. 115 | @param searchQueryType The type of search to do. 116 | @param offset The index at which to start returning results. 117 | @param accessToken A valid access token, or `nil`. 118 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 119 | */ 120 | + (NSURLRequest*)createRequestForSearchWithQuery:(NSString *)searchQuery 121 | queryType:(SPTSearchQueryType)searchQueryType 122 | offset:(NSInteger)offset 123 | accessToken:(NSString *)accessToken 124 | error:(NSError**)error; 125 | 126 | /** Performs a search with a given query. 127 | 128 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 129 | 130 | @param searchQuery The query to pass to the search. 131 | @param searchQueryType The type of search to do. 132 | @param accessToken A valid access token, or `nil`. 133 | @param block The block to be called when the operation is complete. The block will pass an `SPTListPage` containing results on success, otherwise an error. 134 | */ 135 | + (void)performSearchWithQuery:(NSString *)searchQuery 136 | queryType:(SPTSearchQueryType)searchQueryType 137 | accessToken:(NSString *)accessToken 138 | callback:(SPTRequestCallback)block; 139 | 140 | /** Create a request for searching with a given query. 141 | 142 | @param searchQuery The query to pass to the search. 143 | @param searchQueryType The type of search to do. 144 | @param accessToken A valid access token, or `nil`. 145 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 146 | */ 147 | + (NSURLRequest*)createRequestForSearchWithQuery:(NSString *)searchQuery 148 | queryType:(SPTSearchQueryType)searchQueryType 149 | accessToken:(NSString *)accessToken 150 | error:(NSError**)error; 151 | 152 | 153 | 154 | 155 | 156 | ///------------------------------ 157 | /// @name Parsers / Deserializers 158 | ///------------------------------ 159 | 160 | /** Parse the response from createRequestForSearch into a list of search results 161 | 162 | @param data The API response data 163 | @param response The API response object 164 | @param searchQueryType The type of search to do. 165 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 166 | @return The list of search results as an `SPTListPage` object 167 | */ 168 | + (SPTListPage *)searchResultsFromData:(NSData *)data 169 | withResponse:(NSURLResponse *)response 170 | queryType:(SPTSearchQueryType)searchQueryType 171 | error:(NSError **)error; 172 | 173 | /** Parse the response from createRequestForSearch into a list of search results 174 | 175 | @param decodedObject The decoded JSON object structure 176 | @param searchQueryType The type of search to do. 177 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 178 | @return The list of search results as an `SPTListPage` object 179 | */ 180 | + (SPTListPage *)searchResultsFromDecodedJSON:(id)decodedObject 181 | queryType:(SPTSearchQueryType)searchQueryType 182 | error:(NSError **)error; 183 | 184 | @end 185 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTTrack.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTJSONDecoding.h" 19 | #import "SPTPartialAlbum.h" 20 | #import "SPTPartialTrack.h" 21 | #import "SPTRequest.h" 22 | 23 | /** This class represents a track on the Spotify service. 24 | 25 | API Docs: https://developer.spotify.com/web-api/track-endpoints/ 26 | 27 | API Console: https://developer.spotify.com/web-api/console/tracks/ 28 | 29 | API Model: https://developer.spotify.com/web-api/object-model/#track-object-full 30 | */ 31 | @interface SPTTrack : SPTPartialTrack 32 | 33 | 34 | 35 | 36 | 37 | 38 | ///---------------------------- 39 | /// @name Properties 40 | ///---------------------------- 41 | 42 | /** The popularity of the track as a value between 0.0 (least popular) to 100.0 (most popular). */ 43 | @property (nonatomic, readonly) double popularity; 44 | 45 | /** Any external IDs of the track, such as the ISRC code. */ 46 | @property (nonatomic, readonly, copy) NSDictionary *externalIds; 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ///---------------------------- 56 | /// @name API Request Factories 57 | ///---------------------------- 58 | 59 | /** Create a request for fetching one track. 60 | 61 | Parse the response into an `SPTListPage` using `SPTTrack trackFromData:withResponse:error:` 62 | 63 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 64 | 65 | @param uri The Spotify URI of the track to request. 66 | @param accessToken An access token, or `nil`. 67 | @param market Either a ISO 3166-1 country code to filter the results to, or `from_token` to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 68 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 69 | */ 70 | + (NSURLRequest *)createRequestForTrack:(NSURL *)uri 71 | withAccessToken:(NSString *)accessToken 72 | market:(NSString *)market 73 | error:(NSError **)error; 74 | 75 | /** Create a request for fetching multiple rtacks 76 | 77 | Parse the response into an `NSArray` of `SPTTrack`-objects using `SPTTrack trackFromDecodedJSON:` 78 | 79 | See https://developer.spotify.com/web-api/get-list-new-releases/ for more information on parameters 80 | 81 | @param uris An array of Spotify Track URIs. 82 | @param accessToken An access token, or `nil`. 83 | @param market Either a ISO 3166-1 country code to filter the results to, or `from_token` to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 84 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 85 | */ 86 | + (NSURLRequest *)createRequestForTracks:(NSArray *)uris 87 | withAccessToken:(NSString *)accessToken 88 | market:(NSString *)market 89 | error:(NSError **)error; 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | ///--------------------------- 99 | /// @name API Response Parsers 100 | ///--------------------------- 101 | 102 | /** Parse an JSON object structure into an array of `SPTTrack` object. 103 | 104 | @param data The API response data 105 | @param response The API response object 106 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 107 | @return an `SPTTrack` object, or nil if the parsing failed. 108 | */ 109 | + (instancetype)trackFromData:(NSData *)data 110 | withResponse:(NSURLResponse *)response 111 | error:(NSError **)error; 112 | 113 | /** Parse an JSON object structure into an array of `SPTTrack` object. 114 | 115 | @param decodedObject The decoded JSON structure to parse. 116 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 117 | @return an `SPTAlbum` object, or nil if the parsing failed. 118 | */ 119 | + (instancetype)trackFromDecodedJSON:(id)decodedObject 120 | error:(NSError **)error; 121 | 122 | /** Parse an JSON object structure into an array of `SPTTrack` object. 123 | 124 | @param data The API response data 125 | @param response The API response object 126 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 127 | @return an array of `SPTTrack` objects, or nil if the parsing failed. 128 | */ 129 | + (NSArray *)tracksFromData:(NSData *)data 130 | withResponse:(NSURLResponse *)response 131 | error:(NSError **)error; 132 | 133 | /** Parse an JSON object structure into an array of `SPTTrack` objects. 134 | 135 | @param decodedObject The decoded JSON structure to parse. 136 | @param error An optional `NSError` that will be set if an error occured when parsing the data. 137 | @return an `SPTAlbum` object, or nil if the parsing failed. 138 | */ 139 | + (NSArray*)tracksFromDecodedJSON:(id)decodedObject 140 | error:(NSError **)error; 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | ///-------------------------- 150 | /// @name Convenience Methods 151 | ///-------------------------- 152 | 153 | /** Request the track at the given Spotify URI. 154 | 155 | This is a convenience method on top of the `SPTTrack createRequestForTracks:withAccessToken:error:` and `SPTRequest performRequest:callback:` methods 156 | 157 | See: https://developer.spotify.com/web-api/get-track/ 158 | 159 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 160 | 161 | @param uri The Spotify URI of the track to request. 162 | @param accessToken An access token, or `nil`. 163 | @param market Either a ISO 3166-1 country code to filter the results to, or `from_token` to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 164 | @param block The block to be called when the operation is complete. The block will pass a Spotify SDK metadata object on success, otherwise an error. 165 | */ 166 | + (void)trackWithURI:(NSURL *)uri accessToken:(NSString *)accessToken market:(NSString *)market callback:(SPTRequestCallback)block; 167 | 168 | /** Request multiple tracks with given an array of Spotify URIs. 169 | 170 | This is a convenience method on top of the `SPTTrack createRequestForTracks:withAccessToken:error:` and `SPTRequest performRequest:callback:` methods 171 | 172 | See: https://developer.spotify.com/web-api/get-several-tracks/ 173 | 174 | @note This method takes an array of Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 175 | 176 | @param uris An array of Spotify Track URIs. 177 | @param accessToken An access token, or `nil`. 178 | @param market Either a ISO 3166-1 country code to filter the results to, or `from_token` to pick the market from the session (requires the `user-read-private` scope), or `nil` for no market filtering. 179 | @param block The block to be called when the operation is complete. The block will pass an array of Spotify SDK metadata objects on success, otherwise an error. 180 | */ 181 | 182 | + (void)tracksWithURIs:(NSArray *)uris accessToken:(NSString *)accessToken market:(NSString *)market callback:(SPTRequestCallback)block; 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | ///-------------------- 191 | /// @name Miscellaneous 192 | ///-------------------- 193 | 194 | /** Checks if the Spotify URI is a valid Spotify Track URI. 195 | 196 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 197 | 198 | @param uri The Spotify URI to check. 199 | */ 200 | + (BOOL)isTrackURI:(NSURL*)uri; 201 | 202 | /** Returns the identifier for a Spotify Track uri. 203 | 204 | @note This method takes Spotify URIs in the form `spotify:*`, NOT HTTP URLs. 205 | 206 | @param uri An track uri. 207 | @return The track id, or `nil` if an invalid track uri was passed. 208 | */ 209 | + (NSString *)identifierFromURI:(NSURL *)uri; 210 | 211 | /** Returns a list of track id's from an array containing either `SPTPartialTrack`, `SPTTrack` or `NSURL`'s 212 | 213 | @param tracks An array of tracks. 214 | @return An array of track id's. 215 | */ 216 | + (NSArray*)identifiersFromArray:(NSArray *)tracks; 217 | 218 | /** Returns a list of track uri's as `NSURL`'s from an array containing either `SPTPartialTrack`, `SPTTrack` or `NSURL`'s 219 | 220 | @param tracks An array of tracks. 221 | @return An array of track uri's. 222 | */ 223 | + (NSArray*)urisFromArray:(NSArray *)tracks; 224 | 225 | /** Returns a list of track uri's as `NSString`'s from an array containing either `SPTPartialTrack`, `SPTTrack` or `NSURL`'s 226 | 227 | @param tracks An array of tracks. 228 | @return An array of track uri strings. 229 | */ 230 | + (NSArray*)uriStringsFromArray:(NSArray *)tracks; 231 | 232 | @end 233 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTTrackProvider.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | 19 | /** This protocol defines an object that can be played by `SPTAudioStreamingController`. */ 20 | @protocol SPTTrackProvider 21 | 22 | /** Returns the tracks for playback if no player-supported URI. */ 23 | -(NSArray *)tracksForPlayback; 24 | 25 | /** Returns the URI to this set of tracks, nil if not supported by player. */ 26 | -(NSURL *)playableUri; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTUser.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTJSONDecoding.h" 19 | #import "SPTRequest.h" 20 | 21 | @class SPTImage; 22 | 23 | /** Represents a user's product level. */ 24 | typedef NS_ENUM(NSUInteger, SPTProduct) { 25 | /** The user has a Spotify Free account. */ 26 | SPTProductFree, 27 | /** The user has a Spotify Unlimited account. */ 28 | SPTProductUnlimited, 29 | /** The user has a Spotify Premium account. */ 30 | SPTProductPremium, 31 | /** The user's product level is unknown. */ 32 | SPTProductUnknown 33 | }; 34 | 35 | /** This class represents a user on the Spotify service. 36 | 37 | API Model: https://developer.spotify.com/web-api/object-model/#user-object-private 38 | 39 | API Console: https://developer.spotify.com/web-api/console/user%20profiles/ 40 | */ 41 | @interface SPTUser : SPTJSONObjectBase 42 | 43 | 44 | 45 | 46 | 47 | ///---------------------------- 48 | /// @name Properties 49 | ///---------------------------- 50 | 51 | /** The full display name of the user. 52 | 53 | Will be `nil` unless your session has been granted the 54 | ``user-read-private`` scope. 55 | */ 56 | @property (nonatomic, readonly, copy) NSString *displayName; 57 | 58 | /** The canonical user name of the user. Not necessarily appropriate 59 | for UI use. 60 | */ 61 | @property (nonatomic, readonly, copy) NSString *canonicalUserName; 62 | 63 | /** An ISO 3166 country code of the user's account. */ 64 | @property (nonatomic, readonly, copy) NSString *territory; 65 | 66 | /** The user's email address. 67 | 68 | Will be `nil` unless your session has been granted the 69 | `user-read-email` scope. 70 | */ 71 | @property (nonatomic, readonly, copy) NSString *emailAddress; 72 | 73 | /** The Spotify URI of the user. */ 74 | @property (nonatomic, readonly, copy) NSURL *uri; 75 | 76 | /** The HTTP open.spotify.com URL of the user. */ 77 | @property (nonatomic, readonly, copy) NSURL *sharingURL; 78 | 79 | /** Returns a list of user images in various sizes, as `SPTImage` objects. 80 | 81 | Will be `nil` unless your session has been granted the 82 | ``user-read-private`` scope. 83 | */ 84 | @property (nonatomic, readonly, copy) NSArray *images; 85 | 86 | /** Convenience method that returns the smallest available user image. 87 | 88 | Will be `nil` unless your session has been granted the 89 | ``user-read-private`` scope. 90 | */ 91 | @property (nonatomic, readonly) SPTImage *smallestImage; 92 | 93 | /** Convenience method that returns the largest available user image. 94 | 95 | Will be `nil` unless your session has been granted the 96 | ``user-read-private`` scope. 97 | */ 98 | @property (nonatomic, readonly) SPTImage *largestImage; 99 | 100 | /** The product of the user. For example, only Premium users can stream audio. 101 | 102 | Will be `SPTProductUnknown` unless your session has been granted the 103 | ``user-read-private`` scope. 104 | */ 105 | @property (nonatomic, readonly) SPTProduct product; 106 | 107 | /** The number of followers this user has. */ 108 | @property (nonatomic, readonly) long followerCount; 109 | 110 | 111 | 112 | 113 | 114 | 115 | ///------------------------------- 116 | /// @name Request creation methods 117 | ///------------------------------- 118 | 119 | /** 120 | Create a NSURLRequest for requesting the current user 121 | 122 | See: https://developer.spotify.com/web-api/console/get-current-user/ 123 | 124 | @param accessToken An authenticated access token. Must be valid and authorized. 125 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 126 | */ 127 | + (NSURLRequest *)createRequestForCurrentUserWithAccessToken:(NSString *)accessToken error:(NSError **)error; 128 | 129 | /** 130 | Request current user 131 | 132 | See: https://developer.spotify.com/web-api/console/get-current-user/ 133 | 134 | @param accessToken An authenticated access token. Must be valid and authorized. 135 | @param block The block to be called when the operation is complete. The block will pass a Spotify SDK metadata object on success, otherwise an error. 136 | */ 137 | +(void)requestCurrentUserWithAccessToken:(NSString *)accessToken callback:(SPTRequestCallback)block; 138 | 139 | /** 140 | Request a user profile 141 | 142 | See: https://developer.spotify.com/web-api/console/get-users-profile/ 143 | 144 | @param username The username of the user to request 145 | @param accessToken An authenticated access token that must be valid and authorized or `nil`. 146 | @param block The block to be called when the operation is complete. The block will pass a Spotify SDK metadata object on success, otherwise an error. 147 | */ 148 | +(void)requestUser:(NSString *)username withAccessToken:(NSString *)accessToken callback:(SPTRequestCallback)block; 149 | 150 | 151 | 152 | 153 | 154 | ///------------------------------- 155 | /// @name Response parsing methods 156 | ///------------------------------- 157 | 158 | /** 159 | Convert a HTTP response into a SPTUser object 160 | 161 | See: https://developer.spotify.com/web-api/object-model/#user-object-private and https://developer.spotify.com/web-api/object-model/#user-object-public 162 | 163 | @param data The response body 164 | @param response The response headers 165 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 166 | */ 167 | + (instancetype)userFromData:(NSData *)data 168 | withResponse:(NSURLResponse *)response 169 | error:(NSError **)error; 170 | 171 | 172 | /** 173 | Convert a decoded response into a SPTUser object 174 | 175 | See: https://developer.spotify.com/web-api/object-model/#user-object-private and https://developer.spotify.com/web-api/object-model/#user-object-public 176 | 177 | @param decodedObject The decoded JSON object structure. 178 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 179 | */ 180 | + (instancetype)userFromDecodedJSON:(id)decodedObject 181 | error:(NSError **)error; 182 | 183 | @end 184 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SPTYourMusic.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2015 Spotify AB 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #import 18 | #import "SPTRequest.h" 19 | 20 | /** This class provides helpers for using the your music features in the Spotify API. 21 | 22 | API Docs: https://developer.spotify.com/web-api/browse-endpoints/ 23 | 24 | API Console: https://developer.spotify.com/web-api/console/user%20library/ 25 | */ 26 | @interface SPTYourMusic : NSObject 27 | 28 | 29 | 30 | 31 | 32 | ///---------------------------- 33 | /// @name API Request Factories 34 | ///---------------------------- 35 | 36 | /** Create a request for getting the authenticated user's Your Music library tracks 37 | 38 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-read` scope. 39 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 40 | */ 41 | + (NSURLRequest*)createRequestForCurrentUsersSavedTracksWithAccessToken:(NSString *)accessToken 42 | error:(NSError **)error; 43 | 44 | /** Create a request for adding a set of tracks to the authenticated user's Your Music library. 45 | 46 | @param tracks An array of `SPTTrack`, `SPTPartialTrack` or `NSURI` objects. 47 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-modify` scope. 48 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 49 | */ 50 | + (NSURLRequest*)createRequestForSavingTracks:(NSArray *)tracks 51 | forUserWithAccessToken:(NSString *)accessToken 52 | error:(NSError **)error; 53 | 54 | /** Create a request for checking whether the authenticated user's Your Music library contains a set of tracks. 55 | 56 | @param tracks An array of `SPTTrack`, `SPTPartialTrack` or `NSURL` objects. 57 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-read` scope. 58 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 59 | */ 60 | + (NSURLRequest*)createRequestForCheckingIfSavedTracksContains:(NSArray *)tracks 61 | forUserWithAccessToken:(NSString *)accessToken 62 | error:(NSError **)error; 63 | 64 | /** Create a request for removing a set of tracks from the authenticated user's Your Music library. 65 | 66 | @param tracks An array of `SPTTrack`, `SPTPartialTrack` or `NSURL` objects. 67 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-modify` scope. 68 | @param error An optional pointer to an `NSError` that will receive the error code if operation failed. 69 | */ 70 | + (NSURLRequest*)createRequestForRemovingTracksFromSaved:(NSArray *)tracks 71 | forUserWithAccessToken:(NSString *)accessToken 72 | error:(NSError **)error; 73 | 74 | 75 | 76 | 77 | 78 | ///-------------------------- 79 | /// @name Convenience Methods 80 | ///-------------------------- 81 | 82 | /** Gets the authenticated user's Your Music Library tracks 83 | 84 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 85 | 86 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-read` scope. 87 | @param block The block to be called when the operation is complete, with the data set if success, otherwise an error. 88 | */ 89 | + (void)savedTracksForUserWithAccessToken:(NSString *)accessToken 90 | callback:(SPTRequestCallback)block; 91 | 92 | /** Adds a set of tracks to the authenticated user's Your Music Library. 93 | 94 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 95 | 96 | @param tracks An array of `SPTTrack`, `SPTPartialTrack` or `NSURI` objects. 97 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-modify` scope. 98 | @param block The block to be called when the operation is complete, with the data set if success, otherwise an error. 99 | */ 100 | + (void)saveTracks:(NSArray *)tracks 101 | forUserWithAccessToken:(NSString *)accessToken 102 | callback:(SPTRequestCallback)block; 103 | 104 | /** Checks whether the authenticated user's Your Music Library contains a set of tracks. 105 | 106 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 107 | 108 | @param tracks An array of `SPTTrack`, `SPTPartialTrack` or `NSURI` objects. 109 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-read` scope. 110 | @param block The block to be called when the operation is complete, with the data set if success, otherwise an error. 111 | */ 112 | + (void)savedTracksContains:(NSArray *)tracks 113 | forUserWithAccessToken:(NSString *)accessToken 114 | callback:(SPTRequestCallback)block; 115 | 116 | /** Removes a set of tracks from the authenticated user's Your Music Library. 117 | 118 | This is a convenience method around the createRequest equivalent and the current `SPTRequestHandlerProtocol` 119 | 120 | @param tracks An array of `SPTTrack`, `SPTPartialTrack` or `NSURL` objects. 121 | @param accessToken An authenticated access token. Must be valid and authorized with the `user-library-modify` scope. 122 | @param block The block to be called when the operation is complete, with the data set if success, otherwise an error. 123 | */ 124 | + (void)removeTracksFromSaved:(NSArray *)tracks 125 | forUserWithAccessToken:(NSString *)accessToken 126 | callback:(SPTRequestCallback)block; 127 | 128 | 129 | 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Headers/SpotifyMetadata.h: -------------------------------------------------------------------------------- 1 | // 2 | // Spotify Metadata Framework.h 3 | // Spotify Metadata Framework 4 | // 5 | // Created by Dmytro Ankudinov on 27/09/16. 6 | // Copyright © 2016 Spotify AB. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Spotify Metadata Framework. 12 | FOUNDATION_EXPORT double SpotifyMetadataVersionNumber; 13 | 14 | //! Project version string for Spotify Metadata Framework. 15 | FOUNDATION_EXPORT const unsigned char SpotifyMetadataVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import 20 | #import 21 | #import 22 | #import 23 | #import 24 | #import 25 | #import 26 | #import 27 | #import 28 | #import 29 | #import 30 | #import 31 | #import 32 | #import 33 | #import 34 | #import 35 | #import 36 | #import 37 | #import 38 | #import 39 | #import 40 | #import 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/SpotifyMetadata.framework/Info.plist -------------------------------------------------------------------------------- /SpotifyTest/SpotifyMetadata.framework/SpotifyMetadata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sethmr/SpotifyInSwift/f95ef7ffd305a7acd90a7e73bf347aead10899c8/SpotifyTest/SpotifyMetadata.framework/SpotifyMetadata -------------------------------------------------------------------------------- /SpotifyTest/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SpotifyTest 4 | // 5 | // Created by Seth Rininger on 11/11/16. 6 | // Copyright © 2016 Seth Rininger. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import AudioToolbox 11 | import AVFoundation 12 | 13 | class ViewController: UIViewController, SPTAudioStreamingDelegate, SPTAudioStreamingPlaybackDelegate { 14 | 15 | @IBOutlet weak var trackTitle: UILabel! 16 | @IBOutlet weak var prevButton: UIButton! 17 | @IBOutlet weak var nextButton: UIButton! 18 | @IBOutlet weak var coverView: UIImageView! 19 | @IBOutlet weak var coverView2: UIImageView! 20 | @IBOutlet weak var spinner: UIActivityIndicatorView! 21 | @IBOutlet weak var progressSlider: UISlider! 22 | @IBOutlet weak var playbackSourceTitle: UILabel! 23 | @IBOutlet weak var artistTitle: UILabel! 24 | 25 | var isChangingProgress: Bool = false 26 | let audioSession = AVAudioSession.sharedInstance() 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | self.trackTitle.text = "Nothing Playing" 30 | self.artistTitle.text = "" 31 | } 32 | 33 | override var prefersStatusBarHidden: Bool { 34 | return true 35 | } 36 | 37 | @IBAction func rewind(_ sender: UIButton) { 38 | SPTAudioStreamingController.sharedInstance().skipPrevious(nil) 39 | } 40 | 41 | @IBAction func playPause(_ sender: UIButton) { 42 | SPTAudioStreamingController.sharedInstance().setIsPlaying(!SPTAudioStreamingController.sharedInstance().playbackState.isPlaying, callback: nil) 43 | } 44 | 45 | @IBAction func fastForward(_ sender: UIButton) { 46 | SPTAudioStreamingController.sharedInstance().skipNext(nil) 47 | } 48 | 49 | @IBAction func seekValueChanged(_ sender: UISlider) { 50 | self.isChangingProgress = false 51 | let dest = SPTAudioStreamingController.sharedInstance().metadata!.currentTrack!.duration * Double(self.progressSlider.value) 52 | SPTAudioStreamingController.sharedInstance().seek(to: dest, callback: nil) 53 | } 54 | 55 | @IBAction func logoutClicked(_ sender: UIButton) { 56 | if (SPTAudioStreamingController.sharedInstance() != nil) { 57 | SPTAudioStreamingController.sharedInstance().logout() 58 | } 59 | else { 60 | _ = self.navigationController!.popViewController(animated: true) 61 | } 62 | 63 | } 64 | 65 | @IBAction func proggressTouchDown(_ sender: UISlider) { 66 | self.isChangingProgress = true 67 | } 68 | 69 | func applyBlur(on imageToBlur: UIImage, withRadius blurRadius: CGFloat) -> UIImage { 70 | let originalImage = CIImage(cgImage: imageToBlur.cgImage!) 71 | let filter = CIFilter(name: "CIGaussianBlur") 72 | filter?.setValue(originalImage, forKey: "inputImage") 73 | filter?.setValue(blurRadius, forKey: "inputRadius") 74 | let outputImage = filter?.outputImage 75 | let context = CIContext(options: nil) 76 | let outImage = context.createCGImage(outputImage!, from: outputImage!.extent) 77 | let ret = UIImage(cgImage: outImage!) 78 | return ret 79 | } 80 | 81 | 82 | func updateUI() { 83 | let auth = SPTAuth.defaultInstance() 84 | if SPTAudioStreamingController.sharedInstance().metadata == nil || SPTAudioStreamingController.sharedInstance().metadata.currentTrack == nil { 85 | self.coverView.image = nil 86 | self.coverView2.image = nil 87 | return 88 | } 89 | self.spinner.startAnimating() 90 | self.nextButton.isEnabled = SPTAudioStreamingController.sharedInstance().metadata.nextTrack != nil 91 | self.prevButton.isEnabled = SPTAudioStreamingController.sharedInstance().metadata.prevTrack != nil 92 | self.trackTitle.text = SPTAudioStreamingController.sharedInstance().metadata.currentTrack?.name 93 | self.artistTitle.text = SPTAudioStreamingController.sharedInstance().metadata.currentTrack?.artistName 94 | self.playbackSourceTitle.text = SPTAudioStreamingController.sharedInstance().metadata.currentTrack?.playbackSourceName 95 | 96 | 97 | SPTTrack.track(withURI: URL(string: SPTAudioStreamingController.sharedInstance().metadata.currentTrack!.uri)!, accessToken: auth!.session.accessToken, market: nil) { error, result in 98 | 99 | if let track = result as? SPTTrack { 100 | let imageURL = track.album.largestCover.imageURL 101 | if imageURL == nil { 102 | print("Album \(track.album) doesn't have any images!") 103 | self.coverView.image = nil 104 | self.coverView2.image = nil 105 | return 106 | } 107 | // Pop over to a background queue to load the image over the network. 108 | 109 | DispatchQueue.global().async { 110 | do { 111 | let imageData = try Data(contentsOf: imageURL!, options: []) 112 | let image = UIImage(data: imageData) 113 | // …and back to the main queue to display the image. 114 | DispatchQueue.main.async { 115 | self.spinner.stopAnimating() 116 | self.coverView.image = image 117 | if image == nil { 118 | print("Couldn't load cover image with error: \(error)") 119 | return 120 | } 121 | } 122 | // Also generate a blurry version for the background 123 | let blurred = self.applyBlur(on: image!, withRadius: 10.0) 124 | DispatchQueue.main.async { 125 | self.coverView2.image = blurred 126 | } 127 | 128 | } catch let error { 129 | print(error.localizedDescription) 130 | } 131 | } 132 | } 133 | } 134 | 135 | } 136 | 137 | override func viewDidAppear(_ animated: Bool) { 138 | super.viewDidAppear(animated) 139 | self.handleNewSession() 140 | print("session: \(SPTAuth.defaultInstance().session.accessToken!)") 141 | } 142 | 143 | 144 | func handleNewSession() { 145 | do { 146 | try SPTAudioStreamingController.sharedInstance().start(withClientId: SPTAuth.defaultInstance().clientID, audioController: nil, allowCaching: true) 147 | SPTAudioStreamingController.sharedInstance().delegate = self 148 | SPTAudioStreamingController.sharedInstance().playbackDelegate = self 149 | SPTAudioStreamingController.sharedInstance().diskCache = SPTDiskCache() /* capacity: 1024 * 1024 * 64 */ 150 | SPTAudioStreamingController.sharedInstance().login(withAccessToken: SPTAuth.defaultInstance().session.accessToken!) 151 | } catch let error { 152 | let alert = UIAlertController(title: "Error init", message: error.localizedDescription, preferredStyle: .alert) 153 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 154 | self.present(alert, animated: true, completion: { _ in }) 155 | self.closeSession() 156 | } 157 | } 158 | 159 | func closeSession() { 160 | do { 161 | try SPTAudioStreamingController.sharedInstance().stop() 162 | SPTAuth.defaultInstance().session = nil 163 | _ = self.navigationController!.popViewController(animated: true) 164 | } catch let error { 165 | let alert = UIAlertController(title: "Error deinit", message: error.localizedDescription, preferredStyle: .alert) 166 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 167 | self.present(alert, animated: true, completion: { _ in }) 168 | } 169 | } 170 | 171 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didReceiveMessage message: String) { 172 | let alert = UIAlertController(title: "Message from Spotify", message: message, preferredStyle: .alert) 173 | alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) 174 | self.present(alert, animated: true, completion: { _ in }) 175 | } 176 | 177 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChangePlaybackStatus isPlaying: Bool) { 178 | print("is playing = \(isPlaying)") 179 | if isPlaying { 180 | self.activateAudioSession() 181 | } 182 | else { 183 | self.deactivateAudioSession() 184 | } 185 | } 186 | 187 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChange metadata: SPTPlaybackMetadata) { 188 | self.updateUI() 189 | } 190 | 191 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didReceive event: SpPlaybackEvent, withName name: String) { 192 | print("didReceivePlaybackEvent: \(event) \(name)") 193 | print("isPlaying=\(SPTAudioStreamingController.sharedInstance().playbackState.isPlaying) isRepeating=\(SPTAudioStreamingController.sharedInstance().playbackState.isRepeating) isShuffling=\(SPTAudioStreamingController.sharedInstance().playbackState.isShuffling) isActiveDevice=\(SPTAudioStreamingController.sharedInstance().playbackState.isActiveDevice) positionMs=\(SPTAudioStreamingController.sharedInstance().playbackState.position)") 194 | } 195 | 196 | func audioStreamingDidLogout(_ audioStreaming: SPTAudioStreamingController) { 197 | self.closeSession() 198 | } 199 | 200 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didReceiveError error: Error?) { 201 | print("didReceiveError: \(error!.localizedDescription)") 202 | } 203 | 204 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didChangePosition position: TimeInterval) { 205 | if self.isChangingProgress { 206 | return 207 | } 208 | let positionDouble = Double(position) 209 | let durationDouble = Double(SPTAudioStreamingController.sharedInstance().metadata.currentTrack!.duration) 210 | self.progressSlider.value = Float(positionDouble / durationDouble) 211 | } 212 | 213 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didStartPlayingTrack trackUri: String) { 214 | print("Starting \(trackUri)") 215 | print("Source \(SPTAudioStreamingController.sharedInstance().metadata.currentTrack?.playbackSourceUri)") 216 | // If context is a single track and the uri of the actual track being played is different 217 | // than we can assume that relink has happended. 218 | let isRelinked = SPTAudioStreamingController.sharedInstance().metadata.currentTrack!.playbackSourceUri.contains("spotify:track") && !(SPTAudioStreamingController.sharedInstance().metadata.currentTrack!.playbackSourceUri == trackUri) 219 | print("Relinked \(isRelinked)") 220 | } 221 | 222 | func audioStreaming(_ audioStreaming: SPTAudioStreamingController, didStopPlayingTrack trackUri: String) { 223 | print("Finishing: \(trackUri)") 224 | } 225 | 226 | func audioStreamingDidLogin(_ audioStreaming: SPTAudioStreamingController) { 227 | self.updateUI() 228 | SPTAudioStreamingController.sharedInstance().playSpotifyURI("spotify:user:spotify:playlist:2yLXxKhhziG2xzy7eyD4TD", startingWith: 0, startingWithPosition: 10) { error in 229 | if error != nil { 230 | print("*** failed to play: \(error)") 231 | return 232 | } 233 | } 234 | } 235 | 236 | func activateAudioSession() { 237 | do { 238 | try audioSession.setCategory(AVAudioSessionCategoryPlayback) 239 | try audioSession.setActive(true) 240 | } 241 | catch let error { 242 | print(error.localizedDescription) 243 | } 244 | } 245 | 246 | func deactivateAudioSession() { 247 | do { 248 | try AVAudioSession.sharedInstance().setActive(false) 249 | } 250 | catch let error { 251 | print(error.localizedDescription) 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /SpotifyTest/WebViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WebViewController.swift 3 | // SpotifyTest 4 | // 5 | // Created by Seth Rininger on 11/11/16. 6 | // Copyright © 2016 Seth Rininger. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WebKit 11 | 12 | @objc protocol WebViewControllerDelegate { 13 | func webViewControllerDidFinish(_ controller: WebViewController) 14 | /*! @abstract Invoked when the initial URL load is complete. 15 | @param success YES if loading completed successfully, NO if loading failed. 16 | @discussion This method is invoked when SFSafariViewController completes the loading of the URL that you pass 17 | to its initializer. It is not invoked for any subsequent page loads in the same SFSafariViewController instance. 18 | */ 19 | @objc optional func webViewController(_ controller: WebViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) 20 | } 21 | 22 | class WebViewController: UIViewController, UIWebViewDelegate { 23 | 24 | var loadComplete: Bool = false 25 | var initialURL: URL! 26 | var webView: UIWebView! 27 | var delegate: WebViewControllerDelegate? 28 | 29 | override func viewDidLoad() { 30 | super.viewDidLoad() 31 | print(initialURL) 32 | let initialRequest = URLRequest(url: self.initialURL) 33 | self.webView = UIWebView(frame: self.view.bounds) 34 | self.webView.delegate = self 35 | self.webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 36 | self.view.addSubview(self.webView) 37 | self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.done)) 38 | self.webView.loadRequest(initialRequest) 39 | } 40 | 41 | func done() { 42 | 43 | self.delegate?.webViewControllerDidFinish(self) 44 | self.presentingViewController?.dismiss(animated: true, completion: { _ in }) 45 | } 46 | 47 | func webViewDidFinishLoad(_ webView: UIWebView) { 48 | if !self.loadComplete { 49 | delegate?.webViewController?(self, didCompleteInitialLoad: true) 50 | self.loadComplete = true 51 | } 52 | } 53 | 54 | func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { 55 | if !self.loadComplete { 56 | 57 | delegate?.webViewController?(self, didCompleteInitialLoad: true) 58 | self.loadComplete = true 59 | } 60 | } 61 | 62 | init(url URL: URL) { 63 | super.init(nibName: nil, bundle: nil) 64 | self.initialURL = URL as URL! 65 | 66 | } 67 | 68 | required init?(coder aDecoder: NSCoder) { 69 | super.init(coder: aDecoder) 70 | } 71 | 72 | } 73 | --------------------------------------------------------------------------------