FatFractal customer forums



Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - dev

Pages: [1]
1
NoServer Questions and Answers / Re: Public extension
« on: November 24, 2014, 10:16:39 AM »
I can't get this to work.

I copy pasted the code to Auth.js with my instagram_client_id and my instagram_client_secret.

And I in my app:
Code: [Select]
[[FF main] setCallbackUri:@"myCallbackURI" forScriptAuthService:@"INSTAGRAM"];
And then by the looks of how use the Facebook and Twitter from your documentation, I'll try this:
Code: [Select]
[[FF main] retrieveAccessTokenForScriptAuthService:@"INSTAGRAM" callbackUriWithVerifier:@"myCallbackURI" onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
       
        if (theErr) {
            NSLog(@"INSTA ERROR %@", theErr.localizedDescription);
        }else{
            NSLog(@"INSTA SUCCESS %@", theObj);
        }
    }];

The app crashes at:
Code: [Select]
[FatFractal urlEncodeString:]

2
NoServer Questions and Answers / Advanced leaderboards and positions
« on: August 15, 2014, 10:39:28 AM »
Hello,

We want to build a rather advanced leaderboard system on the server-side.

In our game the user plays different hashtags and earn points when they win. The user can create own hashtags and play with them as well.

The user should also be able to see unique leaderboard for each hashtag and find their own position in this leaderboard.

So I guess the collections would look something like this:

Hashtag
name

UserHashtag
user (REF to a FFUser)
points
hashtag (REF to Hashtag)

Can this be done? We realize it can get pretty heavy for the server with a lot of users, especially if you want to find your own position.



3
Ah There you go. Thanks Gary

4
I'm trying to retrieve serialized data back from a post to extension method but it doesn't seem to work, it returns JSON.
I've done it with a getArrayFromExtension before and that has worked as expected.
Code: [Select]
[[FF main] postObj:@{@"ids": ids} toExtension:@"/usersFromFacebook" onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
            if (theErr) {
                NSLog(@"%@", theErr);
            }else{
                //This is JSON
            }
        }];

Server-side:
Code: [Select]
var ff = require('ffef/FatFractal');

function ExtentionResponse() {
    this.clazz = "FacebookUsers";
    this.users = null;
}
var usersFromFacebook = function() {
    var data = ff.getExtensionRequestData();
    var facebookIds = data.httpContent.ids;
   
    var facebookUsers = new ExtentionResponse();
    var result = [];
    for (var i = 0; i < facebookIds.length; i++) {
        var facebookId = facebookIds[i]
        var user = ff.getObjFromUri("/FFUser/(facebookId eq '" + facebookId + "')");
       
        result.push(user);
    };
    facebookUsers.users = result;
    var response = ff.response();
    response.result = facebookUsers;
}
exports.usersFromFacebook = usersFromFacebook;

Added a Objective-C class as well:
Code: [Select]
@interface FacebookUsers : NSObject
@property (nonatomic) NSArray *users;
@end

The extension returns the correct data but it's not serialized into FFUser objects.

I also tried it without the mapping object:
Code: [Select]
var ff = require('ffef/FatFractal');

var usersFromFacebook = function() {
    var data = ff.getExtensionRequestData();
    var facebookIds = data.httpContent.ids;
   
    var result = [];
    for (var i = 0; i < facebookIds.length; i++) {
        var facebookId = facebookIds[i]
        var user = ff.getObjFromUri("/FFUser/(facebookId eq '" + facebookId + "')");
       
        result.push(user);
    };
    var response = ff.response();
    response.result = result;
}
exports.usersFromFacebook = usersFromFacebook;

Best
Johan

5
NoServer Questions and Answers / Re: Handle session expiration
« on: April 30, 2014, 04:13:23 AM »
Of course!

6
NoServer Questions and Answers / Re: Handle session expiration
« on: April 29, 2014, 07:30:35 AM »
Yeah the "how to recover where you left off" problem is a hard one..
Not really sure how the delegate could look like, could you share some code-example?

What do think about NSNotificationCenter? The Fat Fractal framework could send a message if the session expires. And the app could register for that notification, something like this:
Code: [Select]
NSNotificationCenter *notificationCenter = [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSessionExpiration:) name:FatFractalSessionDidExpire object:nil];

7
Oh, missed that line. Great news!

8
Best service ever  :)

9
NoServer Questions and Answers / Handle session expiration
« on: April 25, 2014, 09:15:47 AM »
I'm currently caching my logged in user with FFLocalStorageSQLite which works great but I'm not really sure how to handle if the session expires at the moment.
What's the best approach? Should I check in every error if the response code is 401?

Code: [Select]
[[FF] getArrayFromUri:"/Beers" onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
     if (theErr) {
        if (theResponse.statusCode == 401){
           //Session expired, login user
        }
     }else{
           
      //Success

     }
}];

My app has a lot of API calls and checking every request doesn't feel ideal.

10
Gary,
This is so awesome, thank you so much!

Is there any plans on implementing wipes for specific data? Instead of:
Code: [Select]
- (void) wipeAllData
Use something like:
Code: [Select]
- (void) wipeDataWithKey:(NSString*)
Cheers

11
Yes that was it.
Any plans on implementing the opposite?
i.e:
Code: [Select]
FFReadRequest *readRequest;
// ...
[readRequest executeAsyncWithOptions:FFReadOptionDontLoadRefs andBlock:/* ... */];

12
I'm experience some weird behaviour when I use a server-extension. When I call my extension, it invokes 5 more get requests. The extension works and returns the right object but I don't see why it produces the extra get requests. Shouldn't it have all the necessary data from the callback of the extension?
iOS:
Code: [Select]
FFReadRequest *readRequest = [[FF main] newReadRequest];
    [readRequest prepareGetFromExtension:[NSString stringWithFormat:@"/getMatchWithMinigamesAndPhotos?guid=%@", metaData.guid]];
    [readRequest executeAsyncWithBlock:^(FFReadResponse *response) {
       
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self.activityView stopAnimating];
            if (response.error) {
                UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"Error" message:response.error.localizedDescription delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
                [alertView show];
            }else{
                //This returns a correct serialized object of MatchWithMinigamesAndPhotos
                self.scrollView.willBePresentedFromGame = self.willBePresentedFromGame;
                [self.scrollView setTwoPlayerUI:response.obj];
            }
        }];

    }];
Classes:
Code: [Select]
//MatchWithMinigamesAndPhotos

#import <Foundation/Foundation.h>
#import "Match.h"
#import "MinigameDataAndPhotosFromMatch.h"
@interface MatchWithMinigamesAndPhotos : NSObject
@property (nonatomic) Match *match;
@property (nonatomic) NSArray *minigameDataAndPhotos; //Array of MinigameDataAndPhotosFromMatch
@end

//MinigameDataAndPhotosFromMatch

#import <Foundation/Foundation.h>
#import "MinigameData.h"
@interface MinigameDataAndPhotosFromMatch : NSObject
@property (strong, nonatomic) MinigameData *minigameData;
@property (strong, nonatomic) NSArray *photos;
@end
JS:
Code: [Select]
var ff = require('ffef/FatFractal');



var postArrayOfPhotosAndMinigames = function () {
var i, photoObjects, data, result, r, arrayLength;

d = ff.getExtensionRequestData();
data = d.httpContent.minigameData;

function minigameDataObject() {
this.data = null;
this.owner = null;
this.opponent = null;
this.index = null;
this.clazz = "MinigameData";
return this;
}

function photoObject() {
this.url = null;
this.tag = null;
this.likes = null;
this.user = null;
this.userImage = null;
this.clazz = "Photo";
return this;
}
result = [];
for (var k = 0; k < data.length; k++) {
var minigameData = new minigameDataObject();
if (data[k].hasOwnProperty('data')) {
minigameData.data = data[k].data;
}
minigameData.owner = data[k].owner;
minigameData.opponent = data[k].opponent;
minigameData.index = data[k].index;
ff.addReferenceToObj(data[k].minigame, "minigame", minigameData);
ff.addReferenceToObj(data[k].match, "match", minigameData);

var imageData = data[k].imageData;
var minigameWithMeta = ff.createObjAtUri(minigameData, "/MinigameData");
result.push(minigameWithMeta);

//Save photos
for (i = 0; i < imageData.length; i++) {

var photo = new photoObject();
photo.url = imageData[i].url;
photo.tag = imageData[i].tag;
photo.likes = imageData[i].likes;
photo.user = imageData[i].user;
ff.addReferenceToObj(minigameWithMeta.ffUrl, "minigameData", photo);
ff.createObjAtUri(photo, "/Photo")
// result.push();
}


}


r = ff.response();
r.result = result;

};

function ExtentionResponse() {

this.clazz = "MinigameDataAndPhotosFromMatch";
this.minigameData = null;
this.photos = null;
}

function MatchWithMinigamesAndPhotos() {
this.clazz = "MatchWithMinigamesAndPhotos";
this.match = null;
this.minigameDataAndPhotosFromMatch = null;
}
var requestMinigameDataAndPhotosFromMatch = function () {
var photoObjects, data, d, guid, minigameData, result;

d = ff.getExtensionRequestData();
guid = d.httpParameters.guid;

result = [];
minigameData = ff.getArrayFromUri("/Match/" + guid + "/BackReferences.MinigameData.match");
for (var i = 0; i < minigameData.length; i++) {

var minigameDataMeta = minigameData[i];

var photos = ff.getArrayFromUri("/MinigameData/" + minigameDataMeta.guid + "/BackReferences.Photo.minigameData");

var object = new ExtentionResponse();

object.minigameData = minigameData[i];

object.photos = photos;

result.push(object);

}

return result;
};
var requestMatch = function () {
var d = ff.getExtensionRequestData();
var guid = d.httpParameters.guid;
return ff.getObjFromUri("/Match/" + guid);
};
var getMinigameDataAndPhotosFromMatch = function () {
var response = ff.response();
response.result = requestMinigameDataAndPhotosFromMatch();
};
var getMatchWithMinigamesAndPhotos = function () {
var matchWithMinigamesAndPhotos = new MatchWithMinigamesAndPhotos();
matchWithMinigamesAndPhotos.minigameDataAndPhotos = requestMinigameDataAndPhotosFromMatch();
matchWithMinigamesAndPhotos.match = requestMatch();
var response = ff.response();
response.result = matchWithMinigamesAndPhotos;
};

exports.postArrayOfPhotosAndMinigames = postArrayOfPhotosAndMinigames;
exports.getMinigameDataAndPhotosFromMatch = getMinigameDataAndPhotosFromMatch;
exports.getMatchWithMinigamesAndPhotos = getMatchWithMinigamesAndPhotos;

So from xcode it outputs this in the console:

Code: [Select]
2014-04-11 15:37:03.642 SomeProject[20548:60b] invokeHttpMethod: Will send HTTP GET to url: https://someDomain.fatfractal.com/someProject/ff/ext/getMatchWithMinigamesAndPhotos?guid=DCKS4eflvZhC9882GNCXK7

2014-04-11 15:37:04.762 SomeProject[20548:60b] invokeHttpMethod: Will send HTTP GET to url: https://someDomain.fatfractal.com/someProject/ff/resources/MinigameData/YyK0z67t6--u7QvgHD6rs4

2014-04-11 15:37:04.940 SomeProject[20548:60b] invokeHttpMethod: Will send HTTP GET to url: https://someDomain.fatfractal.com/someProject/ff/resources/MinigameData/DUKUE_PRgY9T5cu56Z9Vf5

2014-04-11 15:37:05.603 SomeProject[20548:60b] invokeHttpMethod: Will send HTTP GET to url: https://someDomain.fatfractal.com/someProject/ff/resources/MinigameData/26edZ3b4LWh3wWL4rA5mq5

2014-04-11 15:37:06.280 SomeProject[20548:60b] invokeHttpMethod: Will send HTTP GET to url: https://someDomain.fatfractal.com/someProject/ff/resources/MinigameData/enezYm6aNqdiEqFw3Tgkl4

2014-04-11 15:37:06.960 SomeProject[20548:60b] invokeHttpMethod: Will send HTTP GET to url: https://someDomain.fatfractal.com/someProject/ff/resources/MinigameData/hyuSJeAtkT69OiME9TQP45

13
Great answer, makes perfect sense! Thanks @jonnycools and @gkc

14
Right now I'm getting this in my console in Xcode:

Code: [Select]
(
        {
        minigameData =         {
            clazz = MinigameData;
            createdAt = 1393941214423;
            createdBy = system;
            data =             {
                hashtag = yummy;
            };
            ffRL = "/MinigameData";
            ffRefs =             (
                                {
                    name = match;
                    type = FFO;
                    url = "/ff/resources/Match/Sne504LO0xhEVtuT5ZzpB7";
                },
                                {
                    name = minigame;
                    type = FFO;
                    url = "/ff/resources/Minigame/KYuhPijadobh6w-T3PQFX4";
                }
            );
            ffUrl = "/ff/resources/MinigameData/Th0xlDPpuL5WLJjGyaW1F5";
            guid = Th0xlDPpuL5WLJjGyaW1F5;
            index = 4;
            owner =             {
                score = 4;
                time = "4.97";
            };
            updatedAt = 1393941303564;
            updatedBy = vW0wJgiUZoeRxpimmNIOC7;
            version = 2;
        };
        photos =         (
                        {
                clazz = Photo;
                createdAt = 1393941214541;
                createdBy = system;
                ffRL = "/Photo";
                ffRefs =                 (
                                        {
                        name = minigameData;
                        type = FFO;
                        url = "/ff/resources/MinigameData/Th0xlDPpuL5WLJjGyaW1F5";
                    }
                );

But I don't want the metadata, I want something like this:

Code: [Select]
(
        {
        minigameData = <MinigameData: 0xa9b2330>,
        photos =         (
                                    <Photo: 0xa9b7d20> (NSObject), <Photo: 0xa9acb20> (NSObject)
                               )
               } );

Is this possible? I know if I do this in my server extension:
 
Code: [Select]
for (var i = 0; i < minigameData.length; i++){

result.push(minigameData[i]);

}
r.result = result;

And print it out in Xcode I get an array of converted NSObjects:

Code: [Select]
(<MinigameData: 0xa9b2330> (NSObject),
<MinigameData: 0xa9b2330> (NSObject),
<MinigameData: 0xa9b2330> (NSObject) );

15
NoServer Questions and Answers / Sending back data Server Extension
« on: March 06, 2014, 05:32:00 AM »
I'm trying to reduce my calls from the client so I wrote a server extension to easy access data.
I'm sending a guid from client-side:

Code: [Select]
Match *match // Some match
FFMetaData *meta = [[FF main] metaDataForObj:match];
   
    [[FF main] getArrayFromExtension:[NSString stringWithFormat:@"/getMinigameDataAndPhotosFromMatch?guid=%@", meta.guid] onComplete:^(NSError *theErr, id theObj, NSHTTPURLResponse *theResponse) {
           }
        }
    }];

And this is what I do on the server side:

Code: [Select]
var getMinigameDataAndPhotosFromMatch = function () {
var i, photoObjects, data, ff, r, d, guid, minigameData, result;

ff = require('ffef/FatFractal');
d = ff.getExtensionRequestData();
guid = d.httpParameters.guid;
r = ff.response();
result = [];
minigameData = ff.getArrayFromUri("/Match/" + guid + "/BackReferences.MinigameData.match");
for (var i = 0; i < minigameData.length; i++){

var minigameDataMeta = minigameData[i];

var photos = ff.getArrayFromUri("/MinigameData/" + minigameDataMeta.guid + "/BackReferences.Photo.minigameData");

var object = {minigameData:minigameData[i], photos: photos};

result.push(object);
};

r.result = result;
};

So I'm basically retrieving all minigames related to the match through Backreference and the same with photos related to the Minigame.

The problem is now that it returns me metadata, so this is what I get on the client-side:
Code: [Select]
(
        {
        minigameData =         {
            clazz = MinigameData;
            createdAt = 1393941214423;
            createdBy = system;
            data =             {
                hashtag = yummy;
            };
            ffRL = "/MinigameData";
            ffRefs =             (
                                {
                    name = match;
                    type = FFO;
                    url = "/ff/resources/Match/Sne504LO0xhEVtuT5ZzpB7";
                },
                                {
                    name = minigame;
                    type = FFO;
                    url = "/ff/resources/Minigame/KYuhPijadobh6w-T3PQFX4";
                }
            );
            ffUrl = "/ff/resources/MinigameData/Th0xlDPpuL5WLJjGyaW1F5";
            guid = Th0xlDPpuL5WLJjGyaW1F5;
            index = 4;
            owner =             {
                score = 4;
                time = "4.97";
            };
            updatedAt = 1393941303564;
            updatedBy = vW0wJgiUZoeRxpimmNIOC7;
            version = 2;
        };
        photos =         (
                        {
                clazz = Photo;
                createdAt = 1393941214541;
                createdBy = system;
                ffRL = "/Photo";
                ffRefs =                 (
                                        {
                        name = minigameData;
                        type = FFO;
                        url = "/ff/resources/MinigameData/Th0xlDPpuL5WLJjGyaW1F5";
                    }
                );

 I want it to actually send back Minigame NSObject and a array with Photo NSObject, I guess it has something to do with the javascript object I'm creating.
Is there anyway to achieve this? A NSDictionary with two keys with NSObject content to the client-side?

Pages: [1]
Copyright © FatFractal customer forums