Comments Off

LLVM, load_all, and force_load

Posted December 7th, 2011 in Objective-C, Xcode, iPad, iPhone by Chris Gummer

Previously, I’ve written about an issue with objective-c categories in static libraries. There is an Apple tech note which advises the following for iOS applications:

Important: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -all_load or -force_load flags.

The -all_load option will force the linker to load any object files from all libraries. In my opinion it is better to use the -force_load option. This option works similarly to the -all_load option, but it lets you specify the individual libraries to apply this behaviour to. This is useful, especially when you have many static libraries that are used to form your application binary and you know exactly which ones contain categories.

However, if you’re compiling with LLVM with this option you may run into an issue. With GCC, you specify the option under the Other Linker Flags of your project’s build settings. Therefore, the following would work:

-force_load $(BUILT_PRODUCTS_DIR)/libStaticLibrary.a

However, this option needs to be modified if you’re project is being compiled with LLVM. In order to pass options to the linker in LLVM you use the -Wl option for each library as follows:

-Wl,-force_load,$(BUILT_PRODUCTS_DIR)/libStaticLibrary.a
Comments Off

Automated Xcode 4 builds and DerivedData

Posted October 12th, 2011 in Xcode by Chris Gummer

Xcode 4 introduced the DerivedData location. Derived data contains various pieces of data related to Xcode projects, including logs, indexes and build products. The location of the DerivedData folder that Xcode utilises can be configured in a number of places. By default Xcode will use the following path:

~/Library/Developer/Xcode/DerivedData

This location may also be affected by Xcode’s settings, by your project’s settings, or even by your project’s target settings. Typically this location won’t be of concern when just using Xcode’s GUI to build, run, and archive projects. However, one use case where this can be an issue is for automated builds triggered using the xcodebuild command. Imagine you’ve scripted an automated build that builds your Xcode project and produces build products (e.g. a static library or application binary) which are then packaged and/or distributed elsewhere. It would be difficult to know exactly where the DerivedData folder that contains these build products is located.

One solution is to favour some form of convention. That is, to always use the same location for the DerivedData folder for all your Xcode projects and have this folder hard-coded in your build scripts. The better solution is to tell xcodebuild where to place your build products. xcodebuild can accept build settings, so all we need to do is specify the appropriate setting value. For example:

xcodebuild -configuration Debug CONFIGURATION_BUILD_DIR=/tmp/build

The important piece is the setting of the CONFIGURATION_BUILD_DIR build setting. This allows your script to explicitly define where any build products are placed. In the example build products, including static libraries, application binaries, and dSYM folders would be placed in /tmp/build. Personally I use the following format:

xcodebuild -configuration Debug CONFIGURATION_BUILD_DIR=$SRCROOT/BuildProducts

This will place all the build products in a folder called BuildProducts relative to the project I’m building.

Pro Core Data for iOS

Posted May 10th, 2011 in Core Data by Chris Gummer

I recently read Pro Core Data for iOS: Data Access and Persistence Engine for iPhone, iPad, and iPod Touch Apps (Books for Professionals by Professionals)
from Apress. The book is co-authored by Michael Privat and Rob Warner. Unsurprisingly the book is about Apple’s Core Data framework, specifically the iOS flavour. The book’s introduction includes the following statement:

Introductory texts give you introductory-level understanding of the Core Data framework, which is fine for introductory-level applications but not for applications that cross the chasm from toys to real-life.

This is why I was eager to read this book, due to most tutorials, articles and books providing an introductory-level understanding of Core Data. However, I was keen to explore recommended best practices, common architectures being used, and all the sticky anti-patterns that the unaware engineer may fall into.

The book is organised into nine chapters. The first six chapters primarily deal with what Core Data is and how it’s leveraged in an iOS application. The final three chapters delve into performance, migrations, and various advanced use cases of Core Data.

Whilst the book’s title is prefixed with “Pro”, the first six chapters provide all the detail a beginner requires to integrate Core Data into an app. The reader is taken through the creation of sample apps to aid understanding. These chapters provide good depth, detail and understanding. For example, Chapter One includes a section titled “History of Persistence in iOS.” Chapter Three includes details on creating custom persistent stores, including a thorough example.

Personally, Chapter Six “Refining Result Sets” was the highlight of the book. The authors guide the reader through using NSPredicate object graphs and its query language in order to filter results. This chapter is a complete guide for filtering and sorting, including sections on subqueries, aggregation, compound predicates, and multiple criterion sorting.

Chapter Seven is titled “Tuning Performance and Memory Usage.” The authors share some techniques they use to test and tune performance of real Core Data applications. This chapter includes an excellent section on memory usage and management. This is one area that is easy to forget as a beginner and one that more experienced developers should revise.

Chapter Nine was the most interesting chapter. Topics such as encryption, data change notifications, data seeding, and error handling are discussed.

So what’s the verdict? I found the book to be well written and thorough. My main issue was that the topics covered were still too basic for what I require. Ultimately, I wanted the book to be an extended version of chapters seven and nine. Unfortunately, things like third party tooling, such as the excellent mogenerator were not discussed. The error handling strategy discussed did not suggest a method of recovery, such as maintaining last known good backups or being able to automatically restore to a clean state. There was also no detailed discussion of architectures and common patterns, such as should Managed Object Contexts being explicitly passed or created or encapsulated in singletons for client code. When would each work and when wouldn’t it? Also multi-threaded applications and how to implement Core Data within them were not discussed.

In conclusion, the book is excellent for someone just starting their Core Data journey and requiring deeper understanding of Core Data’s usage. However, for the more advanced engineer, much of what is covered may already be known.

Disclaimer: I was given a free copy for review.


Comments Off

Random Crashes with Xcode 4, LLVM 2.0, and armv6

Posted May 9th, 2011 in Xcode, iPhone by Chris Gummer

After recently deploying a simple update to Boxing Timer, I started to get support requests about the app crashing. I couldn’t understand what would cause the crashes as the update was simply adding French localisation. Some quick smoke testing revealed no issues on an iPhone 4 or iPad. However, reverting back to an iPhone 3G or iPod touch G2, I was able to reproduce the crash. What was particularly strange was that the crash could only be reproduced by exercising a very specific code path. In general though, the app seemed to work fine. However, when the app did crash the logs looked something like this:

Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0×00000002
Crashed Thread: 0

Thread 0 Crashed:
0 ??? 0×00000002 0 + 2

Thread 1:
0 libSystem.B.dylib 0×000014b8 mach_msg_trap + 20
1 libSystem.B.dylib 0×00004094 mach_msg + 60
2 CoreFoundation 0×00057002 CFRunLoopRunSpecific + 982
3 CoreFoundation 0×00056c18 CFRunLoopRunInMode + 44
4 WebCore 0×000846f0 RunWebThread(void*) + 412
5 libSystem.B.dylib 0×0002b7b0 _pthread_body + 20

Thread 0 crashed with ARM Thread State:
r0: 0×00000000 r1: 0×00000000 r2: 0×380ab7fc r3: 0×00138a50
r4: 0×00138a50 r5: 0×00019dd0 r6: 0×00138a50 r7: 0×3817b1b4
r8: 0×00170f80 r9: 0×001fc098 r10: 0×00000004 r11: 0×38179ff4
ip: 0×3810a810 sp: 0×2ffff300 lr: 0×30b336c4 pc: 0×00000002

As it turned out the LLVM 2.0 compiler that shipped with Xcode 4.0 and 4.0.1 was responsible for these crashes. Fortunately Xcode 4.0.2 has fixed this issue. I was able to rebuild my app and get an expedited review, which equals happy customers again!

In a nutshell if you’ve been using Xcode 4.0 or 4.0.1 to build your apps with LLVM 2.0, they will most likely experience crashes on armv6 devices. So make sure you’ve upgraded to Xcode 4.0.2.

Comments Off

Ending Background Tasks

Posted February 28th, 2011 in Multitasking, iOS 4 by Chris Gummer

iOS 4 bought a host of new features and APIs. One of the most exciting for me was the ability to initiate long running tasks that have the ability to continue execution even after your application has moved into the background, that is once it is no longer running in the foreground.

The primary methods used to trigger this functionality are:

  • beginBackgroundTaskWithExpirationHandler:
  • endBackgroundTask:

Both methods are available on instances of UIApplication. Apple’s documentation for beginBackgroundTaskWithExpirationHandler: states:

Each call to this method must be balanced by a matching call to the endBackgroundTask: method.

These rules for background tasks are analogous to memory management rules within Objective-C, where it is crucial to balance retain and release calls. In either case the consequences are severe if you don’t get it right. For example if you do not call endBackgroundTask: for each task before its’ time expires, the system terminates the app.

If you do not call endBackgroundTask: for each task before time expires, the system terminates the application.

The exact amount of time your app is given is undefined. However, using the backgroundTimeRemaining method on UIApplication, your app can determine how much time is remaining at any point during execution.

The simplest use case may involve only one background task. However, depending upon your app’s requirements and/or complexity you may have many background tasks potentially being managed across disparate areas of your app.

If you’re working with background tasks I recommend you pay special attention to keeping the begin and end calls balanced. One useful strategy is to set a symbolic breakpoint on the UIApplicationEndBackgroundTaskError function. This function is called when your app calls the endBackgroundTask: method with a backgroundTaskIdentifier that has already been ended or does not exist. You may also place a breakpoint within the expiration handler block that you pass into
the beginBackgroundTaskWithExpirationHandler: method.

These two breakpoints should allow you to catch any unexpected scenarios where you haven’t correctly balanced the two method calls. Just be sure to execute your app with breakpoints on during development!

Time Profiler and iOS 3.2

Posted November 8th, 2010 in iPad by Chris Gummer

Time Profiler is one of the tools available under Instruments. It’s only available for iOS 4 apps. I’m currently working on an iPad only app which is being built with iOS 3.2.

What I wanted to do was use Time Profiler to analyse a performance issue with the app. It’s a powerful tool that’s extremely simple to use and has yielded great benefits for me previously. An Apple employee described the tool as “an absolutely wonderful, statistical sampling profiling tool,” and I tend to agree. However, Time Profiler only works on devices running iOS 4 and above. I also didn’t have the option of using iOS 4.2, so it didn’t look like I could use Time Profiler on my iOS 3.2 app.

What I was able to do was use Time Profiler against my app in the simulator. I just needed to link against iOS 4.1 (by changing my target’s Base SDK) and I was able to run my app in the iPad simulator and use Time Profiler to profile it.

So what are the caveats?

• This will only work on the simulator, not for a device running iOS 3.2
• The simulator and the device will have different performance profiles

In the end this work around is not ideal, but it did help highlight exactly where the performance issues were with the app.

iOS 4 and Disabling Multitasking

Posted June 29th, 2010 in Multitasking, iOS 4, iPhone by Chris Gummer

iOS 4 delivers long awaiting and much anticipated multitasking support for iOS apps. Detailed information on supporting multitasking in your app can be found via Apple’s iPhone Application Programming Guide. If you’ve installed iPhone SDK 4 and are now building apps with it, one very important point to note is:

Applications linked against iPhone OS 4 and later are automatically assumed to support multitasking and to implement the appropriate methods to handle transitions to the background state. However, work is still required to ensure that your application transitions smoothly between the foreground and background.

Therefore, if you set your Xcode project’s target to a Base SDK of 4.0, your application is expected to support multitasking. In some cases having your app moved to the background instead of being terminated may not be appropriate. It is possible to opt out of background execution by adding the UIApplicationExitsOnSuspend key to your project’s Info.plist and setting its’ value to YES. This effectively disables multitasking for your app and will force it to terminate instead of being suspended by the OS.

iPhone screenshots – cropping the status bar

Posted May 29th, 2010 in iPhone by Chris Gummer

When providing your application screenshots in iTunes Connect, one thing that Apple recommends is removing the status bar from your screenshots. Whilst I agree with and follow this recommendation, cropping the screenshots to remove the status bar is particularly tedious and frustrating. The issue is only compounded now with the separate screenshots required for iPad devices.

So I decided to write a small Automator application to automatically crop my screenshots. The application can be downloaded here. To use the application, drag the CropAction.action file to ~/Library/Automator and execute the iPhoneScreenshotCropper, selecting the image files you’d like to crop. The image files have to have one of the supported file extensions of png, jpg, jpeg, or tiff. They also need to have the correct resolution matching a full size screenshot from an iPad, iPhone, or iPod touch device. The existing image files selected will then have the status bar removed.

One caveat, I’ve only tested the application on PNGs so far.

Comments Off

svnmerge and subversion 1.5: Can’t read stdin

Posted February 3rd, 2010 in Subversion by Chris Gummer

I have svnmerge set up to keep two separate branches in sync. Whilst attempting to run a merge I received the following error :

svnmerge: command execution failed (exit code: 1)
svn merge -r 1:1 http://myrepo/svn/projectbranches/source.
Conflict discovered in 'dir/some-file.txt'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: svn: Can't read stdin: End of file found
svn: Error reading spooled REPORT request response

The source of the error is due to a conflict encountered due to the merge. However, due to a new feature in Subversion 1.5, svnmerge is unable to instruct Subversion how to proceed. The new feature is client based and called “Interactive Conflict Resolution”.

To resolve this issue and allow svnmerge to complete, I disabled the new feature. This is done by placing the following line in your Subversion config file:

interactive-conflicts = no

Of course this disables interactive conflict resolution for all further invocations of the Subversion client. So once svnmerge has completed successfully, be sure to set this option back to yes if you’d like to continue using this feature.

Comments Off

Logback and Hibernate SQL

Posted January 10th, 2010 in Java by Chris Gummer

ORM tools can be extremely powerful and save us a lot of the mundane heavy lifting required to persist data captured in an object graph through to an RDBMS. However, one problem can be that behind the scenes the tool may not always function as expected. What’s often important is to be able to see exactly what SQL the ORM tool is building and issuing to your database.
Recently we’d switched to the Logback framework for our logging and I wanted to be able to capture all the SQL that Hibernate was generating for me. There is a Hibernate configuration property which controls whether or not the generated SQL is printed to the console:

hibernate.format_sql

Setting this property to true will print out the generated SQL to the console. However, I’ve found having a separate log file that was solely responsible for capturing this generated SQL was invaluable. So how do we set it up with Logback?

<appender name="hibernate-sql" class="ch.qos.logback.core.FileAppender">
  <file>logs/hibernate-sql.log</file>

  <layout class="ch.qos.logback.classic.PatternLayout">
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
  </layout>
</appender>

<logger name="org.hibernate.SQL">
  <appender-ref ref="hibernate-sql"/>
</logger

This will put all our generated SQL statements from Hibernate into the hibernate-sql.log file.