0

Crash logs

-

So far I’ve had mixed results in weeding out the good from the bad. One skill that I think is of utmost important for a developer is debugging. You might be saying that all developers do that, but some are far better at it than others. Debugging is one of my best skills and I’ve had a ton of experience at it inheriting other people’s projects. With that in mind, I came up with one technical test that could actually tell me if a candidate could debug and that skill goes a long way in development.

Now you ask, what is the question? The other day as I was poking through crash logs, a few stood out at me. Take a look at the following logs and see if you can spot why the apps crashed:

  1. Thread 0 name:  Dispatch queue: com.apple.main-thread
  2. Thread 0:
  3. 0   libsystem_kernel.dylib            0x35cab054 semaphore_wait_trap + 8
  4. 1   libdispatch.dylib                 0x342961c0 _dispatch_semaphore_wait_slow + 184
  5. 2   libdispatch.dylib                 0x342961f4 dispatch_semaphore_wait$VARIANT$mp + 32
  6. 3   libxpc.dylib                      0x3200e89a xpc_connection_send_message_with_reply_sync + 206
  7. 4   SystemConfiguration               0x374f5be6 _reach_server_target_status + 938
  8. 5   SystemConfiguration               0x374f6d56 __SCNetworkReachabilityServer_targetStatus + 14
  9. 6   SystemConfiguration               0x374dfaee __SCNetworkReachabilityGetFlags + 198
  10. 7   SystemConfiguration               0x374e0f7a SCNetworkReachabilityGetFlags + 190
  11. 8   MSNBC                             0x000cb9ec 0x1000 + 829932
  12. 9   MSNBC                             0x0006f998 0x1000 + 453016
  13. 10  MSNBC                             0x0006abfa 0x1000 + 433146
  14. 11  MSNBC                             0x00014d54 0x1000 + 81236
  15. 12  MSNBC                             0x0006ab6e 0x1000 + 433006
  16. Last Exception Backtrace:
  17. 0   CoreFoundation                    0x3567188f __exceptionPreprocess + 163
  18. 1   libobjc.A.dylib                   0x37a18259 objc_exception_throw + 33
  19. 2   CoreFoundation                    0x356713b3 __NSFastEnumerationMutationHandler + 163
  20. 3   EmSea                             0x001f9c2b 0xe2000 + 1145899
  21. 4   EmSea                             0x00199bed 0xe2000 + 752621
  22. 5   EmSea                             0x00223453 0xe2000 + 1315923
  23. 6   EmSea                             0x002239c9 0xe2000 + 1317321
  24. 7   Foundation                        0x351b6c29 __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke_0 + 17
  25. 8   Foundation                        0x3510e6d9 -[NSURLConnectionInternalConnection invokeForDelegate:] + 29
  26. 9   Foundation                        0x3510e6a3 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 199
  27. 10  Foundation                        0x3510e5c5 -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 61
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0:
0   libsystem_kernel.dylib            0x35cab054 semaphore_wait_trap + 8
1   libdispatch.dylib                 0x342961c0 _dispatch_semaphore_wait_slow + 184
2   libdispatch.dylib                 0x342961f4 dispatch_semaphore_wait$VARIANT$mp + 32
3   libxpc.dylib                      0x3200e89a xpc_connection_send_message_with_reply_sync + 206
4   SystemConfiguration               0x374f5be6 _reach_server_target_status + 938
5   SystemConfiguration               0x374f6d56 __SCNetworkReachabilityServer_targetStatus + 14
6   SystemConfiguration               0x374dfaee __SCNetworkReachabilityGetFlags + 198
7   SystemConfiguration               0x374e0f7a SCNetworkReachabilityGetFlags + 190
8   MSNBC                             0x000cb9ec 0x1000 + 829932
9   MSNBC                             0x0006f998 0x1000 + 453016
10  MSNBC                             0x0006abfa 0x1000 + 433146
11  MSNBC                             0x00014d54 0x1000 + 81236
12  MSNBC                             0x0006ab6e 0x1000 + 433006
Last Exception Backtrace:
0   CoreFoundation                    0x3567188f __exceptionPreprocess + 163
1   libobjc.A.dylib                   0x37a18259 objc_exception_throw + 33
2   CoreFoundation                    0x356713b3 __NSFastEnumerationMutationHandler + 163
3   EmSea                             0x001f9c2b 0xe2000 + 1145899
4   EmSea                             0x00199bed 0xe2000 + 752621
5   EmSea                             0x00223453 0xe2000 + 1315923
6   EmSea                             0x002239c9 0xe2000 + 1317321
7   Foundation                        0x351b6c29 __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke_0 + 17
8   Foundation                        0x3510e6d9 -[NSURLConnectionInternalConnection invokeForDelegate:] + 29
9   Foundation                        0x3510e6a3 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 199
10  Foundation                        0x3510e5c5 -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 61

 

On the first one, the hint is that the app failed to launch in time. I’m going to use these crash logs as a test to see if a candidate can tell me what went wrong. Neither app is mine and while I can’t see the code, I can immediately spot the problems.

In the first crash log, the app calls SCNetworkReachabilityGetFlags on the main thread. This call is a blocking call which means it won’t return until it is done; this call can take a significant amount of time to return and should never be called on the main thread, especially at app startup.

In the second crash log, it isn’t as obvious. What the developer has done is something like:

  1. for (NSString *string in someMutableArray)
  2. {
  3.     if ([string isEqualToString:@"Yuck"])
  4.     {
  5.         [someMutableArray removeObject:string];
  6.     }
  7. }
for (NSString *string in someMutableArray)
{
    if ([string isEqualToString:@"Yuck"])
    {
        [someMutableArray removeObject:string];
    }
}

The array is getting modified while it is being enumerated. The fix is pretty simple.

  1. NSMutableArray *deleteArray = [NSMutableArray array];
  2. for (NSString *string in someMutableArray)
  3. {
  4.     if ([string isEqualToString:@"Yuck"])
  5.     {
  6.         [deleteArray addObject:string];
  7.     }
  8. }
  9.  
  10. [someMutableArray removeObjectsInArray:deleteArray];
NSMutableArray *deleteArray = [NSMutableArray array];
for (NSString *string in someMutableArray)
{
    if ([string isEqualToString:@"Yuck"])
    {
        [deleteArray addObject:string];
    }
}

[someMutableArray removeObjectsInArray:deleteArray];

 

Are you good at reading crash logs?

0

How can we programmatically detect which iOS version is device running on

-

Best current version, without need to deal with numeric search within NSString is to define macros(See original answer: Check iPhone iOS Version)

Like this:

  1. #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
  2. #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
  3. #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
  4. #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
  5. #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) 
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) 
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

and use them like this:

  1. if (SYSTEM_VERSION_LESS_THAN(@"5.0")) {
  2. // code here
  3. }
  4. if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
  5. // code here
  6. }
if (SYSTEM_VERSION_LESS_THAN(@"5.0")) { 
// code here 
} 
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) { 
// code here 
}
0

Using attributed strings in iOS6

-

Cocoa Touch is absolutely amazing if you need to complete a sophisticated task like getting the GPS location of the device anywhere in the world, make an HD video and send it over to your web server, or get the orientation of the user towards the north pole.

However for quite some time now it’s been relatively complicated to do some simple text formatting – like having a bold word in the middle of a sentence, for example when using a UILabel. Also something that I often wished for was to have a button, which mimics a hyperlink, like the one on the image below:

(more...)

0

Post Image on friends facebook wall

-

In this post we shall learn how to post image data on facebook friends wall.

In my last series of facebook i have explained how to post some text data on your friends wall, well posting an image on your friends wall is the similar with just one minute change.

Note: Remember one thing image is a file and if you want to post a file on your friends wall then in that case you have to make use of a class named "FBGraphFile".

(more...)

0

NSInvocation alternative for performSelector:

-

This code doesn’t involve compiler flags or direct runtime calls:

 

  1. SEL selector = @selector(zeroArgumentMethod);
  2. NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
  3. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
  4. [invocation setSelector:selector];
  5. [invocation setTarget:self];
  6. [invocation invoke];
SEL selector = @selector(zeroArgumentMethod);
NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setSelector:selector];
[invocation setTarget:self];
[invocation invoke];


Resource
NSInvocation allows multiple arguments to be set so unlike performSelector this will work on any method.

And tip:

  1. #pragma clang diagnostic push
  2. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  3.     [self.ticketTarget performSelector: self.ticketAction withObject: self];
  4. #pragma clang diagnostic pop
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self.ticketTarget performSelector: self.ticketAction withObject: self];
#pragma clang diagnostic pop

 

0

Convert Property List (plist) Between Binary and XML Formats

-

Have you ever opened a plist file outside of Xcode using a text editor and ran into something that looked like this:

 

When what you really wanted was something more like this:

 

Beginning with Mac OS X Tiger, plist files are now stored in a binary format (versus XML).

For the most part this is transparent in your day-to-day development, however, if you use scripts or other tools to read and/or update a plist, this can be a problem.

Good news is, there is a utility to convert between binary and XML plist formats. The following will convert a binary plist file (with the name ‘Info.plist) to XML format:

plutil -convert xml1 Info.plist

Make any changes you need, and then to convert back to binary:

plutil -convert binary1 Info.plist


1 2 3 4 »