Posts tagged ‘Xcode’

All schemes missing from Xcode when loading old project

There is no worse feeling in the world than when you load up an old Objective-C project that you have to make some changes on, and all of a sudden there are no schemes present for the project when you pull it up in Xcode. As such, there is no way to run the project to see if your changes are good or not.

I did find a solution to this issue. Apparently you need to have Xcode rebuild some of your user data to get the schemes back again.

If this is happening to you when you load your project or workspace into Xcode, do the following steps:

  1. With the project/workspace open in Xcode, right click on the project item all the way at the top of the Project navigator, and select “Show in Finder”.
  2. Quit Xcode.
  3. From the Finder window that just opened, right click on the .xcodeproj file for your project and select “Show Package Contents”.
  4. Double click on the xcuserdata folder.
  5. Right click on the folder that begins with your user name and ends with .xcuserdatad and select “Move to Trash”.
  6. If you are using a workspace instead of just a project (such as if you are using Cocoapods), go back 2 steps to the original folder that Xcode loaded and repeat the above 3 steps except starting by right clicking on the .xcworkspace file instead of the .xcodeproj file.
  7. Load your project/workspace again in Xcode, and the schemes should be rebuilt.

By the way, while we are at it, you do have the xcuserdata folder as an entry in your Git ignore file, right?

Hope you are all having a safe and happy holiday season. See you in 2024.

Xcode 4 exception breakpoint

Did you ever have Objective-C code that would fail with an exception (such as asking for an objectAtIndex beyond the bounds of the array), but by the time you got word of it, all the stack trace had in it was the obj_msgsend and main? Yeah, I hate that.

Well I discovered that you can add a breakpoint to your project that will immediately break when the exception happens. To do this with Xcode 4, click on the Breakpoints symbol (2nd from the right) in the Navigator pane, click the + button at the bottom of the pane, and select Add Exception Breakpoint. From the bubble that appears, I selected Objective-C from the Exception choice (although I suspect you can safely leave it at all if you desire), and I left the Break selection at On Throw. Once you click Done, you should then have a new exceptions breakpoint in the list.

This was instrumental in helping me track down an issue on an app rescue that I am currently working on.

By the way, here is an awesome line of code that I found in the aforementioned app rescue. My brain hurts from looking at the code for long stretches of time, but there are some nice nuggets like this sprinkled in the code:

Assets *ass = [[Assets alloc]init];

UIButton can sing and dance, too!

Apparently, there is no way to take a UIButton and set it’s property to “selected” for the purposes of having the UI display the button with the background image as it appears in the UIControlStateSelected state. As a result, I decided that I would just track which of my series of UIButton controls was supposed to be selected, set the background image of all the buttons to nil, and set the UIControlStateNormal background image of the button to an image, and it seemed to work OK.

The code to do this, however, was kind of ugly, and my co-worker on this project pushed me to find a better way. The result is the ExpandoButton class that we created and added to the project. For this class (which of course inherits UIButton), I wanted to be able to initialize it to a particular background image, and I wanted to have a message I could send the button to have it switch back and forth from the unselected background image to the selected background image.

Here are the header and implementation files for the ExpandoButton object class:

//
//  ExpandoButton.h
//
 
#import <Foundation/Foundation.h>
 
@interface ExpandoButton : UIButton {
 
}
 
- (void)setSelectedImage:(BOOL)isSelected;
 
@end
//
//  ExpandoButton.m
//
 
#import "ExpandoButton.h"
 
@implementation ExpandoButton
 
- (id)initWithCoder:(NSCoder *)decoder
{
	if (self = [super initWithCoder:decoder]) {
		UIImage *image = [UIImage imageNamed:@"button_normal.png"];
		UIImage *stretchImage =
					[image stretchableImageWithLeftCapWidth:4.0 topCapHeight:4.0];
		[self setBackgroundImage:stretchImage forState:UIControlStateNormal];
		self.backgroundColor = [UIColor clearColor];
	}
 
	return self;
}
 
- (void)setSelectedImage:(BOOL)isSelected
{
	NSString *file;
 
	if (isSelected)
	{
		file = @"button_selected.png";
	}
	else 
	{
		file = @"button_normal.png";
	}
 
	UIImage *image = [UIImage imageNamed:file];
	UIImage *stretchImage =
				[image stretchableImageWithLeftCapWidth:4.0 topCapHeight:4.0];
	[self setBackgroundImage:stretchImage forState:UIControlStateNormal];
}
 
@end

A few notes here about the implementation file. You will of course need to add the stretchable unselected and selected button images to your project and change the names above, along with changing the cap width and height to your needs. Also, the initWithCoder part took us a few moments to figure out, it wasn’t working at first because we weren’t calling the super’s initWithCoder, just the regular old init. And finally, keep in mind that there is no error checking, optimization, or memory leak checking going on here.

To actually use the ExpandoButton, go into your Interface Builder, and from the Library window, select the Classes option, make sure the choice list right below is set to Library, and you should then be able to scroll the list and see an ExpandoButton, which looks just like a UIButton. Put that object on your view and set the size and title if you wish. VERY IMPORTANT: Make sure to set the button type of your ExpandoButton to Custom instead of the default of Rounded Rect.

Then, in your view controller header file, set up an IBOutlet with type of ExpandoButton (don’t forget the header or @class), along with the corresponding @property, and in the view controller implementation file, set up the @synthesize. After you save the files and build, go back into Interface Builder and set up the connection between the IBOutlet and the ExpandoButton on the view. (I hope you remembered where it was. When you set it to Custom and if you do not have any title text, the button sort of disappears.)

If everything is hooked up and working correctly, in your implementation file code, you can do something like this:

[myExpandoButton setSelectedImage:YES];

And the button should show up with the selected background image.

A pearl of great price

If you are using Xcode for either Macintosh or iPhone development, please go to one of your implementation files in Xcode right now, hold down Control and Command and press the up arrow. Your life will be much better.