@wwdrew/expo-spotify-sdk 0.1.1 → 0.3.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.
- package/README.md +17 -9
- package/build/ExpoSpotifySDK.types.d.ts +7 -0
- package/build/ExpoSpotifySDK.types.d.ts.map +1 -1
- package/build/ExpoSpotifySDK.types.js.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -2
- package/build/index.js.map +1 -1
- package/ios/ExpoSpotifyConfiguration.swift +4 -9
- package/ios/ExpoSpotifySDKModule.swift +29 -16
- package/ios/ExpoSpotifySessionManager+SessionManagerDelegate.swift +14 -4
- package/ios/ExpoSpotifySessionManager.swift +45 -29
- package/package.json +1 -1
- package/plugin/build/index.js +10 -7
- package/plugin/build/types.d.ts +0 -2
package/README.md
CHANGED
|
@@ -24,9 +24,7 @@ Include the `expo-spotify-sdk` plugin in your `app.json/app.config.js` file with
|
|
|
24
24
|
["@wwdrew/expo-spotify-sdk", {
|
|
25
25
|
"clientID": "<your-spotify-client-id>",
|
|
26
26
|
"scheme": "expo-spotify-sdk-example",
|
|
27
|
-
"host": "authenticate"
|
|
28
|
-
"tokenSwapURL": "http://192.168.0.5:3000/swap",
|
|
29
|
-
"tokenRefreshURL": "http://192.168.0.5:3000/swap"
|
|
27
|
+
"host": "authenticate"
|
|
30
28
|
}]
|
|
31
29
|
],
|
|
32
30
|
...
|
|
@@ -37,23 +35,27 @@ Required:
|
|
|
37
35
|
- `clientID`: <string> the Spotify Client ID for your application
|
|
38
36
|
- `scheme`: <string> the [URL scheme](https://docs.expo.dev/versions/latest/config/app/#scheme) to link into your app as part of the redirect URI
|
|
39
37
|
- `host`: <string> the path of the redirect URI
|
|
40
|
-
- `tokenSwapURL` (optional): <string> The URL to use for attempting to swap an authorization code for an access token
|
|
41
|
-
- `tokenRefreshURL` (optional): <string> The URL to use for attempting to renew an access token with a refresh token
|
|
42
38
|
|
|
43
39
|
## API Reference
|
|
44
40
|
|
|
45
|
-
|
|
41
|
+
```typescript
|
|
42
|
+
isAvailable(): boolean`
|
|
43
|
+
```
|
|
46
44
|
|
|
47
45
|
Determines if the Spotify app is installed on the target device.
|
|
48
46
|
|
|
49
47
|
---
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
```typescript
|
|
50
|
+
authenticateAsync(config: SpotifyConfig): Promise<SpotifySession>
|
|
51
|
+
```
|
|
52
52
|
|
|
53
53
|
Starts the authentication process. Requires an array of OAuth scopes. If the Spotify app is installed on the target device it will interact directly with it, otherwise it will open a web view to authenticate with the Spotify website.
|
|
54
54
|
|
|
55
55
|
### Parameters
|
|
56
56
|
|
|
57
|
+
- `tokenSwapURL` (optional): <string> The URL to use for attempting to swap an authorization code for an access token
|
|
58
|
+
- `tokenRefreshURL` (optional): <string> The URL to use for attempting to renew an access token with a refresh token
|
|
57
59
|
- `scopes`: An array of OAuth scopes that declare how your app wants to access a user's account. See [Spotify Scopes](https://developer.spotify.com/web-api/using-scopes/) for more information.
|
|
58
60
|
|
|
59
61
|
**Note**: The following scopes are not available to Expo Spotify SDK:
|
|
@@ -68,11 +70,18 @@ Starts the authentication process. Requires an array of OAuth scopes. If the Spo
|
|
|
68
70
|
### Types
|
|
69
71
|
|
|
70
72
|
```typescript
|
|
73
|
+
interface SpotifyConfig {
|
|
74
|
+
scopes: SpotifyScope[];
|
|
75
|
+
tokenSwapURL?: string;
|
|
76
|
+
tokenRefreshURL?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
interface SpotifySession {
|
|
72
80
|
accessToken: string;
|
|
73
81
|
refreshToken: string;
|
|
74
82
|
expirationDate: number;
|
|
75
83
|
isExpired: boolean;
|
|
84
|
+
scopes: SpotifyScopes[];
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
type SpotifyScopes =
|
|
@@ -94,12 +103,11 @@ type SpotifyScopes =
|
|
|
94
103
|
| "user-library-read"
|
|
95
104
|
| "user-read-email"
|
|
96
105
|
| "user-read-private";
|
|
97
|
-
|
|
98
106
|
```
|
|
99
107
|
|
|
100
108
|
## Acknowledgments
|
|
101
109
|
|
|
102
|
-
This project has been heavily inspired by the following projects
|
|
110
|
+
This project has been heavily inspired by the following projects:
|
|
103
111
|
|
|
104
112
|
* [react-native-spotify-remote](https://github.com/cjam/react-native-spotify-remote)
|
|
105
113
|
* [expo-spotify](https://github.com/kvbalib/expo-spotify)
|
|
@@ -3,6 +3,13 @@ export interface SpotifySession {
|
|
|
3
3
|
refreshToken: string;
|
|
4
4
|
expirationDate: number;
|
|
5
5
|
isExpired: boolean;
|
|
6
|
+
scopes: SpotifyScope[];
|
|
7
|
+
}
|
|
8
|
+
export interface SpotifyConfig {
|
|
9
|
+
scopes: SpotifyScope[];
|
|
10
|
+
tokenSwapURL?: string;
|
|
11
|
+
tokenRefreshURL?: string;
|
|
12
|
+
shouldRequestAccessToken?: boolean;
|
|
6
13
|
}
|
|
7
14
|
export type SpotifyScope = "ugc-image-upload" | "user-read-playback-state" | "user-modify-playback-state" | "user-read-currently-playing" | "app-remote-control" | "streaming" | "playlist-read-private" | "playlist-read-collaborative" | "playlist-modify-private" | "playlist-modify-public" | "user-follow-modify" | "user-follow-read" | "user-top-read" | "user-read-recently-played" | "user-library-modify" | "user-library-read" | "user-read-email" | "user-read-private";
|
|
8
15
|
//# sourceMappingURL=ExpoSpotifySDK.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoSpotifySDK.types.d.ts","sourceRoot":"","sources":["../src/ExpoSpotifySDK.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ExpoSpotifySDK.types.d.ts","sourceRoot":"","sources":["../src/ExpoSpotifySDK.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,0BAA0B,GAC1B,4BAA4B,GAC5B,6BAA6B,GAC7B,oBAAoB,GACpB,WAAW,GACX,uBAAuB,GACvB,6BAA6B,GAC7B,yBAAyB,GACzB,wBAAwB,GACxB,oBAAoB,GACpB,kBAAkB,GAClB,eAAe,GACf,2BAA2B,GAC3B,qBAAqB,GACrB,mBAAmB,GACnB,iBAAiB,GACjB,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoSpotifySDK.types.js","sourceRoot":"","sources":["../src/ExpoSpotifySDK.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface SpotifySession {\n accessToken: string;\n refreshToken: string;\n expirationDate: number;\n isExpired: boolean;\n}\n\nexport type SpotifyScope =\n | \"ugc-image-upload\"\n | \"user-read-playback-state\"\n | \"user-modify-playback-state\"\n | \"user-read-currently-playing\"\n | \"app-remote-control\"\n | \"streaming\"\n | \"playlist-read-private\"\n | \"playlist-read-collaborative\"\n | \"playlist-modify-private\"\n | \"playlist-modify-public\"\n | \"user-follow-modify\"\n | \"user-follow-read\"\n | \"user-top-read\"\n | \"user-read-recently-played\"\n | \"user-library-modify\"\n | \"user-library-read\"\n | \"user-read-email\"\n | \"user-read-private\";\n"]}
|
|
1
|
+
{"version":3,"file":"ExpoSpotifySDK.types.js","sourceRoot":"","sources":["../src/ExpoSpotifySDK.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface SpotifySession {\n accessToken: string;\n refreshToken: string;\n expirationDate: number;\n isExpired: boolean;\n scopes: SpotifyScope[];\n}\n\nexport interface SpotifyConfig {\n scopes: SpotifyScope[];\n tokenSwapURL?: string;\n tokenRefreshURL?: string;\n shouldRequestAccessToken?: boolean;\n}\n\nexport type SpotifyScope =\n | \"ugc-image-upload\"\n | \"user-read-playback-state\"\n | \"user-modify-playback-state\"\n | \"user-read-currently-playing\"\n | \"app-remote-control\"\n | \"streaming\"\n | \"playlist-read-private\"\n | \"playlist-read-collaborative\"\n | \"playlist-modify-private\"\n | \"playlist-modify-public\"\n | \"user-follow-modify\"\n | \"user-follow-read\"\n | \"user-top-read\"\n | \"user-read-recently-played\"\n | \"user-library-modify\"\n | \"user-library-read\"\n | \"user-read-email\"\n | \"user-read-private\";\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpotifyConfig, SpotifySession } from "./ExpoSpotifySDK.types";
|
|
2
2
|
declare function isAvailable(): boolean;
|
|
3
|
-
declare function authenticateAsync(
|
|
3
|
+
declare function authenticateAsync(config: SpotifyConfig): Promise<SpotifySession>;
|
|
4
4
|
declare const Authenticate: {
|
|
5
5
|
authenticateAsync: typeof authenticateAsync;
|
|
6
6
|
};
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGvE,iBAAS,WAAW,IAAI,OAAO,CAE9B;AAED,iBAAS,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAMzE;AAED,QAAA,MAAM,YAAY;;CAEjB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -2,8 +2,11 @@ import ExpoSpotifySDKModule from "./ExpoSpotifySDKModule";
|
|
|
2
2
|
function isAvailable() {
|
|
3
3
|
return ExpoSpotifySDKModule.isAvailable();
|
|
4
4
|
}
|
|
5
|
-
function authenticateAsync(
|
|
6
|
-
|
|
5
|
+
function authenticateAsync(config) {
|
|
6
|
+
if (!config.scopes || config.scopes?.length === 0) {
|
|
7
|
+
throw new Error("scopes are required");
|
|
8
|
+
}
|
|
9
|
+
return ExpoSpotifySDKModule.authenticateAsync(config);
|
|
7
10
|
}
|
|
8
11
|
const Authenticate = {
|
|
9
12
|
authenticateAsync,
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAE1D,SAAS,WAAW;IAClB,OAAO,oBAAoB,CAAC,WAAW,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAE1D,SAAS,WAAW;IAClB,OAAO,oBAAoB,CAAC,WAAW,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAqB;IAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,oBAAoB,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,YAAY,GAAG;IACnB,iBAAiB;CAClB,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { SpotifyConfig, SpotifySession } from \"./ExpoSpotifySDK.types\";\nimport ExpoSpotifySDKModule from \"./ExpoSpotifySDKModule\";\n\nfunction isAvailable(): boolean {\n return ExpoSpotifySDKModule.isAvailable();\n}\n\nfunction authenticateAsync(config: SpotifyConfig): Promise<SpotifySession> {\n if (!config.scopes || config.scopes?.length === 0) {\n throw new Error(\"scopes are required\");\n }\n\n return ExpoSpotifySDKModule.authenticateAsync(config);\n}\n\nconst Authenticate = {\n authenticateAsync,\n};\n\nexport { isAvailable, Authenticate };\n"]}
|
|
@@ -4,22 +4,17 @@ struct ExpoSpotifyConfiguration: Codable {
|
|
|
4
4
|
let clientID: String
|
|
5
5
|
let host: String
|
|
6
6
|
let scheme: String
|
|
7
|
-
|
|
8
|
-
let tokenSwapURL: URL?
|
|
9
|
-
|
|
7
|
+
|
|
10
8
|
var redirectURL: URL? {
|
|
11
9
|
return URL(string: "\(scheme)://\(host)")
|
|
12
10
|
}
|
|
13
|
-
|
|
11
|
+
|
|
14
12
|
init(clientID: String = "defaultClientID",
|
|
15
13
|
host: String = "defaultHost",
|
|
16
|
-
scheme: String = "defaultScheme"
|
|
17
|
-
|
|
18
|
-
tokenSwapURL: URL? = nil) {
|
|
14
|
+
scheme: String = "defaultScheme"
|
|
15
|
+
) {
|
|
19
16
|
self.clientID = clientID
|
|
20
17
|
self.host = host
|
|
21
18
|
self.scheme = scheme
|
|
22
|
-
self.tokenRefreshURL = tokenRefreshURL
|
|
23
|
-
self.tokenSwapURL = tokenSwapURL
|
|
24
19
|
}
|
|
25
20
|
}
|
|
@@ -2,31 +2,44 @@ import ExpoModulesCore
|
|
|
2
2
|
import SpotifyiOS
|
|
3
3
|
|
|
4
4
|
public class ExpoSpotifySDKModule: Module {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
|
|
7
6
|
public func definition() -> ModuleDefinition {
|
|
8
|
-
|
|
7
|
+
|
|
9
8
|
let spotifySession = ExpoSpotifySessionManager.shared
|
|
10
|
-
|
|
9
|
+
|
|
11
10
|
Name("ExpoSpotifySDK")
|
|
12
|
-
|
|
11
|
+
|
|
13
12
|
Function("isAvailable") {
|
|
14
13
|
return spotifySession.spotifyAppInstalled()
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
AsyncFunction("
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
|
|
16
|
+
AsyncFunction("authenticateAsync") { (config: [String: Any], promise: Promise) in
|
|
17
|
+
guard let scopes = config["scopes"] as? [String] else {
|
|
18
|
+
promise.reject("INVALID_CONFIG", "Invalid SpotifyConfig object")
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let tokenSwapURL = config["tokenSwapURL"] as? String
|
|
23
|
+
let tokenRefreshURL = config["tokenRefreshURL"] as? String
|
|
24
|
+
let shouldRequestAccessToken = config["shouldRequestAccessToken"] as? Bool ?? true
|
|
25
|
+
|
|
26
|
+
spotifySession.authenticate(scopes: scopes, tokenSwapURL: tokenSwapURL, tokenRefreshURL: tokenRefreshURL, shouldRequestAccessToken: shouldRequestAccessToken).done { result in
|
|
27
|
+
switch result {
|
|
28
|
+
case .session(let session):
|
|
29
|
+
promise.resolve([
|
|
30
|
+
"accessToken": session.accessToken,
|
|
31
|
+
"refreshToken": session.refreshToken,
|
|
32
|
+
"expirationDate": Int(session.expirationDate.timeIntervalSince1970 * 1000),
|
|
33
|
+
"scopes": SPTScopeSerializer.serializeScopes(session.scope),
|
|
34
|
+
"isExpired": session.isExpired
|
|
35
|
+
])
|
|
36
|
+
case .authorizationCode(let code):
|
|
37
|
+
promise.resolve(["code": code])
|
|
38
|
+
}
|
|
27
39
|
}.catch { error in
|
|
28
40
|
promise.reject(error)
|
|
29
41
|
}
|
|
30
42
|
}
|
|
43
|
+
|
|
31
44
|
}
|
|
32
45
|
}
|
|
@@ -3,14 +3,24 @@ import SpotifyiOS
|
|
|
3
3
|
|
|
4
4
|
extension ExpoSpotifySessionManager: SPTSessionManagerDelegate {
|
|
5
5
|
public func sessionManager(manager _: SPTSessionManager, didInitiate session: SPTSession) {
|
|
6
|
-
|
|
6
|
+
if shouldRequestAccessToken {
|
|
7
|
+
authPromiseSeal?.fulfill(AuthenticationResult.session(session))
|
|
8
|
+
}
|
|
7
9
|
}
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
public func sessionManager(manager _: SPTSessionManager, didFailWith error: Error) {
|
|
10
12
|
authPromiseSeal?.reject(error)
|
|
11
13
|
}
|
|
12
|
-
|
|
14
|
+
|
|
13
15
|
public func sessionManager(manager _: SPTSessionManager, didRenew session: SPTSession) {
|
|
14
|
-
authPromiseSeal?.fulfill(session)
|
|
16
|
+
authPromiseSeal?.fulfill(AuthenticationResult.session(session))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public func sessionManager(manager: SPTSessionManager, shouldRequestAccessTokenWith code: String) -> Bool {
|
|
20
|
+
if !shouldRequestAccessToken {
|
|
21
|
+
authPromiseSeal?.fulfill(AuthenticationResult.authorizationCode(code))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return shouldRequestAccessToken
|
|
15
25
|
}
|
|
16
26
|
}
|
|
@@ -2,16 +2,24 @@ import ExpoModulesCore
|
|
|
2
2
|
import SpotifyiOS
|
|
3
3
|
import PromiseKit
|
|
4
4
|
|
|
5
|
+
enum AuthenticationResult {
|
|
6
|
+
case session(SPTSession)
|
|
7
|
+
case authorizationCode(String)
|
|
8
|
+
}
|
|
9
|
+
|
|
5
10
|
enum SessionManagerError: Error {
|
|
6
11
|
case notInitialized
|
|
12
|
+
case invalidConfiguration
|
|
7
13
|
}
|
|
8
14
|
|
|
9
15
|
final class ExpoSpotifySessionManager: NSObject {
|
|
10
16
|
weak var module: ExpoSpotifySDKModule?
|
|
11
|
-
var authPromiseSeal: Resolver<
|
|
12
|
-
|
|
17
|
+
var authPromiseSeal: Resolver<AuthenticationResult>?
|
|
18
|
+
|
|
19
|
+
var shouldRequestAccessToken: Bool = true
|
|
20
|
+
|
|
13
21
|
static let shared = ExpoSpotifySessionManager()
|
|
14
|
-
|
|
22
|
+
|
|
15
23
|
private var expoSpotifyConfiguration: ExpoSpotifyConfiguration? {
|
|
16
24
|
guard let expoSpotifySdkDict = Bundle.main.object(forInfoDictionaryKey: "ExpoSpotifySDK") as? [String: String],
|
|
17
25
|
let clientID = expoSpotifySdkDict["clientID"],
|
|
@@ -20,63 +28,71 @@ final class ExpoSpotifySessionManager: NSObject {
|
|
|
20
28
|
{
|
|
21
29
|
return nil
|
|
22
30
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let tokenSwapURL = URL(string: expoSpotifySdkDict["tokenSwapURL"] ?? "")
|
|
26
|
-
|
|
27
|
-
return ExpoSpotifyConfiguration(clientID: clientID, host: host, scheme: scheme, tokenRefreshURL: tokenRefreshURL, tokenSwapURL: tokenSwapURL)
|
|
31
|
+
|
|
32
|
+
return ExpoSpotifyConfiguration(clientID: clientID, host: host, scheme: scheme)
|
|
28
33
|
}
|
|
29
|
-
|
|
34
|
+
|
|
30
35
|
lazy var configuration: SPTConfiguration? = {
|
|
31
36
|
guard let clientID = expoSpotifyConfiguration?.clientID,
|
|
32
37
|
let redirectURL = expoSpotifyConfiguration?.redirectURL else {
|
|
33
38
|
NSLog("Invalid Spotify configuration")
|
|
34
39
|
return nil
|
|
35
40
|
}
|
|
36
|
-
|
|
41
|
+
|
|
37
42
|
return SPTConfiguration(clientID: clientID, redirectURL: redirectURL)
|
|
38
43
|
}()
|
|
39
|
-
|
|
44
|
+
|
|
40
45
|
lazy var sessionManager: SPTSessionManager? = {
|
|
41
46
|
guard let configuration = configuration else {
|
|
42
47
|
return nil
|
|
43
48
|
}
|
|
44
|
-
|
|
45
|
-
configuration.tokenSwapURL = expoSpotifyConfiguration?.tokenSwapURL
|
|
46
|
-
configuration.tokenRefreshURL = expoSpotifyConfiguration?.tokenRefreshURL
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
return SPTSessionManager(configuration: configuration, delegate: self)
|
|
49
51
|
}()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
func authenticate(
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
func authenticate(scopes: [String], tokenSwapURL: String?, tokenRefreshURL: String?, shouldRequestAccessToken: Bool = true) -> PromiseKit.Promise<AuthenticationResult> {
|
|
53
55
|
return Promise { seal in
|
|
54
|
-
guard let
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
guard let clientID = expoSpotifyConfiguration?.clientID,
|
|
57
|
+
let redirectURL = expoSpotifyConfiguration?.redirectURL else {
|
|
58
|
+
NSLog("Invalid Spotify configuration")
|
|
59
|
+
seal.reject(SessionManagerError.invalidConfiguration)
|
|
57
60
|
return
|
|
58
61
|
}
|
|
59
|
-
|
|
62
|
+
let configuration = SPTConfiguration(clientID: clientID, redirectURL: redirectURL)
|
|
63
|
+
|
|
64
|
+
if (tokenSwapURL != nil) {
|
|
65
|
+
configuration.tokenSwapURL = URL(string: tokenSwapURL ?? "")
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (tokenRefreshURL != nil) {
|
|
69
|
+
configuration.tokenRefreshURL = URL(string: tokenRefreshURL ?? "")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
self.shouldRequestAccessToken = shouldRequestAccessToken
|
|
73
|
+
self.configuration = configuration
|
|
74
|
+
self.sessionManager = SPTSessionManager(configuration: configuration, delegate: self)
|
|
75
|
+
|
|
60
76
|
self.authPromiseSeal = seal
|
|
61
|
-
|
|
77
|
+
|
|
62
78
|
DispatchQueue.main.sync {
|
|
63
|
-
sessionManager
|
|
79
|
+
sessionManager?.initiateSession(with: SPTScopeSerializer.deserializeScopes(scopes), options: .default)
|
|
64
80
|
}
|
|
65
81
|
}
|
|
66
82
|
}
|
|
67
|
-
|
|
83
|
+
|
|
68
84
|
func spotifyAppInstalled() -> Bool {
|
|
69
85
|
guard let sessionManager = sessionManager else {
|
|
70
|
-
NSLog("
|
|
86
|
+
NSLog("SPTSessionManager not initialized")
|
|
71
87
|
return false
|
|
72
88
|
}
|
|
73
|
-
|
|
89
|
+
|
|
74
90
|
var isInstalled = false
|
|
75
|
-
|
|
91
|
+
|
|
76
92
|
DispatchQueue.main.sync {
|
|
77
93
|
isInstalled = sessionManager.isSpotifyAppInstalled
|
|
78
94
|
}
|
|
79
|
-
|
|
95
|
+
|
|
80
96
|
return isInstalled
|
|
81
97
|
}
|
|
82
98
|
}
|
package/package.json
CHANGED
package/plugin/build/index.js
CHANGED
|
@@ -5,13 +5,16 @@ const withSpotifyAndroidAppBuildGradle_1 = require("./android/withSpotifyAndroid
|
|
|
5
5
|
const withSpotifyQueryScheme_1 = require("./ios/withSpotifyQueryScheme");
|
|
6
6
|
const withSpotifyURLScheme_1 = require("./ios/withSpotifyURLScheme");
|
|
7
7
|
const withSpotifyConfig_1 = require("./withSpotifyConfig");
|
|
8
|
-
const withSpotifySdkConfig = (config, spotifyConfig
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
8
|
+
const withSpotifySdkConfig = (config, spotifyConfig) => {
|
|
9
|
+
if (!spotifyConfig.host) {
|
|
10
|
+
throw new Error("Missing required Spotify config value: host");
|
|
11
|
+
}
|
|
12
|
+
if (!spotifyConfig.scheme) {
|
|
13
|
+
throw new Error("Missing required Spotify config value: scheme");
|
|
14
|
+
}
|
|
15
|
+
if (!spotifyConfig.clientID) {
|
|
16
|
+
throw new Error("Missing required Spotify config value: clientID");
|
|
17
|
+
}
|
|
15
18
|
config = (0, withSpotifyConfig_1.withSpotifyConfig)(config, spotifyConfig);
|
|
16
19
|
// Android specific
|
|
17
20
|
config = (0, withSpotifyAndroidAppBuildGradle_1.withSpotifyAndroidAppBuildGradle)(config, spotifyConfig);
|