App Crash on slow internet connections - iphone

Whenever there is a connection problem, a slow connection on 2G , etc., my app crashes with the following log:
What I can get from the log is, that it crashes on sendSynchronousRequest method of the NSURLConnection. How do I know what exactly is the problem, and how do I solve it?
I have put Reachability methods, given by Apple, but the return YES to both Internet reachability and Host reachability. It's just that the internet connection is very slow.
On Fast connections (Wifi), it works perfectly well.
Edit:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window setFrame:[[UIScreen mainScreen] bounds]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//singleton
u=[[U5 alloc]init];
m_tUSyncPersistableConfig = [[USyncPersistableConfig alloc] init] ;
m_commonObj = [[CommonClass alloc] init] ;
u.m_tUSyncPersistableConfig=m_tUSyncPersistableConfig;
u.commonObj = m_commonObj;
//register for push notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
//load persisting data : from sqlite database
[u loadPreferences:m_tUSyncPersistableConfig];
window.rootViewController = tabBarController;
[window makeKeyAndVisible];
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"]) {
//first launch//setting some values
}else {
//not first launch
}
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedOnce"] || [u.m_tUSyncPersistableConfig.mUserName isEqualToString:#""] || !u.m_tUSyncPersistableConfig.mUserName)
{
// This is the first launch ever
//present login page
}
else
{
// app already launched
[[u commonObj] performSelectorInBackground:#selector(getAccountInfo) withObject:nil];
}
return YES;
}

I would strongly recommend moving away from synchronous NSURLConnection web requests. It's not recommended by Apple and is considered bad design. I suggest moving to asynchronous requests -- it might sidestep your problem, and you can handle errors with the NSURLConnection delegate method.

Running synchronous requests in background threads is fine in general.
But the crash report shows that the synchronous request is running on the main thread. So there is at least one location where you are not running it in the background thread. And on the main thread it will block the UI and the iOS watchdog process will notice this and kill the app on startup.
So make sure, that you are never ever using synchronous requests on the main thread!
You are saying that you are doing this, but maybe you are doing it wrong. Show the code that is actually calling the connection methods. If you symbolicate the crash report it will also show these locations in the frames 8 to 10 of the thread 0 stack trace.

Related

CocoaAsyncSockets creating Connection on app startup but Reading/Writing from a view(s)

I am using the CocoaAsyncSockets library in order to create a tcp socket connection in my app. Currently, I have successfully created a connection by opening the socket connection in my didFinishLaunchingWithOptions method in my appDelegate.m file. My code looks like so:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
socket = [[AsyncSocket alloc] initWithDelegate:self];
[self connect];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[tekMatrixViewController alloc] initWithNibName:#"tekMatrixViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
And here's my connect method:
- (void)connect
{
[socket connectToHost:#"9.5.3.6" onPort:11005 error:nil];
}
Now, what I have been struggling with is how to use read/write methods in my views without having to re-establish a connection.
I have established a tcp socket connection when the application launches
I open the socket in the didFinishLaunchWithOptions method so that I can create the connection and stay connected the entire time my app is running
I don't know how to read/write from/to the server from my views
I'm very new to socket/iOS development, so I'm hoping for the easiest possible solution
I would appreciate any help I can get on this. I'm still pretty new to iOS and still picking up on the syntax, so the more details anyone can provide, the better off I'll be.
Thanks so much for the help!
AsyncSocket comes with this method for writing:
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
And several variants of read methods, here is one: (more from the header file of the library)
- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
You should get the samples code from the same website that you have downloaded the AsyncSocket library to see how they are used. One thing to keep in mind is that these methods are asynchronous operations.

Iphone application gets stuck after unlocking screen

When i keep my application open for awhile, the iPhone/iPod locks the screen. When i unlock it my application gets stuck for like 2 seconds and then it resumes and keep functioning as usual. Why is this ? and how can i prevent it ?
To prevent this from hapenning is there any PLIST method where we could stop the process of the application when it goes to a locked screen (Might not be a better idea)
In your application delegate do you have any code that could slow down your app? Check the following methods?
-(void) applicationWillResignActive:(UIApplication *)application
-(void) applicationDidBecomeActive:(UIApplication *)application
-(void) applicationDidEnterBackground:(UIApplication*)application
-(void) applicationWillEnterForeground:(UIApplication*)application
-(void) applicationWillTerminate:(UIApplication *)application
Also use the above methods ensure you application suspends properly.
Log when your app receives a memory warning inside:
-(void) applicationDidReceiveMemoryWarning:(UIApplication *)application
Maybe when you suspend or reopen your app some there is a memory issue.
I'm not quite sure about the answer for your first question (you maybe do some heavy things inside the applicationDidBecomeActive method or the app simply reallocates memory), but i can answer the second one.
You can simply prevent the auto lock by calling:
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
A good palce for this is inside the applicationDidFinishLaunching method of the app delegate.

Where should I perform a Reachability check?

I want to check for a valid network connection. I followed Apple's Reachability example and put my check in applicationDidFinishLaunching
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
{
NSLog(#"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
}
// Override point for customization after application launch.
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil];
//Check for connectivity
internetReach = [[Reachability reachabilityForInternetConnection] retain];
[internetReach startNotifer];
[self updateInterfaceWithReachability: internetReach];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
However, my app will crash sometimes with the error Application Failed to Launch in Time
I have posted my crash as an SO question here: Application Failed to Launch in Time
I'm not sure where I should perform the reachability check?
A Reachability check could take a significant amount of time (30 seconds or more) depending on network conditions. But if your app's UI does not respond for some number of seconds (much less than 30), the OS assumes that it is dead and kills it.
If you do your Reachability check in a background thread, not the UI thread, then your UI will stay responsive, and neither the OS nor the user will assume that your app has locked up or crashed.
In -applicationDidBecomeActive you may call a method in the background that uses the reachability code with -performSelectorInBackground:withObject:.

Application Failed to Launch in Time

How can I diagnose this error?
Application Specific Information:
MyApp failed to launch in time
Elapsed total CPU time (seconds): 4913.443 (user 3868.270, system 1045.173), 56% CPU
Elapsed application CPU time (seconds): 0.010, 0% CPU
Backtrace not available
Unknown thread crashed with unknown flavor: 5, state_count: 1
Binary Images:
0x2fe00000 - 0x2fe26fff dyld armv7 <a11905c8ef7906bf4b8910fc551f9dbb> /usr/lib/dyld
Here is my didFinishLaunching method:
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
{
NSLog(#"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
}
// Override point for customization after application launch.
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil];
//Check for connectivity
internetReach = [[Reachability reachabilityForInternetConnection] retain];
[internetReach startNotifer];
[self updateInterfaceWithReachability: internetReach];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
You're probably doing a lot of setup work in your AppDelegate's application:didFinishLaunching method.
You should make sure this function exits as soon as possible. Any setup-work that takes time (network access for example) should be done asynchronously in your application. While this is going on, you can show a spinner to indicate to the user that the application is loading.
In order to add so information to Philippe Leybaert response.
If the application take to much time to start the main thread will be kill so the application will crash.
When you're using the simulator, it will not crash.
When you are using your iphone connected to xcode it will not crash.
When you send it for App Store it might be accepted if the Apple tester is using a fast iPhone
When your users on slow like iPhone 3S will crash
A way to test this issu before submitting is to deploy to testflight or with adhoc and install it on the slower device you want to support.
Just try to divide your application:didFinishLaunchingWithOptions: method code to different function calls and make those calls in background using the threads other then main and make sure that application:didFinishLaunchingWithOptions: method returns as soon as possible
you can use
dispatch_async(dispatch_get_main_queue(), ^{
//put your code
}
I have resolved the issue using this code !

iPhone application crash (iOS4 Only)

My iPhone application occasionally crashs the first time it is run after being installed. After this every time i try and run the app it remains on the splash screen or even a black screen until eventually it dies. I have to restart the device to get the application to work. After this it works fine every time. The only change between the OS3 code and 4 is the property 'UIApplicationExitsOnSuspend' to force the app to reload every time instead of suspending. Any help would be great.
Here are the two Code snippets:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
taskListViewController = [[TaskListViewController alloc] initWithNibName:#"TaskListView" bundle:nil];
taskListViewController.managedObjectContext = self.managedObjectContext;
[taskListViewController setAppDefaults];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:taskListViewController];
[taskListViewController release];
navController.navigationBar.tintColor = [UIColor blackColor];
[window addSubview:[navController view]];
[window makeKeyAndVisible];
}
- (void)viewDidLoad
{
NSLog(#"viewDidLoad - Start");
[super viewDidLoad];
NSError *error = nil;
if(![[self fetchedResultsController] performFetch:&error])
{
NSLog(#"Error with initial fetch %#, %#", error, [error userInfo]);
}
[activityIndicator startAnimating];
self.navigationItem.leftBarButtonItem.enabled = NO;
self.navigationItem.rightBarButtonItem.enabled = NO;
infoButton.enabled = NO;
syncButton.enabled = NO;
taskListTable.userInteractionEnabled = NO;
taskListTable.allowsSelection = NO;
checkingRecovery = true;
[self insertCheck];
}
Other Methods mentioned above:
[taskListViewController setAppDefaults]
[self insertCheck];
setAppDefaults - Enumerates through the settings bundle applying the defaultValues to NSUserDefaults if they have not been set already by the user in peferences.
insertCheck - Performs some queries on the db to ensure file integrity on audio recordings but in this case as this is the first time the app is loaded it will do nothing.
Update:
I have commented out the extra method calls (the two above) and i am still having the problem.
I have found a few people having the same sort of problem on the apple developer forum with no solutions. One reply was from a user having the same problem but there application did get approved on the app store.
Thanks Sj
If you are debugging the application when it crashes, you should get a stack trace, which will show you on what line the application crashes.
If you could provide the stack trace it would be much easier to find the cause of the crash.
Have you looked at the log files?
You can copy them off your iPhone if you plug it in, load organizer (Windows->Organizer in XCode) and select device logs.
If you see a log for the time your application crashed, it should include the call stack (which should include the function causing it to crash)
Alternatively it could be that you're stuck in some code run at startup - and if your application doesn't start in a timely manor (within 30 seconds IIRC) iOS kills it.
Try it without the managedObjectContext piece and see if you are still crashing. What does the log say when you crash? Do you get a memory exception?