what GKSession doesn't connect on every attempt? - iphone

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

Related

Check if Notify Alert is Displayed - Bluetooth Notify On Disconnect

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.

xcode webview error not working

This web view failed error showing the alert popup even when it is loading the website. I believe I need to delay this method in order for it to work.What will be the best method for doing this?
- (void)webView:(UIWebView *)webViewfail didFailLoadWithError:(NSError *)error
{
if([webViewfail isEqual:webview]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Failed" message:#"Check your Internet connection before refreshing."
delegate:webview
cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
Here is how I am loading the website
- (void)viewDidLoad
{
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.blabla.com"]]];
}
The problem is most likely an error -999 which generally happens when something from the webpage does not load correctly or a user tries to navigate back while the page is still loading. After some research here's what I found and used to keep the NetworkAlert from poping up every time but still popping up when there is no network.
-(void)webView:(UIWebView *)webBlog didFailLoadWithError:(NSError *)error{
if ([error code] != -999) {
NSLog(#"Could not load the dumb webPage");
//show error alert, etc.
[self showNoNetworkAlert];
}else{
NSLog(#"Could not load the dumb web page...just might blame user!");
}
}
- (void) showNoNetworkAlert{
UIAlertView *baseAlert = [[UIAlertView alloc]
initWithTitle:#"No Network" message:#"A network connection is required. Please verify your network settings and try again."
delegate:nil cancelButtonTitle:nil
otherButtonTitles:#"Dismiss", nil];
[baseAlert show];
}
Hope this helps someone...

XMPPFramework not sending presence

Im developing an app for iPhone, in wich one of the functionalities is an instant message system, using XMPPFramework. By now, im testing it with Google Talk. The delegate is the same class that manages the User Interface. So, I got this code:
In viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupStream];
}
The setupStream method:
- (void) setupStream
{
NSLog(#"Inside setupStream");
xmppStream = [[XMPPStream alloc] init];
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[self connect];
}
The connect method:
- (BOOL) connect
{
NSLog(#"Inside connect method");
General *general = [General sharedManager];//this is a singleton to manage settings for every user
NSString *chatid;
NSString *chatpass;
//chatid=[general user];
chatid=#"somegmailaccount#gmail.com";
xmppStream.myJID=[XMPPJID jidWithString:chatid];
if (![xmppStream isDisconnected]) {
return YES;
}
NSError *error = nil;
if (![xmppStream connect:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
return NO;
}
return YES;
}
In xmppStreamDidConnect method:
- (void) xmppStreamDidConnect:(XMPPStream *)sender
{
[xmppStream authenticateWithPassword:#"password" error:NULL];
[self goOnline];
}
And goOnline method:
- (void) goOnline
{
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
NSLog(#"Presence sent");
}
With this, the presence is not sent. I have another google account that I try for testing (say, testing#gmail.com) and in this account the presence of somegmailaccount.gmail.com is not seen. Both accounts are connected and know each other, since I used this same accounts to develop the Android app.
Any idea about what i´m doing wrong? Any help is appreciated.
Thank you very much.
I found it! The presence is not sent this way:
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
Insted, i have done it this way:
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[xmppStream sendElement:presence];
This way, the presence is sent without any problem :)
With this code, i implement method xmppStreamDidAuthenticate:(XMPPStream *)sender
and the program DO enter that method without any call from my code. But if i put
[xmppStream setHostName:#"talk.google.com"];
[xmppStream setHostPort:5222];
... in method connect, the program DO NOT enter that method, nor xmppStreamDidConnect.
Im getting mad.

Bluetooth warnings Xcode?

I'm trying to learn about using bluetooth connectivity through making a simple peer to peer bluetooth chat app. I'm hitting a bit of a problem as I'm new to exploring GameKit and Bluetooth and am hoping someone can help me. I think it's a formatting issue, but I could be very wrong. Basically when sending messages between both devices I'd like to use the name of the device that the message is coming from in the UIAlertView popup that displays the message. For example, 'Johnny's Iphone says:...'
Here's the bit of my code dealing with the AlertVIew:
- (void) receiveData:(NSData *)data
fromPeer:(NSString *)peer
inSession:(GKSession *)session
context:(void *)context {
//---convert the NSData to NSString---
NSString* str;
str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:(#"Chat Message: %#", peer)
message:str
delegate:self
cancelButtonTitle:#"REPLY"
otherButtonTitles:nil];
[alert show];
[alert release];
}
In the above I'm trying to use 'peer' to set the name but it's not working. I've tried initialising peer as a string and then passing it but this isn't working either. In both cases I get a string of 9 or 10 numbers with whatever message was sent displayed below. Where am I going wrong and what should I be doing?
Use [session displayNameForPeer:peer] which will return you the "display name"

UIAlertView Pops Up Three Times per Call Instead of Just Once

I am getting odd behavior from an NSAlert in two different parts of my program. The behavior is:
Alert appears and then spontaneously disappears.
Alert reappears and then remains until dismissed by user i.e. normal behavior.
Alert reappears again.
This behavior only occurs the first time the method that displays the alert is called. After that first time, it behaves normally.
Here is the code for the one of the parts in which the behavior occurs:
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locationAlert release];
Or if you prefer, with a bit more context:
- (IBAction)locateMe {
NSLog(#"About to check location");
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locMan.distanceFilter = 1609; //1 mile
[locMan startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation * )oldLocation {
if (newLocation.horizontalAccuracy >= 0) {
CLLocation *airportLocation = [[[CLLocation alloc] initWithLatitude:51.500148 longitude:-0.204669] autorelease];
CLLocationDistance delta = [airportLocation getDistanceFrom: newLocation];
long miles = (delta * 0.000621371) + 0.5; //metres to rounded mile
if (miles < 3) {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locationAlert release];
[locMan stopUpdatingLocation];
} else {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are not in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locationAlert release];
[locMan stopUpdatingLocation];
}
}
}
- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"Error." message:error.code delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
[locMan release];
locMan = nil;
}
Any ideas? Thanks.
Edit---------
The other place this happens is:
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unable to download feed from web site (Error code %i )", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
For context the first case is in the AppDelegate and the second in the view controller for the 1st tab view. The second problem occurs every time the xml is reloaded when there is no internet connection. The first one only occurs the first time the function is called.
Edit-----
If I move the alert it works. Unfortunatly this is not where I want it!
- (IBAction)locateMe {
UIAlertView * locationAlert = [[UIAlertView alloc] initWithTitle:#"You are in the right place." message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[locationAlert show];
/*
NSLog(#"About to check location");
locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
locMan.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locMan.distanceFilter = 1609; //1 mile
[locMan startUpdatingLocation];*/
}
Update:
I set some NSLog entries and discovered that despite the addition of [locMan stopUpdatingLocation] the didUpdateToLocation function was running multiple times.
I guess the spontaneous disappearance happens because the alert view is called again and the programme clears the first instance to make way for the second automatically.
Any ideas as to why [locMan stopUpdatingLocation] doesn't work would be appreciated but in the mean time I just moved the declaration of the locationAlert out of the function (so it is global), set it in the initial locate me function and use the following the first time it is called:
[locationAlert show];
locationAlert = nil;
That way it works perfectly.
You're not turning off your location manager when you first show the alert. As the location is refined by the device (ie, the accuracy is increased), your callback will be (potentially) called multiple times. You should use [locMan stopUpdatingLocation] after your alert display.
I set some NSLog entries and discovered that despite the addition of [locMan stopUpdatingLocation] the didUpdateToLocation function was running multiple times.
I guess the spontaneous disappearance happens because the alert view is called again and the programme clears the first instance to make way for the second automatically.
Any ideas as to why [locMan stopUpdatingLocation] doesn't work would be appreciated but in the mean time I just moved the declaration of the locationAlert out of the function (so it is global), set it in the initial locate me function and use the following the first time it is called:
[locationAlert show];
locationAlert = nil;
That way it works perfectly.
I think the NSAlert disappearing on its own is the key to solving this.
It's simple to explain why an alert displays unexpectedly i.e. it's just been called unexpectedly. However, it's not so common to programmatically dismiss an alert. Whatever is causing it to disappear is most likely triggering the display again.
To debug I suggest:
(1) Looking in your code for the NSAlert – dismissWithClickedButtonIndex:animated: method and see if somehow you're actually dismissing the alert programmatically.
(2) I believe (someone double-check me on this) that an alert view is added as a subview to whichever base view is currently on screen. It might be that the base view is disappearing for some reason and taking the alert view with it. If the view disappears and then reappears rapidly enough, it might not be obvious when the alert is frontmost. (Edit: see Ed Marty's comment below.)
(3) Since this happens in two separate pieces of the app, compare both to find a common element or structure. That common element might be the cause.
An odd problem.
Edit01: Updated for additional info
If locMan isan instance variable, it should be defined as a property and you should access it every time withself.locMan By accessing it directly, you lose your automatic retention management.
I encountered the same exact issue with the alert dialog appearing momentarily, reappearing, and finally appearing again after being dismissed. I was making a string comparison before deciding to show the alert view:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([string isEqualToString:#"OK"]) {
NSLog(#"(Settings)Registration Successful");
statusField.text = #"Registration successful!";
[settingsActivity stopAnimating];
}
else {
NSLog(#"(Settings)Registration Failure");
[settingsActivity stopAnimating];
UIAlertView * regFail = [[[UIAlertView alloc] initWithTitle:#"Registration Error!" message:#"Please check your email address and try again." delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
[regFail show];
}}
To correct this behavior I simply verified the returned string rather than just showing the alert:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([string isEqualToString:#"OK"]) {
NSLog(#"(Settings)Registration Successful");
statusField.text = #"Registration successful!";
[settingsActivity stopAnimating];
}
else if([string isEqualToString:#"Error"]) {
NSLog(#"(Settings)Registration Failure");
[settingsActivity stopAnimating];
UIAlertView * regFail = [[[UIAlertView alloc] initWithTitle:#"Registration Error!" message:#"Please check your email address and try again." delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
[regFail show];
}
I also got the Same problem while working on Location Manager. Here i checked with Nslog but it is executing multiple times, finally i fount that i am creating multiple objects and using Sharedinstance for same ViewController that contains Location Manger but i am not releasing the object, so at perticular location how many objects if we create that many times the location detects.So while working on LocationManger check handling objects thoroughly to reduce these type of problems.