How to synchronize your iPhone or iPad in more than one computer

For a long time I struggled around the possibility of synchronizing any given iDevice, be it an iPhone, iPad or iPod Touch, in more than one computer. There were uncountable times that I received a client’s device to troubleshoot (for example, to see why he wasn’t being able to successfully install an AdHoc build), and  when I tried to synchronize it with my iTunes, there would be a message saying that all applications would be deleted. Heck, that’s not why I wanted to do.

Maybe I was looking at the wrong place or doing the wrong searches on Google, but it took me some time to figure out the correct approach to handle this problem. There are two possible situations you may face, which are:

1) Synchronize your own device in more than one computer

This is the simplest of the cases: you have an iPhone, iPad or iPod Touch, and want to sync it at your home’s computer and at your company’s computer. Please bear in mind that you are allowed to do such thing up to 5 computers. Connect your device via an usb cable and fire up iTunes, then go to the Store menu and choose Authorize This Computer. Enter your credentials, and after that go to the File menu and choose Transfer purchases from ….. Wait until it finishes, and you are good to go.

2) Synchronize more than one device in the same computer

This is a bit more elaborated, and handles the situation where you have multiple devices that you need to sync in the same computer – note that it’s a different need than the previous, where it states out to sync the device in different computers. The question here is how not to mess with your own library when someone else’s device is sync’d at your iTunes.

To correctly perform this task, you will need to think about multiple iTunes libraries (or multiple accounts), and then perform the steps previously described at (1). Do the following:

Quit iTunes, and before opening it again, hold down the Option key (Mac) or Shit key (Windows), and without releasing it, fire up iTunes. A dialog window saying that you should “Choose iTunes Library” will open, as shown in the image below:

Select “Create Library” and place it wherever you want. That would be the location where the files will be stored, so if you want to use it other than for temporary purposes, please make sure you choose a good directory.

One you do that, do the steps at (1). To switch between libraries, to the same Option or Shift trick again, but then select “Choose Library” instead.

Converting multiple PDF files into JPG using ImageMagick

ImageMagick is an extremely powerful program, which can do amazing things even with very simple arguments. One of the things I have been using ImageMagick recently was to convert PDF files into image files (JPG, PNG, GIF, you name it), that is a task that many think that only can be achieved using some comercial (and expensive) tool. The basic usage is effortless:

convert input.pdf output.jpg

ImageMagick’s convert command will take the PDF as input and create a JPG file as output. Note that the type of the output file is determined by its extension, so if you wanted to create a PNG file, just use output.png. More advanced results include specifying the pixel density, quality, resize, scale, colorspace, alpha channel etc.. the list goes on beyond you could imagine. For a complete and detailed set of commands, check http://www.imagemagick.org/script/command-line-options.php.

A more detailed example:

convert -alpha off -density 150 -quality 80 -resize 768 -unsharp 1.5 input.pdf output.jpg

The previous command will convert a PDF to JPG of quality 80, with 150 DPI and as last step, apply a 1.5 radius unsharp filter. Doing that with any programming language would require literally dozens of line of code.

One interesting option to note about is -alpha off, which prevents the JPG to be created with a black background. However, please note that may not be the case all the times, and you probably will have to adjust the arguments to fit your needs.

Batch processing

As a final example, the convert command requires either an input and an output names, but sometimes you want to the filename to be the same, just with a different extension (like Presentation_123.pdf => Presentation_123.jpg). This is very common when we have a set of pages in a given directory and want to convert them all. One easy way to accomplish that is by using the command mogrify instead of convert. mogrify works much like convert, but allows us to do some batch processing. For example:

mogrify -format jpg -alpha off -density 150 -quality 80 -resize 768 -unsharp 1.5 *.pdf

There are two different arguments: the first is the format we want to convert to, and the other is the format we are converting from. The form is mogrify -format <output type desired> [other arguments] *.<input type>, so if you want to convert all JPG files to PNG without changing the filename (only the extension), you’d execute

mogrify -format png *.jpg

Easy as eating chocolate.

Crappy iOS APIs – UINavigationController

While Apple has some great products and has achieved excellence designing beautiful UIs, the same can’t be said for many of its APIs. Anyone who has tried to do even the simplest of the things just by looking at the documentation or based on assumptions of how one could expect that a given thing would work based on context and method names, would know what I am talking about: literally hours trying to correctly setup a more complex UILabel, or pulling the hair out of the head after not being able to easily change the color of an UINavigationController or UIToolBar. The list goes on ad-infinitum.

Take UINavigationController for instance: it has methods to set the title, the left and right buttons, and for the back button when a new controller is pushed into the stack. So imagine you are in controller A,which pushes controller into the stack by calling [self.navigationController pushViewController:b animated:YES]. The view slides left with a nice looking animation, and b’s view pops in the screen. By default, iOS will automatically set up a working back button for you – which is great – and that button’s label is set to the previous screen’s title – that, again, makes a lot of sense.

However, if for any reason you’d like to change the label of the back button to another text. you can’t just do

self.navigationItem.backBarButtonItem.title = @"Back";

on b. Well, you can, but it won’t work. It does not crash the app, but also does nothing. Now imagine for a moment that doing the previous code is the most natural thing anyone could possible do, but it does not work. “Ok then, maybe if I override the entire button”:

self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Back"
	style:UIBarButtonItemStyleBordered target:nil action:nil] autorelease];

only that it also does not work: you’d still get the default button, despite assigning a new one. Lots of tries here and there, and you finally figure out (by looking a Google or deciphering the poorly written documentation) that the only way to get it working is to set the title BEFORE you push b into the stack, in the PREVIOUS controller. In other words, you must the the title you’d like to see in b in the a controller. Genius, right?! Apple just killed SoC. It will look like this:

// Somewhere in AController
BController *b = [[BController alloc] init];
self.title = @"Back"; // Scream in pain
self.navigationItem.back
[self.navigationController pushViewController:b animated:YES];
[b release];

There simply can’t be any good reason on earth to do that. It get’s worse then you need to have a custom method called before the view pops out of the stack, as it is not possible to override backButton‘s selector.

So that one should do, instead? Well, what I do is the following: I force backButton to be hidden when the new controller slides up on the screen, and then set up a “left” button:

// BController
-(void) viewDidLoad {
	self.navigationItem.hidesBackButton = YES; // Important
	self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Back"
		style:UIBarButtonItemStyleBordered target:self action:@selector(myCustomBack)] autorelease];
}

-(void) myCustomBack {
	// Some anything you need to do before leaving
	[self.navigationController popViewControllerAnimated:YES];
}

it just works. It’s a lot of work, of course, but works. Now, if you’d like to have a different layout for such button, that’s a whole new story.

Setting up the JAR file search location for the java command line tool

Before I forget it again: usually, Command-Line Java applications set up their classpath using the -classpath argument, which requires you to specify each single jar, among the root package directory where .class files are in. I find this method boring and slow to set up, specially when you have dozens of files.

A much better approach is to use the option -Djava.ext.dirs=<directory> instead, as in

java -Djava.ext.dirs=/path/to/all/jars com.my.Application

Just point to the root directory where all your jars are located. Way more useful and using the -classpath argument.

Handling the “open() 11 resource temporarily unavailable” error with Nginx

While developing a website, I started receiving the error “open() 11 resource temporarily unavailable” after we migrated from Apache to Nginx. The symptom was that, after any change to a CSS or JS file (in fact, to any file directly served by Nginx) the first request would crash, but any subsequent request did work. However, after performing any kind of change in one of those files, the problem happened again.

One important thing to notice is that I was developing through Samba – more specifically, I had the Nginx server running on a local Linux box, and the files were being manipulated in a text editor in Windows.

What I found out is that, if I edited the files directly in the Linux box, the problem didn’t happen. Going a little bit further, it was clear that changing to another text editor in Windows would not trigger the problem. After some Googleing, a post in the Nginx users list mentioned that this issue may arrive due to the fact that some text editors perform some kind of temporary lock at Samba in the files being edited (although I couldn’t find anything visually, at least), which caused Nginx to not being able to open the file even for reading.

So, if you have an environment like mine and are running into this issue, try swapping to another editor. You may have luck.

A useful UIView addition via Categories (Objective-C, iOS)

One thing that makes me surprise even in 2011 is how many Objective-C developers completely ignore (or misuse) the power that Categories in Objective-C give to you. In other words, Categories allows you to do almost any sort of customization to any given class, especially those from the official SDK, which can be of huge help to save a lot of typing and making your code more readable.

One good example is view location and size handling, a task that every Objective-C developer does a lot. And I mean it. Objective-C can be extremely verbose to do some very simple and laboral tasks, like creating and positioning views on the screen, as well manipulating them. Take the following as example:

UIView *v = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 20, 10)];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];

// Change only the X
CGRect frame = v.frame;
frame.origin.x = 90;
v.frame = frame;

// [....]

// Later, if we want to change the width, do it all again
CGRect anotherFrame = v.frame;
anotherFrame.size.width = 200;
v.frame = anotherFrame;

// And so on

While this is a practical, very common and working code, it can get repetitive and boring very fast, as the need to change any property of the view’s frame arrises, because we can’t simply do

v.frame.origin.x = 90;

as the compiler would complain. Instead, we first need to assign the frame property to a temporary variable, change it, and then assign it back to the target instance. Do this a series of times and you’ll be willing to pull your hair off. (I do). So how do we make it better? By using Categories, of course. What we want to accomplish is the following:

v.x = 90;

// .....
v.width = 200;

// And so on

As you can see, the different is that, instead of writing three lines of code for every single property we might want to change, we write just one. Below you find the Category code for this UIView addition:

@interface UIView (FrameAdditions)
@property float x;
@property float y;
@property float width;
@property float height;
@end

@implementation UIView (FrameAdditions)
-(float) x {
	return self.frame.origin.x;
}

-(void) setX:(float) newX {
	CGRect frame = self.frame;
	frame.origin.x = newX;
	self.frame = frame;
}

-(float) y {
	return self.frame.origin.y;
}

-(void) setY:(float) newY {
	CGRect frame = self.frame;
	frame.origin.y = newY;
	self.frame = frame;
}

-(float) width {
	return self.frame.size.width;
}

-(void) setWidth:(float) newWidth {
	CGRect frame = self.frame;
	frame.size.width = newWidth;
	self.frame = frame;
}

-(float) height {
	return self.frame.size.height;
}

-(void) setHeight:(float) newHeight {
	CGRect frame = self.frame;
	frame.size.height = newHeight;
	self.frame = frame;
}
@end

Save this code in any file, like UIView+FrameAdditions.(m|h), include it in your project, and you are good to go!