Skip to content

Instantly share code, notes, and snippets.

@joewright
Last active November 18, 2015 13:40
Show Gist options
  • Save joewright/14e93b4de285bdc1adb0 to your computer and use it in GitHub Desktop.
Save joewright/14e93b4de285bdc1adb0 to your computer and use it in GitHub Desktop.
PokitDok API Titanium example
/***
* Ti PD API
*
* App.config -> global config namespace
* we connect to a proxy instead of the API directly
* to avoid storing credentials on the client
*
*
* // Example api request
* api.request({
* method: 'GET',
* path: '/businesses',
* callback: function (err, res) {});
*
*/
var refreshActive = false,
retryQueue = [];
/***
* make an api call to pokitdok
* @param args
* @returns {*}
*/
exports.request = function (args) {
if (Ti.Network.online === false) {
// network unavailable message i18n
alert(L('networkUnavailableBody'));
return args.callback(true, L('networkUnavailableBody'));
}
var client = Ti.Network.createHTTPClient({
// hande 2XX response codes
onload: function (e) {
// Ti.API.info('Request: ' + args.method + ':' + url + ' ' + this.status);
// the UI can only process valid JSON
try {
var resJSON = JSON.parse(this.responseText);
// Ti.API.info(resJSON);
args.callback(null, resJSON);
} catch (e) {
Ti.API.info('JSON parse failure: ', e);
args.callback(true, {
message: this.responseText,
status: this.status
});
}
},
// handle non 2XX response codes
onerror: function (e) {
Ti.API.error('Request: ' + args.method + ':' + url + ' ' + this.status);
Ti.API.error('Request: ' + args.method + ':' + url + ' ' + this.responseText);
// auto-refresh the oauth token
if (this.status == 400 || this.status == 401) {
return refreshToken(args);
}
// the UI can only process valid JSON
try {
var resJSON = JSON.parse(this.responseText);
return args.callback(true, resJSON);
} catch (e) {
return args.callback(true, {
message: this.responseText,
status: this.status
});
}
},
// kill long lived requests
timeout: App.config.HTTP_TIMEOUT
});
// open Request
var url = App.config.API_PROXY_URL + args.path;
client.open(args.method, url);
// attach the oauth bearer token
var accessToken = Ti.App.Properties.getString('accessToken', false);
if (accessToken) {
client.setRequestHeader('Authorization', 'Bearer ' + accessToken);
}
// make sure POST data is JSON
if (args.data) {
client.setRequestHeader('Content-Type', 'application/json');
}
// send the current version
client.setRequestHeader('X-App-Version', 'iOS.' + App.config.VERSION);
// send Request
Ti.API.info('\n\n\nSending Reqest:' + App.config.API_PROXY_URL + args.path);
args.data && Ti.API.info(args.data);
(args.data) ? client.send(JSON.stringify(args.data)) : client.send();
// return the HTTP client for cancellation
return client;
};
/***
* refresh a users oauth2 token and retry
* the api request
* @param requestArgs
*/
function refreshToken(requestArgs) {
// protect against parallel refreshes
retryQueue.push(requestArgs);
if (refreshActive) {
return false;
}
var client = Ti.Network.createHTTPClient({
// hande 2XX response codes
onload: function (e) {
Ti.API.info('Request: POST:/oauth2/token ' + this.status);
// the UI can only process valid JSON
try {
var resJSON = JSON.parse(this.responseText);
// replace the existing oauth tokens
Ti.App.Properties.setString('accessToken', resJSON.access_token);
Ti.App.Properties.setString('refreshToken', resJSON.refresh_token);
// retry any queued requests
while (0 < retryQueue.length) {
exports.request(retryQueue.pop());
}
refreshActive = false;
} catch (e) {
requestArgs.callback(true, {
message: this.responseText,
status: this.status
});
// disable additional requests
refreshActive = false;
retryQueue = [];
// kill the sesssion on any refresh errors
if (Ti.App.Properties.getString('accessToken')) {
App.fireEvent('logout');
}
}
},
// handle non 2XX response codes
onerror: function (e) {
Ti.API.error('Request: POST:/refresh-token ' + this.status);
// the UI can only process valid JSON
try {
var resJSON = JSON.parse(this.responseText);
requestArgs.callback(true, resJSON);
} catch (e) {
requestArgs.callback(true, {
message: this.responseText,
status: this.status
});
}
// disable additional requests
refreshActive = false;
retryQueue = [];
// kill the sesssion on any refresh errors
if (Ti.App.Properties.getString('accessToken')) {
App.fireEvent('logout');
}
},
// kill long lived requests
timeout: App.config.HTTP_TIMEOUT
});
// open Request
client.open('POST', App.config.API_PROXY_URL + '/refresh-token');
// only send JSON
client.setRequestHeader('Content-Type', 'application/json');
// send the current version
client.setRequestHeader('X-App-Version', 'iOS.' + App.config.VERSION);
// send the request
client.send(JSON.stringify({
refresh_token: Ti.App.Properties.getString('refreshToken', '')
}));
// protect against parallel refreshes
refreshActive = true;
return client;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment