通过在离子框架中使用 $cordovaFileTransfer 将 facebook 个人资料图片下载到移动应用程序 StorageDirectory

Download facebook profile pictures to mobile applicationStorageDirectory via using $cordovaFileTransfer in ionic framework

我正在 ionic 框架中开发应用程序。

我在控制器中有一个函数应该下载 facebook 个人资料图片,如下所示($rootScope.user_friends 是对象数组,在对象的 fb_id 属性 中具有要下载其个人资料图片的用户的 facebook id):

$scope.downloadDP = function() {

    // Make an API call for getting facebook profile picture URL
    Session.userFBProfilePicture($rootScope.user_friends, function(response) {

        console.log(response);

    });

};

以下是service/factory方法:

// Makes API call for user's facebook DP URL
userFBProfilePicture: function(data_array, callback) {

    var promises = [];

    for (var i = 0; i < data_array.length; i++) {

        var deffered = $q.defer();
        var data = data_array[i];

        $http({
            method: 'GET',
            url: 'https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false',
        }).
        success(function(data) {

            var url = data.url;
            var targetPath = cordova.file.applicationStorageDirectory + "MyApp/" + data.mobile + ".png";
            var trustHosts = true;
            var options = {};

            $cordovaFileTransfer.download(url, targetPath, options, trustHosts)
                .then(function(result) {
                    deffered.resolve(result);
                }, function(err) {
                    deffered.reject();
                });



        }).
        error(function(error) {
            deffered.reject();
        });

        promises.push(deffered);
    }

    return $q.all(promises);


},

https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false url 的网络调用成功进行,我得到一个对象,而不是服务器重定向,其 data.url 给出了用户个人资料图片的实际位置。

我参考了这个博客 post : https://www.raymondcamden.com/2015/04/13/chaining-multiple-cordova-file-transfers-with-ngcordova/ 并试图做出相应的承诺,但没有成功。

此外,我在控制器方法的 console.log(response); 中什么也得不到。我不确定我哪里出错了,任何help/pointers非常感谢。

当我查看 $http 文档时,这里是我看到的示例。

// Simple GET request example:
$http({
  method: 'GET',
  url: '/someUrl'
}).then(function successCallback(response) {
    // this callback will be called asynchronously
    // when the response is available
  }, function errorCallback(response) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

也许试试 .then

.success 方法是我不熟悉的方法吗?抱歉,如果这不是主题,但这是我在查看您的代码时的第一个想法。

编辑刚刚在 here 上看到这个。

Deprecation Notice The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.

谢谢。

我认为问题在于您如何在控制器级别解决承诺,您正在以回调方式处理它。正确的实现应该是

Session.userFBProfilePicture($rootScope.user_friends)
 .then(function(response) {
   console.log(response);
   // bind the data.url to the scope or View Model and use ng-src in your view
 })
 .catch(function(err) {
   // handle error
 });

此外,@jamesmpw 是正确的,您应该将 .then promise 结构与 $http 一起使用以避免遗留错误。

我更喜欢使用 async 库进行异步操作,例如数据库或 api 调用数组。

所以函数会像

// Makes API call for user's facebook DP URL
userFBProfilePicture: function(data_array, callback) {

var results_array= [];
var deffered = $q.defer();
async.each(data_array, function(data, callback) {


    $http({
        method: 'GET',
        url: 'https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false',
    }).
    then(function(data) {

        var url = data.url;
        var targetPath = cordova.file.applicationStorageDirectory + "MyApp/" + data.mobile + ".png";
        var trustHosts = true;
        var options = {};

        $cordovaFileTransfer.download(url, targetPath, options, trustHosts)
            .then(function(result) {
                results_array.push(result);
                callback();
            }, function(err) {
               callback(err);
            });



    }, function(error) {
        callback(error);
    });
}, function(err){
// if any of the input produced an error, err would equal that error
if( err ) {
  // One of the iterations produced an error.
  // All processing will now stop.
  return deffered.reject(err);
} else {
  return deffered.resolve(results_array);
}
})

return deffered.promise;
},

此函数将 return 一个承诺。所以你可以相应地处理它。