Статьи

Работа с Ionic, Box и IBM MobileFirst

Ранее сегодня IBM объявила о новом партнерстве с Box. Box — поставщик облачных хранилищ, очень похожий на Dropbox, OneDrive и другие сервисы, но также предоставляет некоторые довольно интересные функции рабочего процесса. Пока еще рано, скоро вы увидите несколько интересных взаимодействий между IBM и Box. Я решил посмотреть, насколько легко будет интегрировать Box в гибридное мобильное приложение, используя как Ionic, так и IBM MobileFirst . Это просто простое доказательство концепции, но оно демонстрирует, как вы можете использовать все эти разные части вместе в одном приложении.

Прежде чем углубиться в код, давайте посмотрим на несколько скриншотов приложения в действии. При загрузке приложения вы увидите кнопку, предлагающую войти в систему с помощью Box.

Снимок экрана iOS-симулятора 24 июня 2015 г., 7.55.58

Нажатие на эту кнопку начнет процесс аутентификации. Вы должны иметь учетную запись на Box.com, конечно.

Снимок экрана iOS-симулятора 24 июня 2015 г., 7.57.47

После входа в систему вы должны разрешить приложению доступ к вашим данным:

Снимок экрана iOS-симулятора 24 июня 2015 г., 7.59.09

После того, как вы разрешили приложению доступ к вашей учетной записи Box, вы можете приступить к работе с вашими данными. Для демонстрации я просто позволил приложению загружать изображения с устройства в учетную запись Box. (Вы можете изменить код, чтобы новые снимки можно было делать с помощью камеры. Поскольку я проводил тестирование на симуляторе, я ограничил его существующими снимками.)

Снимок экрана iOS-симулятора 24 июня 2015 г., 8.01.00

После выбора изображения я отображаю эскиз и затем загружаю его.

Снимок экрана iOS-симулятора 24 июня 2015 г., 8.02.20

Если ваша учетная запись Box открыта в браузере (у них также есть настольный клиент), вы можете увидеть изображение.

Shot1

Вот и все. Box API обеспечивает полный доступ к содержимому Box, а не только загрузку. Вы даже можете использовать специальный API просмотра для отображения воспроизведения содержимого Box. Это довольно хороший API, и я призываю вас прочитать больше об этом на их сайте разработчика . Итак — поговорим о коде.

Чтобы справиться с OAuth, я использовал замечательную библиотеку от Nic Raboy под названием ng-cordova-oauth . Он обеспечивает поддержку OAuth для различных задач, в том числе Box. Насколько это просто? Вот код позади кнопки, которую вы видели на снимке экрана выше.

$scope.doAuth = function() {
Logger.log("Beginning to auth against Box");

$cordovaOauth.box(clientId, clientSecret,state).then(function(result) {
Logger.log("Successful log to Box");
token = result.access_token;
$scope.noAuth = false;
}, function(error) {
console.log('Error',error);
});
}

Да, вот и все. Тогда использовать сам API довольно просто. Сначала я написал некоторый код, чтобы просто протестировать использование API, в моем случае запрашивая папки в корне учетной записи. Вот как я это сделал, используя $ http-сервис Angular:

$scope.getFolders = function() {
console.log("attempting to get folders");

$http.defaults.headers.common.Authorization = 'Bearer '+token;

$http.get("https://api.box.com/2.0/folders/0").success(function(data, status, headers, config) {
console.log('succcess');
console.dir(data);
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
console.log('error');
console.dir(arguments);
 });
}

Единственная интересная часть здесь — это установка токена OAuth в заголовке. Вы можете видеть, что это одна простая строка до получения. Технически мне нужно сделать это только один раз и установить это после входа в систему — но, как я уже сказал, я написал это просто как тест API. Загрузка файлов была немного более сложной. Вместо $ http я использовал плагин Cordova FileTransfer. Это позволило мне загрузить файл изображения, выбранный пользователем. Вот вся операция, включая выбор камеры и загрузку.

$scope.doPicture = function() {

navigator.camera.getPicture(function(uri) {
$scope.selectedImage = uri;
$scope.status.message = "Uploading bits to Box...";
$scope.$apply();

Logger.log("Going to send a file to Box");

var win = function (r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
    $scope.status.message = "Sent to box!";
    Logger.log("Sent a file to box!");
    $scope.$apply();
}

var fail = function (error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
    Logger.log("Failed to send to Box");
}

var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = uri.substr(uri.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";

var headers={'Authorization':'Bearer '+token};

options.headers = headers;

var params = {};
params.attributes = '{"name":"'+options.fileName+'", "parent":{"id":"0"}}';

options.params = params;
var ft = new FileTransfer();
ft.upload(uri, encodeURI("https://upload.box.com/api/2.0/files/content"), win, fail, options);


}, function(err) {
console.log("Camera error", err);
}, {
quality:25,
destinationType:Camera.DestinationType.FILE_URI,
sourceType:Camera.PictureSourceType.PHOTOLIBRARY
});

}

And that’s it. I then mixed in MobileFirst – specifically the logging service. I blogged about this a few months back (). It is a rather simple API I can make available via a service in my app:

}).factory('Logger', function() {

var logger = WL.Logger.create({autoSendLogs:true});

return {
log:function(s) {
logger.log('log', s);
        console.log(s);
}
}
})

Then when I inject Logger into my controllers, I can just do Logger.log("some message"). There were a few examples of that above. Then when my application is out in the wild, I can look at my analytics in my MobileFirst server:

Shot2

Want to see all of the code? You can see all the code here: https://github.com/cfjedimaster/Cordova-Examples/tree/master/boxdemo_mfp. Note that I ran into two small issues with Nic’s OAuth plugin. The first is that after authenticating with Box, you will see a 404 error temporarily. Nic already has a fix for this in the dev branch of his library. It is harmless and can be ignored. The second issue was specifically involving his code running in MobileFirst. Plugins act a bit differently there and his code to check for the InAppBrowser didn’t work. (To be clear, that one is absolutely not his fault.) The workaround was a quick mod to his code and is in the GitHub repo. You can see a video of the app in action below.