Best objective-c questions in September 2010

Best practice for setting up an automated build server for iphone apps?

13 votes

I'm looking to setup an automated nightly build server for our iphone apps, and looking for advice on what works and what doesn't.

Basically, something that at least nightly runs all the unit tests and publishes a new adhoc build to our internal website.

All the developers use laptops (which'll be off overnight), so I'm considering getting a dedicated Mac Mini to do this.

I'm not sure if I should get standard Mac OS X or the server edition.

At least for the first attempt, I'm considering just using a simple shell script run from a crontab to do the actual work. In the future a full continuous integration server (hudson etc) would be good.

I've already found a few articles through searching, though they're quite brief:

http://nachbaur.com/blog/how-to-automate-your-iphone-app-builds-with-hudson

http://blog.jeffreyfredrick.com/2008/11/27/continuous-integration-for-iphonexcode-projects/

and also this stackoverflow question has some useful software info (though it's two years old now):

http://stackoverflow.com/questions/212999/continuous-integration-for-xcode-projects

Any guidance people can give on how they've setup a build server and any potential issues would be greatly appreciated.

Thanks!

Joseph

Hudson is really not hard to set up; it's what we use internally. We don't just run iphone builds from it -- in fact, there's only only one lone mac mini set up for iphone builds, and it's a relatively recent addition. We've had a half-dozen other slaves on it for other different platforms for some time.

You can play with it through the "Test Drive" link on the Meet Hudson page to get a feel for how easy it is to set up. (This is one of the things that sold me on it; it was really easy to get started with, but still configurable, extensible, and powerful enough to keep us expanding over the last few years. It replaced a really kludgy pile of hand-rolled scripts and programs that, despite being the author of, I was very happy to see laid to rest.)

We have the hudson backend running on a beefy Mac OSX server, but there's no reason you couldn't run it pretty much anywhere (linux, windows, mac).

As for configuring it for building -- it's about 6 lines of shell script in the project configuration, mostly calling xcodebuild and passing it -project and -configuration arguments.

Example:

cd ${WORKSPACE}/Engineering/

set -e
set -v

xcodebuild -project foo.xcodeproj -alltargets -configuration Distribution clean
xcodebuild -project foo.xcodeproj -alltargets -configuration Release clean
xcodebuild -project foo.xcodeproj -alltargets -configuration Debug clean

xcodebuild -project foo.xcodeproj -alltargets -configuration Distribution
xcodebuild -project foo.xcodeproj -alltargets -configuration Release
xcodebuild -project foo.xcodeproj -alltargets -configuration Debug

We haven't set up the slave to run as a service yet -- this is on the TODO list. For now we just launch it via JNLP whenever we reboot the mini it's on.

Repository is SVN, and the hudson master takes care of remembering the https auth info for us.

We actively use the Email-ext plugin, and have a build timeout plugin and an audit trail plugin since there are a lot of other people using the system and some of the builds are not well-behaved. We've experimented briefly with the Warnings plugin and Static Code Analysis plugins as well, need to get those used on more projects (we usually have warnings as errors in builds, but we do use PC-Lint and other tools on some projects; having output aggregated and tracked here is very nice). Finally the all-important Chuck Norris and Emotional Hudson plugins.

We're currently not running unit tests (shame!) on any of the iphone builds, and we just use the ordinary "Archive the Artifacts" functionality built into hudson for storing builds. These can be accessed via authorized users via the hudson web interface. I've no doubt that it would not be hard for you to run your unit tests within the framework.

</fanboy>

Our only real issues have had to do with AFP and SMB on the mac mini -- nothing to do with hudson at all, more just our internal network infrastructure. And the mini is a bit slow for my tastes -- we usually run pretty beefy build slaves on the theory that quick autobuild turnaround is a good thing. The mini may be gifted an SSD for this reason at some point.

Should I use properties or direct reference when accessing instance variables internally?

12 votes

Say I have a class like this:

@interface MyAwesomeClass : NSObject
{
@private
    NSString *thing1;
    NSString *thing2;
}
@property (retain) NSString *thing1;
@property (retain) NSString *thing2;
@end

@implementation MyAwesomeClass
@synthesize thing1, thing1;
@end

When accessing thing1 and thing2 internally (i.e, within the implementation of MyAwesomeClass), is it better to use the property, or just reference the instance variable directly (assuming cases in which we do not do any work in a "custom" access or mutator, i.e., we just set and get the variable). Pre-Objective C 2.0, we usually just access the ivars directly, but what's the usual coding style/best practice now? And does this recommendation change if an instance variable/property is private and not accessible outside of the class at all? Should you create a property for every ivar, even if they're private, or only for public-facing data? What if my app doesn't use key-value coding features (since KVC only fires for property access)?

I'm interested in looking beyond the low-level technical details. For example, given (sub-optimal) code like:

@interface MyAwesomeClass : NSObject
{
    id myObj;
}
@proprety id myObj;
@end

@implementation MyAwesomeClass
@synthesize myObj;
@end

I know that myObj = anotherObject is functionally the same as self.myObj = anotherObj.

But properties aren't merely fancy syntax for instructing the compiler to write accessors and mutators for you, of course; they're also a way to better encapsulate data, i.e., you can change the internal implementation of the class without rewriting classes that rely on those properties. I'm interested in answers that address the importance of this encapsulation issue when dealing with the class's own internal code. Furthermore, properly-written properties can fire KVC notifications, but direct ivar access won't; does this matter if my app isn't utilizing KVC features now, just in case it might in the future?

I don't think any way is 'better'. You see both styles in common use, so there isn't even a usual/best practice now. In my experience, the style used has very little impact on how well I digest some implementation file I am looking. You certainly want to be comfortable with both styles (and any in between) when looking at other people's code.

Using a property for every internal ivar might be going slightly overboard, in terms of maintenance. I've done it, and it added a non-trivial amount of work that I don't think paid off for me. But if you have a strong desire/OCD for seeing consistent code like self.var everywhere, and you have it in the back of your mind every time you look at a class, then use it. Don't discount the effect that a nagging feeling can have on productivity.

Exceptions- Obviously, for custom getters (e.g. lazy creation), you don't have much of a choice. Also, I do create and use a property for internal setters when it makes it more convenient (e.g. setting objects with ownership semantics).

"just in case", "might" is not be a compelling reason to do something without more data, since the time required to implement it is non-zero. A better question might be, what is the probability that all the private ivars in some class will require KVC notifications in the future, but not now? For most of my own classes, the answer is exceedingly low, so I now avoid a hard rule about creating properties for every private ivar.

I've found that when dealing with internal implementations, I quickly get a good handle on how each ivar should be accessed regardless.

If you are interested, my own approach is this:

  • Reading ivars: Direct access, unless there is a custom getter (e.g. lazy creation)
  • Writing ivars: Directly in alloc/dealloc. Elsewhere, through a private property if one exists.

How to speed up TDD flow with iOS and Objective-C/Xcode

9 votes

Have been searching for experiences on TDD with Objective-C and iOS development.
Previous post about "string calculator"-kata in Objective-C was useful (thanks).

But it would be nice to learn even more fluent iPhone-TDD.

Do you have some experience of how to use UISpec (based on Rspec), iCuke (based on cucumber) or similar tools?

And if you also have got the flow going with autotesting (autoiphonetest.rb) like Paul did in his his blog, it would be very interesting feedback.

Here is a good post: Test Driven Development in Objective-C with MacRuby

I found the following screencast pretty useful http://vimeo.com/9394596 to get started.

360° panorama librarys for ios

9 votes

are there any libraries or classes out there to show a 360 degree panorama on the iphone?

i found this here: http://code.google.com/p/panoramagl/ but its not up to date and only for old versions of ios.

i'm thankfull for any link that helps me to create a 360 degree panorama view on ios.

thanks!

I've recently found KRPano and since it's not listed here..

Categories/Interfaces From Static Libs Not Autocompleting?

9 votes

Thanks to this post and the now built-in static library template, I am able to put some of the pieces of my project elsewhere. Everything compiles with no warnings and runs fine. However, I used to get autocomplete for the categories in my import statement. This is no longer happening. How can I get autocomplete for categories in a static library?

The problem is that XCode doesn't know where to look for your header files.

To fix this, do the following - In the "User Header Search Paths" of your app's target, point to the location of your category header. That tells XCode where to look for it, and autocomplete should work. In case of multiple targets, you could fix it for each target or at the project's settings.

Objective C parse hex string to integer

8 votes

I would like to know how to parse a hex string, representing a number, in objective c. I am willing to use both an objective, or a C based method, either is fine.

example:

#01FFFFAB

should parse into the integer: 33554347

Any help would be appreciated!

Joshua Weinberg's answer is mostly correct, however the Ox prefix is optional when scanning hexadecimal integers. If you have a string in the format #01FFFFAB, you can still use an NSScanner, but you can simply skip the first character.

unsigned result = 0;
NSScanner *scanner = [NSScanner scannerWithString:@"#01FFFFAB"];

[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&result];

Why do people always use reassignment for instance variables in objective-C (namely iphone)?

8 votes

I always see example code where in the viewDidLoad method, instead of saying, for example

someInstanceVar = [[Classname alloc] init];

they always go

Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];

Why is this? Isn't it the exact same thing, just longer?

The short answer: This pattern shows up all the time in iPhone code because it is considered the best way to create a new object and assign it to a member variable while still respecting all of the memory management rules and invoking the appropriate side effects (if any) while also avoiding the use of autorelease.

Details:

Your second example would create a zombie, since var is left holding a pointer to memory that has been released. A more likely usage case looks like this:

tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];

Assuming that propertyVar is a declared as copy or retain property, this code hands off ownership of the new object to the class.

Update 1: The following code is equivalent, but not recommended* on iOS, which is probably why most iPhone programs use the first pattern instead.

self.propertyVar = [[[Classname alloc] init] autorelease];

* autorelease is discouraged on iOS because it can cause problems when overused. The easiest way to be sure you never overuse it is to never use it all, so you will quite often see iOS code that uses alloc/init and release, even when autorelease would be acceptable. This is a matter of coder preference.

Update 2: This pattern looks confusing at first because of the memory management that Cocoa performs automagically behind the scenes. The key to it all is the dot notation used to set the member variable. To help illustrate, consider that the following two lines of code are identical:

self.propertyVar = value;
[self setPropertyVar:value];

When you use the dot notation, Cocoa will invoke the property accessor for the indicated member variable. If that property has been defined as a copy or retain property (and that is the only way for this pattern to work without creating a zombie), then several very important things happen:

  1. Whatever value was previously stored in propertyVar is released
  2. The new value is retained or copied
  3. Any side effects (KVC/KVO notifications, for example) are automatically handled

How to unit-test an internet protocol implementation?

7 votes

I decided to add unit tests to my project and continue development in a test-driven kind of way. I’m currently working on implementing unit tests for my ManageSieve client object and I’m not sure what’s the best way to test that beast.

My SieveClient object relies on two other objects for the network communication: CocoaAsyncSocket and my own SaslConn object, which is my wrapper around the Cyrus SASL library to handle the authentication methods. For testing I need to replace those with mock objects. I’m going to use the OCMock framework for this. I’m not quite sure how to do this, since the SieveClient object needs to create those objects itself. Right now I overwrite the (private) setters for that object to always install my mock objects using OCMocks partialMockForObject: method. But this feels not right to me. Any ideas how this could be solved better?

The other part I have trouble with is the socket itself. To be able to test the protocol details I’d need a way to return predefined test data from the socket. I suppose I could just use OCMock mechanisms to fake the return values from the socket. But since CocoaAsyncSocket provides many different methods to read data from the socket I have to know exactly which are being used by the protocol object in which order. I don’t want my unit test to be that dependent on implementation details of my protocol object. So what should I do here? Implement a mock object for the socket class by hand? This seems non-trivial, so I’d probably need unit tests for that too. Is that a good idea?

I’ve read that if something is hard to test it’s probably not very well designed either. But I don’t see how I could do better, since the hard part lies in interacting with the socket which I have to do.

If you’d like to see code you can find it at Bitbucket: SieveClient.m and SieveClient.h

Edit: Dependency Injection

So I read about Dependency Injection, and I think I’m going to use this to get the AsyncSocket and SaslConn objects into my SieveClient object. I’ll change my constructor to accept those objects and use them. Since the user of this class usually doesn’t care about the socket and the SASL object I’ll add a factory method (in the form of a convenience constructor) that just creates those objects and passes them to the constructor.

But this solves only the first (and easier) part of my testing problem.

Can you split what you're doing into two parts, one of which is the abstract protocol and the other of which is the binding to sockets? Then you can test the abstract protocol more easily, and focus the testing of the binding on whether it invokes methods/operations of any connected abstract protocol correctly.

Abstractly, you'd be decreasing the coupling between the parts of your code. That increases testability, at a cost of some increase in overall complexity (though not too bad because you're getting better tools to manage it through Separation of Concerns) and some potential decrease in performance (not much of an issue with most systems though; your computer is far faster than its I/O subsystems).

Simple bug crashes hangs Xcode.

7 votes

I have build the simplest possible iPhone program, a window based program. I only changed the testappdelegate.h file to be the following:

#import <UIKit/UIKit.h>

@interface TestAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    int pos[10]10]; //note the error here.
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

Note the error in the 'int pos...' line.

When I try to compile this program XCode hangs (showing millions of errors). I am not asking how to fix the line, the fix is obvious.

The problem is that overwhelms XCode and I want to know why?

Update: submitted bug report Bug ID# 8406197

Update2: Sept 24. I got a response from Apple Engineering has provided the following information:

We don't plan to fix this in llvm-gcc or gcc, and it is already fixed in clang. Xcode not freaking out is tracked in a clone of this bug.

We are now closing this bug since our engineers are aware of the issue and will continue to track it offline.

The issue is that Xcode is having to ingest those millions of errors to try and figure out if there is a line of code that needs annotation.

Please file a bug via http://bugreport.apple.com/.

That you have produced such a simple test case will help the engineering team to ensure that any fixes they may be pursuing address the problem sufficiently. There are potentially two bugs here; the first for Xcode to handle such a volume of errors gracefully and the second for the compiler to not spew so much in the face of such an obvious error.

It is likely that your bug(s) will be returned as known duplicates. That only happens, though, after the engineering team has captured any unique information from your bug. That is to say, dupes are often very useful.

When filing the bug, add the bug # to your SO question. Many Apple engineers cruise SO and will click through to followup internally.

6 votes

How can I get the year/month/day of a NSDate object, given no other information? I realize that I could probably do this with something similar to this:

NSCalendar *cal = [[NSCalendar alloc] init];
NSDateComponents *components = [cal components:0 fromDate:date];
int year = [components year];
int month = [components month];
int day = [components day];

But that seems to be a whole lot of hassle for something as simple as getting a NSDate's year/month/day. Is there any other solution?

Yeah, it's a little bit of hassle, but that's the only way of getting this information without manually calculating it yourself from NSDate's -timeIntervalSince1970 method.

If you're going go with NSCalendar, though, you might want to change your code a bit to make it easier to use:

NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
NSInteger day = [components day];    
NSInteger month = [components month];
NSInteger year = [components year];

Also, if you have to pass around these date components a lot, I'd recommend wrapping them in a struct. Just a tip.

OpenGL glTexParameter

5 votes

Hey guys I just had a simple question. Does glTexParamter act on all textures or just the texture that is currently bound

So like if I call this at the texture load:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

And this on another texture load:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

When I bind the first texture will it just use the last value I set (GL_CLAMP) or will it use the values set while the texture was bound?

From the OpenGL FAQ:


21.070 How do texture objects work?

Texture objects store texture maps and their associated texture parameter state. They allow switching between textures with a single call to glBindTexture().

(...)

The following functions affect and store state in texture objects: glTexImage*(), glTexSubImage*(), glCopyTexImage*(), glCopyTexSubImage*(), glTexParameter*(), and glPrioritizeTextures(). Since the GLU routines for building mipmap pyramids ultimately call glTexImage*(), they also affect texture object state.Noticeably absent from this list are glTexEnv*() and glTexGen*(); they do not store state in texture objects.


Ergo, glTexParameter* affects only the bound texture.

Odd Core Data error caused by over releasing?

5 votes

Occasional reader and first time question asker, so please be gentle :)

I am creating a Managed Object (Account), that is being passed into a child view controller where its being set in a property that is retained.

Account * account = [[Account alloc] initWithEntity:entity insertIntoManagedObjectContext:context];
AddAccountViewController *childController = [[AddAccountViewController alloc] init];
childController.title = @"Account Details"; 
childController.anAccount = account;
childController.delegate = self;

[self.navigationController pushViewController:childController animated:YES];
[childController release];
[account release];

The view controller interface:

@interface AddAccountViewController : UIViewController {
}

@property (nonatomic, retain) IBOutlet UITextField * usernameTextField;
@property (nonatomic, retain) IBOutlet UITextField * passwordTextField;

@property (nonatomic, retain) Account * anAccount;
@property (nonatomic, assign) id <AddAccountDelegate> delegate;

- (IBAction)cancel:(id)sender;
- (IBAction)add:(id)sender;
- (IBAction)textFieldDone:(id)sender;
@end

So in code sample 1 I've released the account object because I am no longer interested in it in that method. As it is retained by the AddAccountViewController I have an entry in AddAccountViewController's dealloc that releases it.

However when I go to delete the object from the ManagedObjectContext the app crashes with the following (rather unclear) error:

Detected an attempt to call a symbol in system libraries that is not present on the iPhone:
_Unwind_Resume called from function _PFFaultHandlerLookupRow in image CoreData.

After much debugging & hair pulling I discovered that if I don't release account in AddAccountViewController's dealloc method the app works properly continually and doesn't appear to leak according to Instruments.

Can anyone shed any light as to whats going on? I understand from the docs on properties that those retained need to be released. What have I missed?

Update to answer Kevin's question

The code to delete the object from the ManagedObjectContext is in the RootViewController (that holding the child controller)

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the managed object for the given index path
        NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];

        [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

        // Save the context.
        NSError *error = nil;
        if (![context save:&error]) {
            /*
             Replace this implementation with code to handle the error appropriately.

             abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
             */
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }  
}

Firstly: It sounds like a bug on Apple's part. Core Data is calling _Unwind_Resume, which is (probably) some sort of exception unwind. Exception-unwinding exists on the phone, but (I think) uses the ARM ABI, which uses function names beginning with __cxa_. Are you running on the simulator? Which version of the SDK?

There might be an extra release floating around somewhere which is "balanced" when you remove the call to [account release];.

"Instruments doesn't show any leaks" doesn't mean there aren't any; last I checked it got confused by cycles (i.e. it wouldn't show a leak if you forgot to un-set IBOutlets in dealloc). I tested with NSMutableData * d = [NSMutableData dataWithLength:1<<20]; memcpy(d.mutableBytes, &d, 4);, but an easier test is just [[UIView alloc] initWithFrame:CGRectZero].

If you think it's a retain/release issue, I once debugged these by overriding retain/release/autorelease to call NSLog. I then added breakpoints on all of them, set them to run the command "bt", and clicked the autocontinue. Then run the thing that breaks (in my case I think it was just an extra retain), print out the log output,stick it on a whiteboard, and spend half an hour matching retains and releases.

What's the normal way of organising a header file in Objective-C?

5 votes

I do start off organising my .h files with the best intentions but somehow they get disgustingly messy.

Below is an example (which isn't that bad, but i've seen much worse!). I've tried grouping sections with #pragma mark but it seems to look even messier.

All the UILabels and UIButtons are required (as mentioned above) as they're showing data coming from a web service request so they're all required if we're using Interface Builder to design our GUI's. For example, the label might be a "weight" or "height" characteristic for a product.

Does anyone have any good advice on how to organise these in the most maintainable/readable way?

Cheers

alt text

It strikes me as possible that you have too many properties, there. I've quite literally never seen any class with this many outlets; why are you addressing every single element in your layout? And why all from one controller?

It seems as if the best solution to your problem is to consider your class and split it up into multiple classes; each controlling one aspect of your interface. You also need to make sure that you really need to address all these elements. (The UILabels and UIButtons in particular seem like strange things to have outlets for.)

Can I use NSAttributedString in Core Text in iOS?

5 votes

I'm trying to work out how to take an NSAttributedString and use it in Core Text on the iPad. I watched one of the WWDC videos (110) which has slides (but no source code) and it describes how to create an NSAttributedString, then just put it into a CTFramesetterRef:

CTFontRef helveticaBold = CTFontCreateWithName( CFSTR("Helvetica-Bold"), 24.0, NULL);

NSString* unicodeString = NSLocalizedString(@"TitleString", @"Window Title");
CGColorRef color = [UIColor blueColor].CGColor; NSNumber* underline = [NSNumber numberWithInt:kCTUnderlineStyleSingle|kCTUnderlinePatternDot];
NSDictionary* attributesDict = [NSDictionary dictionaryWithObjectsAndKeys:helveticaBold, (NSString*)kCTFontAttributeName, color, (NSString*)kCTForegroundColorAttributeName, underline, (NSString*)kCTUnderlineStyleAttributeName, nil];
NSAttributedString* stringToDraw = [[NSAttributedString alloc] initWithString:unicodeString attributes:attributesDict];

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(stringToDraw);

CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CTFrameDraw(frame, context);
CFRelease(frame);

But when I try this, it throws the error:

Passing argument 1 of 'CTFramesetterCreateWithAttributedString' from incompatible pointer type

Are CFAttributedString and NSAttributedString 'toll-free bridged'? I've read somewhere that this is only true on OSX, but this is how Apple do it in their demo...

Thanks!

:-Joe

You can download the WWDC10 source code here. In addition, use toll-free bridging and explicitly cast your stringToDraw to a CFAttributedStringRef.