The Event Loop
In order to do work, the library function SpPumpEvents() must be called periodically. This is where the library performs all asynchronous operations, and this is where it invokes the callback functions that the application registers (such as the error callback that is specified in SpConfig::error_callback).
There are two major ways to write the main event loop:
- Call SpPumpEvents() from the application's main event loop
- Call SpPumpEvents() from a separate thread and communicate with the application's main thread
In both cases, you must make sure that you never invoke Spotify Embedded APIs from different threads. The Spotify Embedded SDK is not thread-safe, and will typically refuse to execute APIs called from another thread. See Threading for details.
Logging In And Logging Out
Note: The following example uses SpConnectionLoginOauthToken() to log in. This API exists for testing purposes only.
In order to be certified, hardware devices must either enable the internal ZeroConf implementation (see SpConfig::zeroconf_serve), or implement the ZeroConf in the eSDK integration and use the function SpConnectionLoginZeroConf() to log in.
Change the code from the previous example so that it passes a valid Spotify OAuth access token (see Authorization Guide) to SpConnectionLoginOauthToken(). Register a callback of type SpCallbackConnectionNotify() by calling SpRegisterConnectionCallbacks() to receive the notification kSpConnectionNotifyLoggedInwhen login is successful.
As soon as the example application has logged in successfully, it will log out again using SpConnectionLogout() and wait for the notification kSpConnectionNotifyLoggedOut.
Here is the new code:
_68int has_logged_in = 0;_68int has_logged_out = 0;_68_68static void CallbackConnectionNotify(enum SpConnectionNotification event,_68 void *context) {_68 switch (event) {_68 case kSpConnectionNotifyLoggedIn:_68 LOG("Logged in\n");_68 has_logged_in = 1;_68 break;_68 case kSpConnectionNotifyLoggedOut:_68 LOG("Logged out\n");_68 has_logged_in = 0;_68 has_logged_out = 1;_68 break;_68..._68_68 default:_68 break;_68 }_68}_68_68..._68_68int main(int argc, char *argv[]) {_68 SpError err;_68 struct SpConnectionCallbacks connection_callbacks;_68_68 memset(&connection_callbacks, 0, sizeof(connection_callbacks));_68 connection_callbacks.on_notify = CallbackConnectionNotify;_68_68..._68_68 if (kSpErrorOk != (err = SpInit(&conf)))_68 LOG("Error %d\n", err);_68 return 0;_68 }_68_68 SpRegisterConnectionCallbacks(&connection_callbacks, NULL);_68_68 err = SpConnectionLoginOauthToken(YOUR_OAUTH_TOKEN);_68 if (err != kSpErrorOk) {_68 LOG("Error %d\n", err);_68 SpFree();_68 return 0;_68 }_68_68 while (1) {_68 err = SpPumpEvents();_68 if (kSpErrorOk != err || error_occurred) {_68 goto end;_68 }_68_68 if (has_logged_in) {_68 LOG("Login was successful. Logging out again.\n");_68 has_logged_in = 0;_68 SpConnectionLogout();_68 }_68 if (has_logged_out) {_68 LOG("Logged out. Exiting.\n");_68 break;_68 }_68 }_68_68 SpFree();_68_68 return 0;_68}
Writing Callbacks
The application should not perform time-consuming tasks in any of the callbacks. Try to return from the callback as quickly as possible. If a time-consuming operation needs to be performed as a reaction to an event, the callback should trigger an asynchronous task.
Note: Only Spotify Embedded API functions that are explicitly marked as such are allowed to be invoked from callbacks.