My iPhone app connects to a BLE Peripheral using this line of code:
[manager connectPeripheral:per.peripheral options:[NSDictionary dictionaryWithObject [NSNumber numberWithBool:YES]
forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
I enable the option to notify the user upon the peripheral disconnecting which will only happen when the app isn't being used (i.e. the iPhone is locked or the app is in the background)
When the peripheral disconnects, it calls a function in which I display an alert to the user telling them it disconnected:
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
//Show alert to the user
NSString *str = [[NSString alloc] initWithFormat:#"Peripheral disconnected. Try connecting again. Error: %#", error.localizedDescription];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Peripheral Disconnected"
message:str delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[self.navigationController popToRootViewControllerAnimated:NO];
}
The problem that I have is that when the iPhone is locked and the peripheral disconnects, both alerts pop up and it makes the user click "OK" on both alerts. How can I check to see if the "NotifyOnDisconnect" alert is being displayed to cancel showing the other alert?
You could avoid using CBConnectPeripheralOptionNotifyOnDisconnectionKey altogether and in your -centralManager:didDisconnectPeripheral: implementation, check if the app is in the background and present a UILocalNotification if it is in the background or your existing UIAlertView if the app is in the foreground. This way only one alert will be presented.
Related
I have this NSURL like so:
NSURL *url = [NSURL URLWithString:#"http://jamessuske.com/isthedomeopen/isthedomeopenGetData.php"];
and it works fine when I am connected to the internet. But if I am not (or if the user has no signal) I would want an UIAlertView to appear. I tried the following code below (with and without the if statement) but my app crashes.
if(!url){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Test Message"
message:#"This is a test"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
What Am I doing wrong?
What I mean by crashing, I mean my app opens and does not get the data from the URL. I do not see any errors, I just get brought to a page with this highlighter:
Thread 6
com.app.root.default-priority
- 0 ucol_getVersion
Next to it is a window with this hightlighted
0x17bbd32: movl 204(%ecx), %edx Thread 6: EXC_BAD_ACCESS (code=2 address=0xcc)
What you are doing only checks if the object url is a NULL pointer or not. If you want to check if a user has internet connection, I would recommend trying the Reachability classes, which can be found easily online. This one is very useful for me.
it is recommended to check the Internet availability if you are developing the app with internet connection requirement by the Apple and they are also providing the .h and .m files namely Reachability.h and Reachability.m so please download that files and import to your projects and there is a parameter named "internetConnectionStatus" and by that values use the below alert
if (internetConnectionStatus == NotReachable)
{
UIAlertView *responseAlert = [[UIAlertView alloc] initWithTitle:#"Network Error"
message:#"This application requires network connectivity."
delegate:self
cancelButtonTitle:#"Exit"
otherButtonTitles:#"Continue", nil];
[responseAlert show];
}
else
{ //do other stuff here
}
you can find the reachability files Here and you can use any Reachability files from github
ThnQ
Am new to use APNS in iPhone app. I have used and received the message in all scenarios. When the user clicks the "View" button from the APNS alert i should do the actions in the app and navigate the user to 3rd tab.
But when the app is in In Active (The app not in use) i can't trigger the actions in the app. I have used the below code in "didFinishLaunch" but not used.
NSString *params=[[launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] objectForKey:#"aps"];
NSDictionary *remoteNotif = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
NSLog(#"remoteNotif : %#", remoteNotif);
if ([params length] > 0 )
{
UIAlertView *messageReceivedAlert = [[UIAlertView alloc] initWithTitle:#"My APP" message:#"New Message Recevied From APNS in IN-Active Stage" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[messageReceivedAlert show];
[messageReceivedAlert release];
}
It always returns (null).
Can anyone please help me to do this? Thanks in advance.
Use this :
- (void) application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
And you can check for inactive by using
if([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
I am showing alertViews when Location manager unable to find current location. I did it like this
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
[manager stopUpdatingLocation];
switch([error code])
{
case kCLErrorNetwork: // general, network-related error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please check your network connection or that you are not in airplane mode" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
case kCLErrorDenied:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"User has denied to use current Location " delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
default:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Unknown network error" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
}
}
My problem is locationManager didFailWithError method get called repeatedly. So my alertviews repeatedly display.
How can I solve this issue?
Apple documentation states:
If the location service is unable to retrieve a location right away,
it reports a kCLErrorLocationUnknown error and keeps trying. In such a
situation, you can simply ignore the error and wait for a new event.
If the user denies your application’s use of the location service,
this method reports a kCLErrorDenied error. Upon receiving such an
error, you should stop the location service.
So you might skip some cases where you stop updating and show the alert, especially the default case.
A good start for error messages that can be triggered by an ongoing background process - like the location manager - is to store the reference to the UIAlertView. When the delegate receives alertView:clickedButtonAtIndex:, reset this reference to nil. Before displaying new errors, check if one is already visible.
Even better, don't display modal error messages from background processes. Just walking around, you'll occasionally lose reception, and it's tedious to have to dismiss an error when that happens. If your app has a configuration or help screen, include a space there for the most recent error message from the Location Manager (or Game Center, or iCloud, or anything else that loses connectivity occasionally.)
I have a UILocalNotification and I want to fire an alert when the app recovers from background to foreground. I can create the alert in didReceiveLocalNotification, but this method can only be called when the app is active. Now I want to check if a notification was fired while the app is in background and then fire an alert when the app recovers.
this is my current method
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
application.applicationIconBadgeNumber = 0;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSLog(#"prefs %#",[prefs stringForKey:#"kTimerNotificationUserDef"]);
if([prefs stringForKey:#"kTimerNotificationUserDef"] != nil)
{
[prefs setObject:nil forKey:#"kTimerNotificationUserDef"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Timer Alert" message:[prefs stringForKey:#"kTimerNotificationUserDef"] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
the NSUserDefaults is set when I initialize the notification, however, this alert is called even though the notification did not arrive yet. So, Im assuming maybe I can do something like:
if([prefs stringForKey:#"kTimerNotificationUserDef"] != nil && didFireNotifFromBackground)
any suggestions? thanks!
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
notification.applicationIconBadgeNumber = 0;
NSString *reminderText = [notification.userInfo objectForKey:kRemindMeNotificationDataKey];
[viewController showReminder:reminderText];
}
show the alertview where class u want to show
- (void)showReminder:(NSString *)text
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Reminder" message:text delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
}
It is in your settings. Settings ->Notification->Your application in right side-> Choose your alert style.
Then you get alert directly while firing local notification
In application, invitationDidFail is being called, some time it connects properly, but sometime it doesn't...
what can be possible reasons of denying the connection?
// Display an alert sheet indicating a failure to connect to the peer.
- (void) invitationDidFail:(SessionManager *)session fromPeer:(NSString *)participantID
{
NSString *str;
if (alertView.visible) {
// Peer cancelled invitation before it could be accepted/rejected
// Close the invitation dialog before opening an error dialog
[alertView dismissWithClickedButtonIndex:0 animated:NO];
[alertView release];
str = [NSString stringWithFormat:#"%# is busy.\nPlease again", participantID];
//[peerList removeAllObjects];
[self peerListDidChange:nil];
[self.tableData reloadData];
//[self TwoPlayer:self];
} else {
// Peer rejected invitation or exited app.
str = [NSString stringWithFormat:#"%# is busy.\nPlease try again", participantID];
//[peerList removeAllObjects];
[self peerListDidChange:nil];
[self.tableData reloadData];
//[self TwoPlayer:self];
}
}
Even it doesn't call this method, It is sure that device is not paired to any other device, then what are reasons that sometime it do accept and call didReceivedInvitation method, or some time it does deny by calling invitationDidFail.
// Invitation dialog due to peer attempting to connect.
- (void) didReceiveInvitation:(SessionManager *)session fromPeer:(NSString *)participantID;
{
[alertView dismissWithClickedButtonIndex:1 animated:NO];
NSString *str = [NSString stringWithFormat:#"Incoming Invite from %#", participantID];
if (alertView.visible) {
[alertView dismissWithClickedButtonIndex:0 animated:NO];
[alertView release];
}
alertView = [[UIAlertView alloc]
initWithTitle:str
message:#"Do you wish to accept?"
delegate:self
cancelButtonTitle:#"Decline"
otherButtonTitles:nil];
[alertView addButtonWithTitle:#"Accept"];
[alertView show];
}
When I was recently writing an application using connections, I used GKSession. I spent weeks trying to debug connection issues with it and in the end I gave up and stopped using it. There seems to be a number of issues with GKSession when connecting especially if you disconnect and then attempt to reconnect within a short time (a short time could be 1 minute or more). It seems that the connection doesn't properly get dropped and then it doesn't recreate the connection properly.
In the end I took out all the GKSession code and used this instead. Worked a treat - no more connection issues.
GCD Async Socket