0

In my app, I push local notifications after the user does a certain action.
When the user opens the app from the pushed notification, I want to register an event to a tracking system (in my case is Mixpanel).
I should have a key to register the event which I'm getting this from my server.

So what I want to do is to get the key in a function and after this function has finished, I want to register the event.

I tried performSelectorOnMainThread:withObject:waitUntilDone: but it didn't work

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //some code here
    [self performSelectorOnMainThread:@selector(performHandShake)
                           withObject:nil
                        waitUntilDone:YES];
    [self performSelectorOnMainThread:@selector(registerLaunchOptionsDetails:) 
                           withObject:launchOptions
                        waitUntilDone:YES];
    //some code here
}

-(void)performHandShake
{
   //myParams here

    [[RKClient sharedClient] get:@"/handshake" usingBlock:^(RKRequest *request) {
        request.params = [RKParams paramsWithDictionary:myParams];
        request.method = RKRequestMethodGET;

        request.onDidLoadResponse = ^(RKResponse *response) {
            //Set the tracking key here 
        };

        request.onDidFailLoadWithError = ^(NSError *error) {
            NSLog(@"ERROR:%@",error);
        };
    }];
}

-(void)registerLaunchOptionsDetails:(NSDictionary *)launchOptions
{
    UILocalNotification *localNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];

    if (localNotification) {
       //Register the event here using the key 
    }
 }

The problem is the registerLaunchOptionsDetails function performed before performHandShake is completed and the events are not being registered.

staticVoidMan
  • 19,275
  • 6
  • 69
  • 98
Sawsan
  • 1,096
  • 10
  • 20
  • 1
    Can you just call the `registerLaunchOptionsDetails` function at the end of the handshake function? – John Farkerson Jan 29 '14 at 15:59
  • 1
    You Have just to use Grand Central Dispatch in this case. Using Queues is recommended in these situations – Ali Jan 29 '14 at 16:02
  • 3
    try to call callregisterLaunchOptionsDetails from onDidLoadResponse block? – alex Jan 29 '14 at 16:03
  • @Ali I tried it but it didn't work for me and I think the reason is because I didn't fully understand it. Any recommended links with good example? – Sawsan Jan 29 '14 at 16:10
  • @alex thank you, it works. You can add your comment as answer and I'll accept it. – Sawsan Jan 29 '14 at 16:27
  • nevermind, upvotes aren't my goal over here:) I'm glad to help u. – alex Jan 30 '14 at 11:24

3 Answers3

1

It might be overkill for what you want to do but there is a library similar to async for node. You can chain async tasks together and/or wait till multiple are done before performing another action.

ReactiveCocoa

GregP
  • 1,584
  • 17
  • 16
1

When you execute -[RKClient get:usingBlock], it will create a network operation that will be executed in the background and the method will return.

This will clear the path to registerLaunchOptionsDetails run, which will happen before the network operation has completed.

The request.onDidLoad will run when the network operation is completed successfully and you have the data that was requested. Which is why calling registerLaunchOptionsDetails: there will work there.

Daniel Barden
  • 1,014
  • 10
  • 10
  • Thank you for the explanation of [RKClient get:usingBlock]. I didn't know that. This helps me in understanding the things. – Sawsan Jan 30 '14 at 07:14
1

Block request.onDidLoadResponse will be invoked when you need, so you need to call registerLaunchOptionsDetails: from this block. Don't forget to pass launchOptions to this block through performHandShake and create weak reference to self to prevent it from retain in block. Final code should be like this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //some code here

    [self performSelectorOnMainThread:@selector(performHandShake:) withObject:launchOptions waitUntilDone:YES];


    //some code here

}

-(void)performHandShake:(NSDictionary *)launchOptions
{
    //myParams here

        [[RKClient sharedClient] get:@"/handshake" usingBlock:^(RKRequest *request){

        request.params = [RKParams paramsWithDictionary:myParams];
        request.method = RKRequestMethodGET;

        __weak AppDelegate *weakSelf = self;
        request.onDidLoadResponse = ^(RKResponse *response)
        {

            //Set the tracking key here

            // Here is registerLaunchOptionsDetails: call
            [weakSelf registerLaunchOptionsDetails:launchOptions];
        };

        request.onDidFailLoadWithError = ^(NSError *error)
        {
            NSLog(@"ERROR:%@",error);
        };
    }];

}

-(void)registerLaunchOptionsDetails:(NSDictionary *)launchOptions
{

    UILocalNotification *localNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];

    if (localNotification)
    {
        //Register the event here using the key 


    }
}