Sunday, September 5, 2010

Tab Bar Custom Icons

If you need a custom icon for your app I recommend this site. Read carefully the license agreement. I spent quite a bit of time trying to use my own photos for custom tab bar items but the tab bar is looking for specific things in the image. You may want to take a look at these icons and then determine if you want to make your own or just use these.

Video Capture of iPhone Simulator

You will find this useful if you would like to demonstrate your iPhone applicaiton. This utility will generate a Quicktime movie of your running applicaiton. There are several different options you can use. Click here.

Here is my first sample using this application:

Saturday, August 28, 2010

The autorelease lightbulb

In my use of some CoreData objects I ran into a situation where I was getting an EXC_BAD_ACCESS crash. This error essentially means that you are accessing an object that has already been released. I tried a couple of different ways to find the error and finally pinned the code down to this:

Photo *photo = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:[myFF managedObjectContext]];

photo.name = [key objectForKey:@"name"];

photo.path = [key objectForKey:@"path"];

photo.photoOwner = person;

[[myFF managedObjectContext] save:&error];


[photo release];


The problem lies in the reference counting on the photo object. It turns out that insertNewObjectForEntityForName will return an autoreleased object per the documentation.

Return Value

A new, autoreleased, fully configured instance of the class for the entity named entityName.


Because I am releasing the photo object also it causes the aforementioned error.

Lesson learned: read the documentation!


Sunday, August 15, 2010

Useful XCode editor tip

It's always useful to have editor tips and tricks available. Here is a link to many for the XCode editor.

Sunday, August 8, 2010

Working with Core Data

You may have already noticed that transitioning from using your own Person and Photo classes to using the suggested NSManagedObject versions is not completely intuitive. In the first part of the Paparazzi assignment, I created my own Person and Photo classes to make managing the data a little easier; only to find out in part #2 that they would have you create Person and Photo objects that inherit from NSManagedObject. It sounds straight forward enough, right? Not so fast there Code Ninja. It is a little more complicated if you actually intend to use core data and have your new classes map to entities in a local database.

After struggling for a bit and enlisting the help of my peers, I was able to successfully port my Paparazzi part #1 over to a core data project and map new classes to my newly created database entities. In the next few paragraphs, I will explain the basics of how I accomplished this in an effort to ease the pain for anyone who has yet undertake this portion of the assignment.


NOTE: I do not recommend trying to adapt your existing project. Primarily because there are several hooks, default files and provided implementation by creating a core data project to start with. Otherwise, you will spend quite a bit of time trying to get your current project retrofitted. It will be far easier to create a new core data project and just copy over any existing code, xibs and AppDelegate logic you already have into to your new project.

Let's get started!
First, Create a new iPhone OS Windows-based Application. Make sure the "Use Core Data for storage is checked." Once you choose the suggested options, a project name and save your new project, you will notice a file unique to core data projects. Within your project hierarchy, under the Resources folder, you will have a "[ProjectName].xcdatamodelId" item. Expanding that item will reveal an "[ProjectName].xcdatamodel" file that will be the basis for your new Person and Photo classes.

Next, make sure you have the "[ProjectName].xcdatamodel" file selected (ensure it is not the parent file with a similar name). The should display a data model file with Entities, Properties and eventually a diagram once you establish some entities. This is where we will create our Person and Photo entities. Xcode will then create classes and map them to these database entities (very similar to any OR mapper you may have used in the past.

Create a Person entity by choosing the [+] icon beneath the Entity view. Once you have done this, you will notice a dialog to the right will appear for you to name the entity and set a few other properties. From the Property view, choose the [+] icon and create properties for "name", and photo. "name" will be an attribute of type NSString and "photos" will be a one-to-may relationship that you will eventually point to the Photo entity.

Create a Photo entity following the same steps as above. Add an NSString attribute for "name" and "path". Add a one-to-one relationship called "user" and choose a destination of Person. Now go back to your Person entity and have the one-to-many relationship "photos" destination point to the Photo entity.

We are almost done!
Now that we have our entities, attributes and relationships, it is time to generate the classes that will inherit from NSManagedObject. With one of your entities selected in the diagram, go to the Xcode menu and choose "File > New File". In the dialog, you will notice an option that is usually not there. This item is "Managed Object Class." This item us under the Mac OS X section. With this item selected, choose "Next". From the next screen, accept the defaults as appropriate and choose "Next". This last screen is the most important. Make sure that all the entities you want classes generated for are selected. By default, validation methods are not generated - which is fine for the Paparazzi assignment and you can change it later. Choose "Finish".

The newly created classes will automatically import "CoreData" and will inherit from "NSManagedObject". If you look at each class you will see they are mostly normal classes. What is really different is how you instantiate (alloc, init) them. For the most part you will always do this through a class called "NSEntityDescription" using a method called "insertNewObjectForEntityForName" or other depending on if you are creating or accessing.

That's it!
From here you should probably make sure you are up to speed on the Paparazzi assignment. There are some classes like FlikrFetcher they want you to use as a singleton to create your objects to insert in the database. Covering that would involve some more discussion and I will save that for a later date. If you found this entry helpful and need more info on instantiating these items and adding them to the database, send me an email or add a comment and I will do my best to get back to you directly or add another entry.

Thursday, July 29, 2010

Improving your UI and all the control options



Apple has provided a great app called UICatalog that is a demo of all the different controls. This is a standard XCode project you can use to not only see the various controls but also see the code that customizes many of these controls. You can find UICatalog here.

You are also allowed to use what you find in the images folder of this project for your own applications.









I took the blue and white buttons and created a simple project and used the button images they provided.

I am using whiteButton.png and blueButton.png which look like this:

whiteButton.png

blueButton.png


Here is the before (the second button has white text):
Here is the after:

You can also use this for the normal and pressed button states using the same techniques.

Here is the code (IBOutlets for button1 and button2) from the ViewController.

- (void)viewDidLoad {

UIImage *buttonImageNormal = [UIImage imageNamed:@"whiteButton.png"];

UIImage *strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];

[button1 setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];

buttonImageNormal = [UIImage imageNamed:@"blueButton.png"];

strechableButtonImageNormal = [buttonImageNormal stretchableImageWithLeftCapWidth:12 topCapHeight:0];

[button2 setBackgroundImage:strechableButtonImageNormal forState:UIControlStateNormal];

[super viewDidLoad];

}






Thursday, July 22, 2010

Using TFS with Xcode

After some searching, it seems our options for integrating Xcode with TFS are pretty limited. Currently Xcode does not provide an API or plugin model to support SCM using anything other than CVS or Subversion. Although it seems straightforward to set up a subversion server and connect to it with Xcode, it would of course be ideal for us to integrate with our established TFS environment. The top recommendations for what we are trying to do are Teamprise (standalone UI) and SvnBridge. SvnBridge seems to be our best bet, acting as a layer on top of TFS to make it appear to be a subversion server to Xcode. Although it may not be the ideal solution, it could meet our basic needs.