Obtain an array with notifications - ios

I am trying to put notifications in an array as they become available, but the count of the array is reset to 1 when I push a new notification.
This is the code:
int r = 0;
listMsgReceived = [[NSMutableArray alloc] init];
if (notification)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Notification received" message:[NSString stringWithFormat:#"%#", message] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
[listMsgReceived insertObject:message atIndex:r];
r++;
NSLog(#"apres: %d \n", [listMsgReceived count]);
}

It looks like you are initializing the variables r and listMsgReceived each time your notification is received (though it's hard to tell from the context you provided).
You should not do that, because that gets you a new array each time, where you insert one object - hence the count will be one after each notification.
You could try moving your array initialization outside of your method; declare it as a property on your class and initialize it in the initializer.

Related

Placeholders for variables in UIAlertView?

I want a UIAlertView to warn the user if there are no items matching his/her chosen search criteria. My initial idea was to use this code:
if (aOiCount == 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No instances of %#",self.thisSpec.activityOfInterest message:#"Please select an activity or Cancel" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
The idea being to slip an actual activity name into the title, like in an NSLog string.
Unfortunately, this doesn't work. Compiler tells me Expected ":"
Is it possible to use a variable like this, and if so, how?
Thanks!
call this line
#"No instances of %#",self.thisSpec.activityOfInterest
in one NSString
NSString *alertstr=[NSString stringWithFormat:#"No instances of %#",self.thisSpec.activityOfInterest];
after that call your UIAlertView and then rearrange the word delegate:nil into delegate:self
if (aOiCount == 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertStr message:#"Please select an activity or Cancel" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
I don't think this is valid Objective C syntax:
initWithTitle:#"No instances of %#",self.thisSpec.activityOfInterest
You need to wrap it in an NSString, or a self-contained form.
Consider one of the many NSString methods, such as stringWithFormat or construct one in a different way. Either way, you should pass a complete string here.

CPDistributedMessagingCenter not working ios7

I am fairly new to jailbreak iOS development and had a question. I am trying to send a message between two processes(MobileSafari to SpringBoard) and am having a problem, the reciever function in SpringBoard is never called! So far in SpringBoard I have this:
-(void)applicationDidFinishLaunching:(id)arg1{
%orig(arg1);
//register for notifications
CPDistributedMessagingCenter *messagingCenter = [CPDistributedMessagingCenter centerNamed:#"com.magnusdevelopment.flow"];
[messagingCenter runServerOnCurrentThread];
[messagingCenter registerForMessageName:#"updateWallpaper" target:self selector:#selector(handleMessageNamed:withUserInfo:)];
[messagingCenter registerForMessageName:#"updateScalingMode" target:self selector:#selector(handleMessageNamed:withUserInfo:)];
[messagingCenter registerForMessageName:#"downloadWallpaper" target:self selector:#selector(handleMessageNamed:withUserInfo:)];
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"Yo!" message:#"registered" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[testAlert show];
}
}
%new
-(NSDictionary *)handleMessageNamed:(NSString *)name withUserInfo:(NSDictionary *)userInfo{
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"Yo!" message:#"2" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[testAlert show];
if([name isEqualToString:#"updateWallpaper"]){
//get info for wallpaper
NSString *wallpaperImagePath = [userInfo objectForKey:#"WALLPAPER_PATH"];
int option = [[userInfo objectForKey:#"OPTION"] intValue];
BOOL retValue = setWallpaperImage(wallpaperImagePath, option);
//return the dictionary
NSMutableDictionary *replyDict = [[NSMutableDictionary alloc] init];
[replyDict setObject:[NSString stringWithFormat:#"%hhd",retValue] forKey:#"RETURN_VALUE"];
return replyDict;
}else if([name isEqualToString:#"updateScalingMode"]){
//get info from dictionary
int option = [[userInfo objectForKey:#"OPTION"] intValue];
NSString *scalingMode = [userInfo objectForKey:#"SCALING_MODE"];
//set wallpaper scaling mode
setWallpaperScalingMode(scalingMode,option);
}//end if
return nil;
}//end method
and when a button is pressed in MobileSafari I call this code:
NSString *option = [NSString stringWithFormat:#"%i",wallpaperOption];
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys: wallpaperPath, #"WALLPAPER_PATH", option, #"OPTION", nil];
CPDistributedMessagingCenter *messagingCenter = [CPDistributedMessagingCenter centerNamed:#"com.magnusdevelopment.flow"];
[messagingCenter sendMessageAndReceiveReplyName:#"downloadWallpaper" userInfo:infoDict];
UIAlertView *testAlert = [[UIAlertView alloc] initWithTitle:#"Yo!" message:#"sent" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[testAlert show];
I get the alert "registered" whenever SpringBoard starts up and then when I press the button I get the message "sent". The only thing that isn't called is the function handleMessageNamed:withUserInfo:
Why isn't this working?
Thanks!
Try darwin notifications https://developer.apple.com/library/mac/documentation/corefoundation/Reference/CFNotificationCenterRef/Reference/reference.html It's a public API, shouldn't be hard to find sample code.
If you look at this document entitled "Updating extensions for iOS 7, it looks there are problems using CPDistributedMessagingCenter on iOS 7, but Ryan Petrich has published a library that may help you work around them:
Inter-process communication
CPDistributedMessagingCenter, XPC and other IPC methods built on top
of bootstrap registered mach services don't work; you get deny lookup
in the Xcode console.
Workaround: rpetrich has built a workaround called RocketBootstrap: "One common way processes communicate with each other
on iOS and OS X is through a messaging system called mach ports. Each
port is a channel that can either receive or send messages. There is a
central registration system for these ports called bootstrap, where
ports can be registered and accessed by a service name assigned to
them. Recent versions of iOS restrict which names a process can
access—MobileMail, MobileSafari and App Store apps are only allowed to
access a very specific set of services that come with iOS.
RocketBootstrap adds a secondary lookup service that doesn't restrict
which processes can access which services."

Making a delegate for a notification

Lets say i have an integer (hi) that is 0. I want a notification to say 0 in the message. my code is:
-(IBAction) alert3;
{
int hi = 0;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"UIAlertView"
message:#"%d"
delegate:hi
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
And then i get an error:
"Incompatible integer to pointer conversion sending 'int' to parameter of type 'id'"
Your implementation is incomplete. You need to add the message as a string.
Do this:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"UIAlertView"
message:[NSString stringWithFormat:#"%d", hi]
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
%d is the parameter formatter for an int, that you have to pass after the comma
About the delegate, the delegate is the class that will respond to the messages defined in the UIAlertViewDelegate (for example, when the user touches a button).
If you dont want to control that, just set it to null:
delegate:nil
Or to self to control it yourself.

Rechability connection to internet

I want to execute some code only, and only if I am connected to the internet:
//Reachability
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
Reachability * reach = [Reachability reachabilityWithHostname:#"www.dropbox.com"];
reach.reachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Block Says Reachable");
connect = #"yes";
});
};
reach.unreachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
connect = #"no";
});
};
[reach startNotifier];
//Reachability
if (connect == #"no") {
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"There is no internet connection. Please connect to the internet. If you are already connected, there might be a problem with our server. Try again in a moment." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
} else if (titleSet == NULL){
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Please select a group or create a new one" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
}else if (NavBar.topItem.title.length < 1){
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Please select a group or create a new one" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
} else if (newmessagename.text.length < 4){
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Please give a name to your event that is at least 4 characters long" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
}
It seems that the code is not executed in order. I think it is taking more time to check the Internet connection than it takes to execute the code. How can I fix this?
Please do not tell me to place the code directly in the parenthesis where connect = #"no"; is located.
The blocks aren't executed sequentially, they are executed asynchronously.
This means that you can't tell when the code inside the blocks is going to be called. The code using the block may finish and execute before the rest of your method (however this is unlikely, especially with Internet connections).
You should place your ifs in a method that is called at a valid time. This time is probably when you receive a response from your blocks, or, if my memory serves true, [reach startNotifier]; can notify you when there is a change in reachability status, this appears to be your reachabilityChanged: method:
-(void) reachabilityChanged:(id) parameter
{
//Query reachability and notify / cache as required.
}
Of course its not executed in order, the whole point of those methods is to stop the ui to freeze while you get your reachability response. Basically you set up the reachability responses and immediately ask for the result when nothing has been checked yet. What you have to really is to move it inside the brackets.
Something else that you can do is make a function with those results, and call this function in both of the blocks.
If you want to have this on the load of the viewcontroller or before you display anything else, then you either have to check for reachability before you show this controller, or add a "loading" screen.
EDIT: Something else that i dont understand is, those reachability methods seem to fire a block when they get the results, but you are registering for a notification as well. And i dont see you posting a notification for this. You are using 2 asynchronous approches here (blocks and notifications)

UITableView didSelectRowAtIndexPath error - when selecting item again

Loaded a list of items on to the UITableview and was able to click and show an alert for the row selected . But however after saying "ok" on the alert and i reclick on the already selected row my code breaks down saying "Thread 1:Program received signal:EXC_BAD_ACCESS".please take a look at the code below.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *playerselected = [exercises objectAtIndex:indexPath.row];
NSString *video = [playerselected valueForKey:#"video"];
NSString *msg = [[NSString alloc] initWithFormat:#"You have selected %#", video];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Player selected"
message:msg
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[video release];
[msg release];
}
PLease suggest me what could be the issue here.
Don't release video.
When you retrieve a value from an NSDictionary you don't own it unless you explicitly retain it.
To be more specific, when you retrieve your string it is still owned by the dictionary. When you release it, you are releasing an object that you do not own, resulting in it being over-released. As a result it is deallocated, and when you next try to access it the memory is no longer valid and your app crashes.

Resources