Loading UIImages from files stored inside a bundle

We’ve learnt before how to make an iOS Assets Bundle. In this mini post… we’ll learn how to learn images, stored in bundles. Okay.. this one is super simple:

[cc lang=”objc”]
UIImage* twitterBtnImage = [UIImage imageNamed:@”SomeResources.bundle/twitter-button.png”];
[/cc]

Of course, you need to have the ‘SomeResources’ bundle in your project. That’s it!

Loading NIBs stored inside a bundle

When does it make sense to store your NIBs inside a bundle?. As we’ve discussed before… this becomes handy when you’re distributing a framework which has some custom NIB files.

But wait…. how do you tell a UIViewController to load its nib file from a bundle?. Short answer… we’ll rely on UIViewController’s ‘initWithNibName: bundle:’ constructor.

Before doing that… we need to take care about a small detail, which is, how to load a NSBundle object (to pass on as the ‘bundle’ parameter).

We’ll show you the required code below, encapsulated into a nice helper class:

[cc lang=”objc”]
@interface LABundles
+ (NSBundle*)someResourcesBundle;
@end

@implementation LABundles
NSString* const kSomeResourcesBundleName = @”SomeResources.bundle”;

+ (NSBundle*) someResourcesBundle
{
static NSBundle* someResourcesBundle = nil;
if ( someResourcesBundle == nil )
{
@synchronized(self)
{
if ( someResourcesBundle == nil )
{
NSString* bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:kSomeResourcesBundleName];
someResourcesBundle = [[NSBundle bundleWithPath:bundlePath] retain];
}
}
}

return someResourcesBundle;
}
@end
[/cc]

Finally, in order to alloc an UIViewController, and load its nib from the SomeResources bundle, we need to do the following:

[cc lang=”objc”]
SomeViewController* someVC = [[SomeViewController alloc] initWithNibName:NSStringFromClass([SomeViewController class])
bundle:[LABundles someResourcesBundle]];
[/cc]

That’s it!. SomeViewController should be loading its nib file from the someResources bundle.

Making an iOS Assets Bundle

An iOS Bundle is just a folder which contains resources. Roughly speaking,  it allows you to store any resource you might need: images, nibs, or localized string files.

Why would you create an application bundle?. What’s that good for?.

Suppose you have a framework of your own. And… suppose that your framework has several UIViewController which require custom images. OR, suppose that you need to load different images dynamically, within your framework’s code.

You can’t include those resources inside an iOS framework. So… that’s where the bundles come in!.

Check out the Facebook SDK. Yup. It contains a bundle with few image resources.

[Step #1] : Adding a Bundle Target 

Let’s add a new target to our project, which will be the one responsible of generating the bundle.

First of all, we need to click over the project name in the navigator (1), and afterwards, over the ‘add target’ button at the bottom (2):

UpdatingTarget

You can find the ‘Bundle’ target in the following path: ‘Mac OSX >> Framework & Library >> Bundle’:

AddingBundle

Did you notice that we had to use the ‘Bundle’ target-template located inside MacOSX section?. Aaaand… did you notice that there is no Bundle target-template inside the iOS section?.

OSX and iOS bundles have a slightly different structure. We can use any of them both. But since we’re working on iOS, let’s switch to its own Bundle structure.

We need to change the ‘base sdk’ Build Setting for our new SomeResources target, as follows:

UpdatingTarget

Let’s update the BaseSDK. Instead of Latest Mac OSX, please, click over that combo and select ‘Latest iOS’.

Allright!. It’s time to edit the Build Phases section of our Bundle. We’ve named our new target as ‘SomeResources’. We just need to add all of our resources into the ‘Copy Bundle Resources’ section, as shown below:

AddingAssets

Note that, for this particular example, we’re exporting three PNG images, a NIB file, and an InfoPlist.strings file. We’ll see, later on, how to load these files.

In order to generate the bundle, we just need to select the ‘SomeResources’ schema:

SelectingSchema

Once we have the ‘SomeResources’ schema selected, we must hit “build” in order to generate the bundle file.

Your build-output folder should look as follows, assuming you’re in debug mode. ‘SomeResources.bundle’ is ready to be distributed:

BuiltBundle


[Step #2] : Including SomeResources.bundle into a Sample project 

How do we manage to import this new bundle into a new project?. Simply drag & drop the ‘SomeResources.bundle’ file into your target app’s Resources folder, as shown below. That’s all you need to do.

ImportingBundle

Up next… we’ll learn how to:

I hope you found this mini guide useful… somehow!.
Have fun!.

Showing current folder in Terminal’s Title

This is a nice trick i’ve learnt not long ago. Nice, and useful. If you run OSX, and you’d like Terminal to display the current folder, in its title… to looks something like this:

TerminalTitle

All you need to do is to edit the .profile in your home directory, and type the following line:

[cc lang=”bash”]export PROMPT_COMMAND=’echo -ne “\033]0;[${PWD/$HOME/~}]\007″‘[/cc]

Nice, right?

Manually Symbolicating iOS Crashlogs

I’ve been facing this problem for as long as i’ve been developing iOS apps. What’s the deal with crashlogs????…..

Apple allows you to download crashlogs through iTunesConnect. What are crashlogs you may say. Well, crashlogs are simply text files that allows us to debug crashes. You get to see the Stack Dump at the moment of the crash, as well as the architecture, and loaded libraries.

What is symbolication??… well, the crashes you download in iTunesConnect aren’t useful, unless you’ve got the dSYM file matching that crashlog. If you do, you’ll be able to symbolicate it. That means that… instead of seeing memory addresses in the stack dump, you’ll get to see method and class names.

You can symbolicate crashlogs using Xcode Organizer. Why would you wanna do it manually?. Because sometimes the crashlogs don’t get symbolicated, and.. if you do it manually, you get access to the verbose mode… and you miiight stand a chance of fixing the glitch that prevents symbolication.

So, let’s begin…. we assume the following:

– You’ve got a horrible .crashlog file.
– You’ve got the dSYM file that matches the binary that crashed.
– You’ve got Xcode 4.3 or superior.

Steps… steps!!

  1. Check and Fix Xcode Path. Fire up a terminal, and type:[cc lang=”bash”]/usr/bin/xcode-select -print-path[/cc]

    If it says anything but ‘/Applications/Xcode.app/Contents/Developer/’, then it’s wrong. In order to fix it, you should type:

    [cc lang=”bash”]sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer/[/cc]

  2. Locate the ‘symbolicatecrash’ script. You can do so by typing:[cc lang=”bash”]find /Applications/Xcode.app -name symbolicatecrash -type f[/cc]
  3. In your home directory (cd ~), you should edit the .profile file, and type the following:[cc lang=”bash”]
    SYMBOLICATECRASH=”Type the path returned by find”export SYMBOLICATECRASH

    export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

    PATH=”:${SYMBOLICATECRASH}:${PATH}”
    export PATH[/cc]

That’s it. Now, you should simply go to the folder where the .crash file is located, and you should type…

[cc lang=”bash”]symbolicatecrash NAME.crash[/cc]

If everything goes fine, the stack dump should he human-readable!

%d