@wwdrew/expo-spotify-sdk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +21 -3
  2. package/README.md +345 -96
  3. package/android/build.gradle +28 -22
  4. package/android/consumer-rules.pro +8 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/java/expo/modules/spotifysdk/ExpoSpotifySDKModule.kt +130 -145
  7. package/android/src/main/java/expo/modules/spotifysdk/SpotifyAuthCoordinator.kt +36 -0
  8. package/android/src/main/java/expo/modules/spotifysdk/SpotifyAuthorizationContract.kt +45 -0
  9. package/android/src/main/java/expo/modules/spotifysdk/SpotifyConfig.kt +80 -0
  10. package/android/src/main/java/expo/modules/spotifysdk/SpotifyErrors.kt +34 -0
  11. package/android/src/main/java/expo/modules/spotifysdk/SpotifyTokenSwapClient.kt +154 -0
  12. package/build/ExpoSpotifySDK.types.d.ts +76 -1
  13. package/build/ExpoSpotifySDK.types.d.ts.map +1 -1
  14. package/build/ExpoSpotifySDK.types.js +12 -1
  15. package/build/ExpoSpotifySDK.types.js.map +1 -1
  16. package/build/ExpoSpotifySDKModule.web.d.ts +7 -3
  17. package/build/ExpoSpotifySDKModule.web.d.ts.map +1 -1
  18. package/build/ExpoSpotifySDKModule.web.js +17 -7
  19. package/build/ExpoSpotifySDKModule.web.js.map +1 -1
  20. package/build/index.d.ts +39 -2
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js +117 -4
  23. package/build/index.js.map +1 -1
  24. package/expo-module.config.json +1 -1
  25. package/ios/ExpoSpotifyAppDelegate.swift +14 -0
  26. package/ios/ExpoSpotifyConfiguration.swift +33 -15
  27. package/ios/ExpoSpotifySDK.podspec +2 -4
  28. package/ios/ExpoSpotifySDKModule.swift +96 -26
  29. package/ios/SPTScopeSerializer.swift +40 -39
  30. package/ios/SpotifyAuthCoordinator.swift +133 -0
  31. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTConfiguration.h +1 -1
  32. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTError.h +6 -7
  33. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTScope.h +43 -39
  34. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SPTSessionManager.h +8 -4
  35. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Headers/SpotifyiOS.h +1 -1
  36. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/Info.plist +0 -0
  37. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64/SpotifyiOS.framework/SpotifyiOS +0 -0
  38. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTConfiguration.h +1 -1
  39. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTError.h +6 -7
  40. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTScope.h +43 -39
  41. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SPTSessionManager.h +8 -4
  42. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Headers/SpotifyiOS.h +1 -1
  43. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/Info.plist +0 -0
  44. package/ios/SpotifySDK/SpotifyiOS.xcframework/ios-arm64_x86_64-simulator/SpotifyiOS.framework/SpotifyiOS +0 -0
  45. package/ios/SpotifyTokenRefreshClient.swift +118 -0
  46. package/package.json +12 -11
  47. package/plugin/build/android/withSpotifyAndroidAppBuildGradle.js +15 -10
  48. package/plugin/build/ios/withSpotifyConfigValues.js +12 -7
  49. package/plugin/build/ios/withSpotifyURLScheme.d.ts +1 -1
  50. package/plugin/build/ios/withSpotifyURLScheme.js +9 -8
  51. package/plugin/build/types.d.ts +35 -0
  52. package/plugin/build/types.js +0 -19
  53. package/ios/ExpoSpotifyAuthDelegate.swift +0 -13
  54. package/ios/ExpoSpotifySessionManager+SessionManagerDelegate.swift +0 -16
  55. package/ios/ExpoSpotifySessionManager.swift +0 -90
  56. package/ios/SpotifySDK/SpotifyiOS.xcframework/_CodeSignature/CodeDirectory +0 -0
  57. package/ios/SpotifySDK/SpotifyiOS.xcframework/_CodeSignature/CodeRequirements +0 -0
  58. package/ios/SpotifySDK/SpotifyiOS.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
  59. package/ios/SpotifySDK/SpotifyiOS.xcframework/_CodeSignature/CodeResources +0 -1118
  60. package/ios/SpotifySDK/SpotifyiOS.xcframework/_CodeSignature/CodeSignature +0 -0
@@ -1,44 +1,45 @@
1
+ import Foundation
1
2
  import SpotifyiOS
2
3
 
3
- class SPTScopeSerializer {
4
- static let scopeMap: [String: SPTScope] = [
5
- "playlist-read-private": .playlistReadPrivate,
6
- "playlist-read-collaborative": .playlistReadCollaborative,
7
- "playlist-modify-public": .playlistModifyPublic,
8
- "playlist-modify-private": .playlistModifyPrivate,
9
- "user-follow-read": .userFollowRead,
10
- "user-follow-modify": .userFollowModify,
11
- "user-library-read": .userLibraryRead,
12
- "user-library-modify": .userLibraryModify,
13
- "user-read-email": .userReadEmail,
14
- "user-read-private": .userReadPrivate,
15
- "user-top-read": .userTopRead,
16
- "ugc-image-upload": .ugcImageUpload,
17
- "streaming": .streaming,
18
- "app-remote-control": .appRemoteControl,
19
- "user-read-playback-state": .userReadPlaybackState,
20
- "user-modify-playback-state": .userModifyPlaybackState,
21
- "user-read-currently-playing": .userReadCurrentlyPlaying,
22
- "user-read-recently-played": .userReadRecentlyPlayed,
23
- ]
24
-
25
- static func serializeScopes(_ scopes: SPTScope) -> [String] {
26
- var serializedScopes = [String]()
27
- for (scopeString, scopeValue) in scopeMap {
28
- if scopes.contains(scopeValue) {
29
- serializedScopes.append(scopeString)
30
- }
31
- }
32
- return serializedScopes
4
+ enum SPTScopeSerializer {
5
+ /// Single source of truth for the string ↔ SPTScope mapping. Order is
6
+ /// preserved on round-trip via `serialize` (sorted alphabetically) so output
7
+ /// is deterministic.
8
+ static let scopeMap: [(String, SPTScope)] = [
9
+ ("app-remote-control", .appRemoteControl),
10
+ ("playlist-modify-private", .playlistModifyPrivate),
11
+ ("playlist-modify-public", .playlistModifyPublic),
12
+ ("playlist-read-collaborative", .playlistReadCollaborative),
13
+ ("playlist-read-private", .playlistReadPrivate),
14
+ ("streaming", .streaming),
15
+ ("ugc-image-upload", .ugcImageUpload),
16
+ ("user-follow-modify", .userFollowModify),
17
+ ("user-follow-read", .userFollowRead),
18
+ ("user-library-modify", .userLibraryModify),
19
+ ("user-library-read", .userLibraryRead),
20
+ ("user-modify-playback-state", .userModifyPlaybackState),
21
+ ("user-read-currently-playing", .userReadCurrentlyPlaying),
22
+ ("user-read-email", .userReadEmail),
23
+ ("user-read-playback-state", .userReadPlaybackState),
24
+ ("user-read-private", .userReadPrivate),
25
+ ("user-read-recently-played", .userReadRecentlyPlayed),
26
+ ("user-top-read", .userTopRead),
27
+ ]
28
+
29
+ static func serialize(_ scopes: SPTScope) -> [String] {
30
+ scopeMap.compactMap { (string, value) in
31
+ scopes.contains(value) ? string : nil
33
32
  }
34
-
35
- static func deserializeScopes(_ scopes: [String]) -> SPTScope {
36
- var deserializedScopes: SPTScope = []
37
- for scopeString in scopes {
38
- if let scopeValue = scopeMap[scopeString] {
39
- deserializedScopes.insert(scopeValue)
40
- }
41
- }
42
- return deserializedScopes
33
+ }
34
+
35
+ static func deserialize(_ scopes: [String]) -> SPTScope {
36
+ var result: SPTScope = []
37
+ let lookup = Dictionary(uniqueKeysWithValues: scopeMap)
38
+ for string in scopes {
39
+ if let value = lookup[string] {
40
+ result.insert(value)
41
+ }
43
42
  }
43
+ return result
44
+ }
44
45
  }
@@ -0,0 +1,133 @@
1
+ import Foundation
2
+ import SpotifyiOS
3
+
4
+ /// Public, structured errors thrown by the coordinator. Each case carries the
5
+ /// JS-facing error code in `code`, mirroring the Android `CodedException`
6
+ /// taxonomy.
7
+ enum SpotifyError: Error {
8
+ case invalidConfiguration(String)
9
+ case authInProgress
10
+ case userCancelled
11
+ case spotifyNotInstalled
12
+ case underlying(Error)
13
+
14
+ var code: String {
15
+ switch self {
16
+ case .invalidConfiguration: return "INVALID_CONFIG"
17
+ case .authInProgress: return "AUTH_IN_PROGRESS"
18
+ case .userCancelled: return "USER_CANCELLED"
19
+ case .spotifyNotInstalled: return "SPOTIFY_NOT_INSTALLED"
20
+ case .underlying: return "UNKNOWN"
21
+ }
22
+ }
23
+
24
+ var message: String {
25
+ switch self {
26
+ case .invalidConfiguration(let m): return m
27
+ case .authInProgress: return "Another authentication request is already in progress"
28
+ case .userCancelled: return "Authentication was cancelled by the user"
29
+ case .spotifyNotInstalled: return "The Spotify app is not installed on this device"
30
+ case .underlying(let err): return err.localizedDescription
31
+ }
32
+ }
33
+ }
34
+
35
+ /// `actor` ensures `pending` is mutated only on the actor's serial executor;
36
+ /// no manual locks needed.
37
+ actor SpotifyAuthCoordinator {
38
+ static let shared: SpotifyAuthCoordinator? = SpotifyAuthCoordinator.create()
39
+
40
+ private let sptConfiguration: SPTConfiguration
41
+ private let sessionManager: SPTSessionManager
42
+ private let bridge: SpotifySessionDelegateBridge
43
+ private var pending: CheckedContinuation<SPTSession, Error>?
44
+
45
+ private init(sptConfiguration: SPTConfiguration, sessionManager: SPTSessionManager, bridge: SpotifySessionDelegateBridge) {
46
+ self.sptConfiguration = sptConfiguration
47
+ self.sessionManager = sessionManager
48
+ self.bridge = bridge
49
+ bridge.coordinator = self
50
+ }
51
+
52
+ private static func create() -> SpotifyAuthCoordinator? {
53
+ guard
54
+ let configuration = ExpoSpotifyConfiguration.fromInfoPlist(),
55
+ let sptConfig = configuration.sptConfiguration
56
+ else {
57
+ NSLog("[ExpoSpotifySDK] Missing or invalid `ExpoSpotifySDK` Info.plist entry")
58
+ return nil
59
+ }
60
+ let bridge = SpotifySessionDelegateBridge()
61
+ let manager = SPTSessionManager(configuration: sptConfig, delegate: bridge)
62
+ return SpotifyAuthCoordinator(sptConfiguration: sptConfig, sessionManager: manager, bridge: bridge)
63
+ }
64
+
65
+ /// Synchronous getter used by the module's `Function("isAvailable")`. Safe
66
+ /// to call from any thread because the underlying SDK property is read-only
67
+ /// state derived from the installed-apps query.
68
+ nonisolated func isSpotifyAppInstalled() -> Bool {
69
+ sessionManager.isSpotifyAppInstalled
70
+ }
71
+
72
+ /// Synchronous URL-handler dispatcher used by the AppDelegate / SceneDelegate
73
+ /// subscribers to forward redirects to the SPTSessionManager.
74
+ nonisolated func handleOpenURL(_ url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
75
+ sessionManager.application(UIApplication.shared, open: url, options: options)
76
+ }
77
+
78
+ func authenticate(
79
+ scopes: SPTScope,
80
+ tokenSwapURL: URL?,
81
+ tokenRefreshURL: URL?
82
+ ) async throws -> SPTSession {
83
+ guard pending == nil else { throw SpotifyError.authInProgress }
84
+
85
+ // SPTConfiguration is a reference type shared with the session manager, so
86
+ // mutating it here takes effect for the upcoming initiateSession call.
87
+ sptConfiguration.tokenSwapURL = tokenSwapURL
88
+ sptConfiguration.tokenRefreshURL = tokenRefreshURL
89
+
90
+ return try await withCheckedThrowingContinuation { (cont: CheckedContinuation<SPTSession, Error>) in
91
+ self.pending = cont
92
+ Task { @MainActor in
93
+ self.sessionManager.initiateSession(with: scopes, options: .default, campaign: nil)
94
+ }
95
+ }
96
+ }
97
+
98
+ func deliver(_ result: Result<SPTSession, Error>) {
99
+ let cont = pending
100
+ pending = nil
101
+ cont?.resume(with: result)
102
+ }
103
+ }
104
+
105
+ /// `SPTSessionManagerDelegate` requires NSObject conformance, which an actor
106
+ /// can't satisfy directly. The bridge is a tiny NSObject that hops the call
107
+ /// onto the actor's executor.
108
+ final class SpotifySessionDelegateBridge: NSObject, SPTSessionManagerDelegate {
109
+ weak var coordinator: SpotifyAuthCoordinator?
110
+
111
+ func sessionManager(manager _: SPTSessionManager, didInitiate session: SPTSession) {
112
+ Task { await coordinator?.deliver(.success(session)) }
113
+ }
114
+
115
+ func sessionManager(manager _: SPTSessionManager, didFailWith error: Error) {
116
+ let mapped: Error = mapSDKError(error)
117
+ Task { await coordinator?.deliver(.failure(mapped)) }
118
+ }
119
+
120
+ func sessionManager(manager _: SPTSessionManager, didRenew session: SPTSession) {
121
+ Task { await coordinator?.deliver(.success(session)) }
122
+ }
123
+
124
+ /// Translate a few well-known SDK error shapes into our taxonomy.
125
+ private func mapSDKError(_ error: Error) -> Error {
126
+ let nsError = error as NSError
127
+ let description = nsError.localizedDescription.lowercased()
128
+ if description.contains("cancel") {
129
+ return SpotifyError.userCancelled
130
+ }
131
+ return SpotifyError.underlying(error)
132
+ }
133
+ }
@@ -51,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
51
51
  - (instancetype)initWithClientID:(NSString *)clientID redirectURL:(NSURL *)redirectURL NS_DESIGNATED_INITIALIZER;
52
52
 
53
53
  /**
54
- Convenience intializer for `SPtConfiguration`
54
+ Convenience initializer for `SPTConfiguration`
55
55
 
56
56
  @param clientID Your client ID obtained from developer.spotify.com
57
57
  @param redirectURL Your redirect URL for Spotify to open your app again after authorization
@@ -10,13 +10,12 @@ SPT_EXPORT NSErrorDomain const SPTLoginErrorDomain;
10
10
  typedef NS_ENUM(NSUInteger, SPTErrorCode) {
11
11
  /// Unknown error code
12
12
  SPTUnknownErrorCode NS_SWIFT_NAME(unknown) = 0,
13
- /// Authorization failed
14
- SPTAuthorizationFailedErrorCode NS_SWIFT_NAME(authorizationFailed),
15
- /// Renew session failed
16
- SPTRenewSessionFailedErrorCode NS_SWIFT_NAME(renewSessionFailed),
17
- /// Failed to parse the returned JSON
18
- SPTJSONFailedErrorCode NS_SWIFT_NAME(jsonFailed),
19
- };
13
+ /// Authorization failed
14
+ SPTAuthorizationFailedErrorCode NS_SWIFT_NAME(authorizationFailed),
15
+ /// Renew session failed
16
+ SPTRenewSessionFailedErrorCode NS_SWIFT_NAME(renewSessionFailed),
17
+ /// Failed to parse the returned JSON
18
+ SPTJSONFailedErrorCode NS_SWIFT_NAME(jsonFailed) };
20
19
 
21
20
  /// Spotify-specific errors. Use NSUnderlyingErrorKey to see the underlying error
22
21
  @interface SPTError : NSError
@@ -30,42 +30,46 @@
30
30
  typedef NS_OPTIONS(NSUInteger, SPTScope) {
31
31
  /// Read access to user's private playlists.
32
32
  SPTPlaylistReadPrivateScope NS_SWIFT_NAME(playlistReadPrivate) = (1 << 0),
33
- /// Include collaborative playlists when requesting a user's playlists.
34
- SPTPlaylistReadCollaborativeScope NS_SWIFT_NAME(playlistReadCollaborative) = (1 << 1),
35
- /// Write access to a user's public playlists.
36
- SPTPlaylistModifyPublicScope NS_SWIFT_NAME(playlistModifyPublic) = (1 << 2),
37
- /// Write access to a user's private playlists.
38
- SPTPlaylistModifyPrivateScope NS_SWIFT_NAME(playlistModifyPrivate) = (1 << 3),
39
- /// Read access to the list of artists and other users that the user follows.
40
- SPTUserFollowReadScope NS_SWIFT_NAME(userFollowRead) = (1 << 4),
41
- /// Write/delete access to the list of artists and other users that the user follows.
42
- SPTUserFollowModifyScope NS_SWIFT_NAME(userFollowModify) = (1 << 5),
43
- /// Read access to a user's "Your Music" library.
44
- SPTUserLibraryReadScope NS_SWIFT_NAME(userLibraryRead) = (1 << 6),
45
- /// Write/delete access to a user's "Your Music" library.
46
- SPTUserLibraryModifyScope NS_SWIFT_NAME(userLibraryModify) = (1 << 7),
47
- /// Read access to the user's birthdate.
48
- SPTUserReadBirthDateScope NS_SWIFT_NAME(userReadBirthDate) = (1 << 8),
49
- /// Read access to user’s email address.
50
- SPTUserReadEmailScope NS_SWIFT_NAME(userReadEmail) = (1 << 9),
51
- /// Read access to user’s subscription details (type of user account).
52
- SPTUserReadPrivateScope NS_SWIFT_NAME(userReadPrivate) = (1 << 10),
53
- /// Read access to a user's top artists and tracks.
54
- SPTUserTopReadScope NS_SWIFT_NAME(userTopRead) = (1 << 11),
55
- /// Upload user generated content images
56
- SPTUGCImageUploadScope NS_SWIFT_NAME(ugcImageUpload) = (1 << 12),
57
- /// Control playback of a Spotify track.
58
- SPTStreamingScope NS_SWIFT_NAME(streaming) = (1 << 13),
59
- /// Use App Remote to control playback in the Spotify app
60
- SPTAppRemoteControlScope NS_SWIFT_NAME(appRemoteControl) = (1 << 14),
61
- /// Read access to a user’s player state.
62
- SPTUserReadPlaybackStateScope NS_SWIFT_NAME(userReadPlaybackState) = (1 << 15),
63
- /// Write access to a user’s playback state
64
- SPTUserModifyPlaybackStateScope NS_SWIFT_NAME(userModifyPlaybackState) = (1 << 16),
65
- /// Read access to a user’s currently playing track
66
- SPTUserReadCurrentlyPlayingScope NS_SWIFT_NAME(userReadCurrentlyPlaying) = (1 << 17),
67
- /// Read access to a user’s currently playing track
68
- SPTUserReadRecentlyPlayedScope NS_SWIFT_NAME(userReadRecentlyPlayed) = (1 << 18),
69
- /// Indicate that the application intends to use OIDC to verify the user's identity
70
- SPTOpenIdScope NS_SWIFT_NAME(openid) = (1 << 19),
71
- };
33
+ /// Include collaborative playlists when requesting a user's playlists.
34
+ SPTPlaylistReadCollaborativeScope NS_SWIFT_NAME(playlistReadCollaborative) = (1 << 1),
35
+ /// Write access to a user's public playlists.
36
+ SPTPlaylistModifyPublicScope NS_SWIFT_NAME(playlistModifyPublic) = (1 << 2),
37
+ /// Write access to a user's private playlists.
38
+ SPTPlaylistModifyPrivateScope NS_SWIFT_NAME(playlistModifyPrivate) = (1 << 3),
39
+ /// Read access to the list of artists and other users that the user follows.
40
+ SPTUserFollowReadScope NS_SWIFT_NAME(userFollowRead) = (1 << 4),
41
+ /// Write/delete access to the list of artists and other users that the user follows.
42
+ SPTUserFollowModifyScope NS_SWIFT_NAME(userFollowModify) = (1 << 5),
43
+ /// Read access to a user's "Your Music" library.
44
+ SPTUserLibraryReadScope NS_SWIFT_NAME(userLibraryRead) = (1 << 6),
45
+ /// Write/delete access to a user's "Your Music" library.
46
+ SPTUserLibraryModifyScope NS_SWIFT_NAME(userLibraryModify) = (1 << 7),
47
+ /// Read access to the user's birthdate.
48
+ SPTUserReadBirthDateScope NS_SWIFT_NAME(userReadBirthDate) = (1 << 8),
49
+ /// Read access to user’s email address.
50
+ SPTUserReadEmailScope NS_SWIFT_NAME(userReadEmail) = (1 << 9),
51
+ /// Read access to user’s subscription details (type of user account).
52
+ SPTUserReadPrivateScope NS_SWIFT_NAME(userReadPrivate) = (1 << 10),
53
+ /// Read access to a user's top artists and tracks.
54
+ SPTUserTopReadScope NS_SWIFT_NAME(userTopRead) = (1 << 11),
55
+ /// Upload user generated content images
56
+ SPTUGCImageUploadScope NS_SWIFT_NAME(ugcImageUpload) = (1 << 12),
57
+ /// Control playback of a Spotify track.
58
+ SPTStreamingScope NS_SWIFT_NAME(streaming) = (1 << 13),
59
+ /// Use App Remote to control playback in the Spotify app
60
+ SPTAppRemoteControlScope NS_SWIFT_NAME(appRemoteControl) = (1 << 14),
61
+ /// Read access to a user’s player state.
62
+ SPTUserReadPlaybackStateScope NS_SWIFT_NAME(userReadPlaybackState) = (1 << 15),
63
+ /// Write access to a user’s playback state
64
+ SPTUserModifyPlaybackStateScope NS_SWIFT_NAME(userModifyPlaybackState) = (1 << 16),
65
+ /// Read access to a user’s currently playing
66
+ /// track
67
+ SPTUserReadCurrentlyPlayingScope NS_SWIFT_NAME(userReadCurrentlyPlaying) = (1 << 17),
68
+ /// Read access to a user’s currently
69
+ /// playing track
70
+ SPTUserReadRecentlyPlayedScope NS_SWIFT_NAME(userReadRecentlyPlayed) = (1 << 18),
71
+ /// Indicate that the application
72
+ /// intends to use OIDC to verify the
73
+ /// user's identity
74
+ SPTOpenIdScope NS_SWIFT_NAME(openid) = (1 << 19),
75
+ };
@@ -8,11 +8,15 @@ NS_ASSUME_NONNULL_BEGIN
8
8
 
9
9
  /// Options for determining the most suitable method for authorization
10
10
  typedef NS_OPTIONS(NSUInteger, SPTAuthorizationOptions) {
11
- /// Authorize using a suitable method. If Spotify is installed the app will be used instead of a web view
11
+ /// Authorize using a suitable method. If Spotify is installed the app will be used instead of ASWebAuthentication.
12
12
  SPTDefaultAuthorizationOption NS_SWIFT_NAME(default) = (0),
13
- /// Authorize using only the Spotify client. If Spotify is not installed authorization will fail.
14
- SPTClientAuthorizationOption NS_SWIFT_NAME(clientOnly) = (1 << 0),
15
- } NS_SWIFT_NAME(AuthorizationOptions);
13
+ /// Authorize using only the Spotify client. If Spotify is not installed authorization will fail.
14
+ SPTClientAuthorizationOption NS_SWIFT_NAME(clientOnly) = (1 << 0),
15
+ /// Use this option if you have reached the limit of `LSApplicationQueriesSchemes` in your Info.plist
16
+ /// Attempt to open Spotify app directly without using `canOpenURL`. Falls back to ASWebAuthentication if
17
+ /// opening fails.
18
+ SPTSpotifySchemeNotRegisteredAuthorizationOption NS_SWIFT_NAME(spotifySchemeNotRegistered) = (1 << 1),
19
+ } NS_SWIFT_NAME(AuthorizationOptions);
16
20
 
17
21
  typedef NSString *const SPTAuthorizationCode;
18
22
 
@@ -4,4 +4,4 @@
4
4
  #import "SPTLogin.h"
5
5
  #import "SpotifyAppRemote.h"
6
6
 
7
- #endif /* _SPOTIFYIOS_ */
7
+ #endif /* _SPOTIFYIOS_ */
@@ -51,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
51
51
  - (instancetype)initWithClientID:(NSString *)clientID redirectURL:(NSURL *)redirectURL NS_DESIGNATED_INITIALIZER;
52
52
 
53
53
  /**
54
- Convenience intializer for `SPtConfiguration`
54
+ Convenience initializer for `SPTConfiguration`
55
55
 
56
56
  @param clientID Your client ID obtained from developer.spotify.com
57
57
  @param redirectURL Your redirect URL for Spotify to open your app again after authorization
@@ -10,13 +10,12 @@ SPT_EXPORT NSErrorDomain const SPTLoginErrorDomain;
10
10
  typedef NS_ENUM(NSUInteger, SPTErrorCode) {
11
11
  /// Unknown error code
12
12
  SPTUnknownErrorCode NS_SWIFT_NAME(unknown) = 0,
13
- /// Authorization failed
14
- SPTAuthorizationFailedErrorCode NS_SWIFT_NAME(authorizationFailed),
15
- /// Renew session failed
16
- SPTRenewSessionFailedErrorCode NS_SWIFT_NAME(renewSessionFailed),
17
- /// Failed to parse the returned JSON
18
- SPTJSONFailedErrorCode NS_SWIFT_NAME(jsonFailed),
19
- };
13
+ /// Authorization failed
14
+ SPTAuthorizationFailedErrorCode NS_SWIFT_NAME(authorizationFailed),
15
+ /// Renew session failed
16
+ SPTRenewSessionFailedErrorCode NS_SWIFT_NAME(renewSessionFailed),
17
+ /// Failed to parse the returned JSON
18
+ SPTJSONFailedErrorCode NS_SWIFT_NAME(jsonFailed) };
20
19
 
21
20
  /// Spotify-specific errors. Use NSUnderlyingErrorKey to see the underlying error
22
21
  @interface SPTError : NSError
@@ -30,42 +30,46 @@
30
30
  typedef NS_OPTIONS(NSUInteger, SPTScope) {
31
31
  /// Read access to user's private playlists.
32
32
  SPTPlaylistReadPrivateScope NS_SWIFT_NAME(playlistReadPrivate) = (1 << 0),
33
- /// Include collaborative playlists when requesting a user's playlists.
34
- SPTPlaylistReadCollaborativeScope NS_SWIFT_NAME(playlistReadCollaborative) = (1 << 1),
35
- /// Write access to a user's public playlists.
36
- SPTPlaylistModifyPublicScope NS_SWIFT_NAME(playlistModifyPublic) = (1 << 2),
37
- /// Write access to a user's private playlists.
38
- SPTPlaylistModifyPrivateScope NS_SWIFT_NAME(playlistModifyPrivate) = (1 << 3),
39
- /// Read access to the list of artists and other users that the user follows.
40
- SPTUserFollowReadScope NS_SWIFT_NAME(userFollowRead) = (1 << 4),
41
- /// Write/delete access to the list of artists and other users that the user follows.
42
- SPTUserFollowModifyScope NS_SWIFT_NAME(userFollowModify) = (1 << 5),
43
- /// Read access to a user's "Your Music" library.
44
- SPTUserLibraryReadScope NS_SWIFT_NAME(userLibraryRead) = (1 << 6),
45
- /// Write/delete access to a user's "Your Music" library.
46
- SPTUserLibraryModifyScope NS_SWIFT_NAME(userLibraryModify) = (1 << 7),
47
- /// Read access to the user's birthdate.
48
- SPTUserReadBirthDateScope NS_SWIFT_NAME(userReadBirthDate) = (1 << 8),
49
- /// Read access to user’s email address.
50
- SPTUserReadEmailScope NS_SWIFT_NAME(userReadEmail) = (1 << 9),
51
- /// Read access to user’s subscription details (type of user account).
52
- SPTUserReadPrivateScope NS_SWIFT_NAME(userReadPrivate) = (1 << 10),
53
- /// Read access to a user's top artists and tracks.
54
- SPTUserTopReadScope NS_SWIFT_NAME(userTopRead) = (1 << 11),
55
- /// Upload user generated content images
56
- SPTUGCImageUploadScope NS_SWIFT_NAME(ugcImageUpload) = (1 << 12),
57
- /// Control playback of a Spotify track.
58
- SPTStreamingScope NS_SWIFT_NAME(streaming) = (1 << 13),
59
- /// Use App Remote to control playback in the Spotify app
60
- SPTAppRemoteControlScope NS_SWIFT_NAME(appRemoteControl) = (1 << 14),
61
- /// Read access to a user’s player state.
62
- SPTUserReadPlaybackStateScope NS_SWIFT_NAME(userReadPlaybackState) = (1 << 15),
63
- /// Write access to a user’s playback state
64
- SPTUserModifyPlaybackStateScope NS_SWIFT_NAME(userModifyPlaybackState) = (1 << 16),
65
- /// Read access to a user’s currently playing track
66
- SPTUserReadCurrentlyPlayingScope NS_SWIFT_NAME(userReadCurrentlyPlaying) = (1 << 17),
67
- /// Read access to a user’s currently playing track
68
- SPTUserReadRecentlyPlayedScope NS_SWIFT_NAME(userReadRecentlyPlayed) = (1 << 18),
69
- /// Indicate that the application intends to use OIDC to verify the user's identity
70
- SPTOpenIdScope NS_SWIFT_NAME(openid) = (1 << 19),
71
- };
33
+ /// Include collaborative playlists when requesting a user's playlists.
34
+ SPTPlaylistReadCollaborativeScope NS_SWIFT_NAME(playlistReadCollaborative) = (1 << 1),
35
+ /// Write access to a user's public playlists.
36
+ SPTPlaylistModifyPublicScope NS_SWIFT_NAME(playlistModifyPublic) = (1 << 2),
37
+ /// Write access to a user's private playlists.
38
+ SPTPlaylistModifyPrivateScope NS_SWIFT_NAME(playlistModifyPrivate) = (1 << 3),
39
+ /// Read access to the list of artists and other users that the user follows.
40
+ SPTUserFollowReadScope NS_SWIFT_NAME(userFollowRead) = (1 << 4),
41
+ /// Write/delete access to the list of artists and other users that the user follows.
42
+ SPTUserFollowModifyScope NS_SWIFT_NAME(userFollowModify) = (1 << 5),
43
+ /// Read access to a user's "Your Music" library.
44
+ SPTUserLibraryReadScope NS_SWIFT_NAME(userLibraryRead) = (1 << 6),
45
+ /// Write/delete access to a user's "Your Music" library.
46
+ SPTUserLibraryModifyScope NS_SWIFT_NAME(userLibraryModify) = (1 << 7),
47
+ /// Read access to the user's birthdate.
48
+ SPTUserReadBirthDateScope NS_SWIFT_NAME(userReadBirthDate) = (1 << 8),
49
+ /// Read access to user’s email address.
50
+ SPTUserReadEmailScope NS_SWIFT_NAME(userReadEmail) = (1 << 9),
51
+ /// Read access to user’s subscription details (type of user account).
52
+ SPTUserReadPrivateScope NS_SWIFT_NAME(userReadPrivate) = (1 << 10),
53
+ /// Read access to a user's top artists and tracks.
54
+ SPTUserTopReadScope NS_SWIFT_NAME(userTopRead) = (1 << 11),
55
+ /// Upload user generated content images
56
+ SPTUGCImageUploadScope NS_SWIFT_NAME(ugcImageUpload) = (1 << 12),
57
+ /// Control playback of a Spotify track.
58
+ SPTStreamingScope NS_SWIFT_NAME(streaming) = (1 << 13),
59
+ /// Use App Remote to control playback in the Spotify app
60
+ SPTAppRemoteControlScope NS_SWIFT_NAME(appRemoteControl) = (1 << 14),
61
+ /// Read access to a user’s player state.
62
+ SPTUserReadPlaybackStateScope NS_SWIFT_NAME(userReadPlaybackState) = (1 << 15),
63
+ /// Write access to a user’s playback state
64
+ SPTUserModifyPlaybackStateScope NS_SWIFT_NAME(userModifyPlaybackState) = (1 << 16),
65
+ /// Read access to a user’s currently playing
66
+ /// track
67
+ SPTUserReadCurrentlyPlayingScope NS_SWIFT_NAME(userReadCurrentlyPlaying) = (1 << 17),
68
+ /// Read access to a user’s currently
69
+ /// playing track
70
+ SPTUserReadRecentlyPlayedScope NS_SWIFT_NAME(userReadRecentlyPlayed) = (1 << 18),
71
+ /// Indicate that the application
72
+ /// intends to use OIDC to verify the
73
+ /// user's identity
74
+ SPTOpenIdScope NS_SWIFT_NAME(openid) = (1 << 19),
75
+ };
@@ -8,11 +8,15 @@ NS_ASSUME_NONNULL_BEGIN
8
8
 
9
9
  /// Options for determining the most suitable method for authorization
10
10
  typedef NS_OPTIONS(NSUInteger, SPTAuthorizationOptions) {
11
- /// Authorize using a suitable method. If Spotify is installed the app will be used instead of a web view
11
+ /// Authorize using a suitable method. If Spotify is installed the app will be used instead of ASWebAuthentication.
12
12
  SPTDefaultAuthorizationOption NS_SWIFT_NAME(default) = (0),
13
- /// Authorize using only the Spotify client. If Spotify is not installed authorization will fail.
14
- SPTClientAuthorizationOption NS_SWIFT_NAME(clientOnly) = (1 << 0),
15
- } NS_SWIFT_NAME(AuthorizationOptions);
13
+ /// Authorize using only the Spotify client. If Spotify is not installed authorization will fail.
14
+ SPTClientAuthorizationOption NS_SWIFT_NAME(clientOnly) = (1 << 0),
15
+ /// Use this option if you have reached the limit of `LSApplicationQueriesSchemes` in your Info.plist
16
+ /// Attempt to open Spotify app directly without using `canOpenURL`. Falls back to ASWebAuthentication if
17
+ /// opening fails.
18
+ SPTSpotifySchemeNotRegisteredAuthorizationOption NS_SWIFT_NAME(spotifySchemeNotRegistered) = (1 << 1),
19
+ } NS_SWIFT_NAME(AuthorizationOptions);
16
20
 
17
21
  typedef NSString *const SPTAuthorizationCode;
18
22
 
@@ -4,4 +4,4 @@
4
4
  #import "SPTLogin.h"
5
5
  #import "SpotifyAppRemote.h"
6
6
 
7
- #endif /* _SPOTIFYIOS_ */
7
+ #endif /* _SPOTIFYIOS_ */