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.
Perform a function only after the first function is completed - ios
-
04-10-2022 - |
Question
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.
No correct solution
OTHER TIPS
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.
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
}
}