Posts Tagged ‘Cocoa’

NSNotificationCenter with Blocks Considered Harmful

This is worth while to being shared!
http://sealedabstract.com/code/nsnotificationcenter-with-blocks-considered-harmful/

Xcode 5 creates properties ( member variables ) for @property like this

For people who doesn’t trust me.

This is original behavior of creating a member variable for a @property.

Very interesting bug of Objective-C

When a member variable (aka property in SmallTalk term, semantically same to @property, but member variables are called “property” in SmallTalk. ) is accessed using self.<property name> through the @property mechanism or just <member variable> name, sometimes the result is different.

different values

Spark Inspector : Its flexibity

Ok.. Using Spark Inspector was very easy.

At first there was one odd thing : Where is the SparkInspector.framework?
It’s located in Spark Inspector app. However, if using its “Framework Setup assistant”, the app ingest frameworks to be linked for a chosen project for you.

One thing I didn’t like was that.. as most Cocoa programmers tend to set up a Xcode project, it puts framework setting in “target” Build Settings rather than “Project” Build Settings.

link settingIf you want to set those links as default for all targets you end up adding, the easier way is to put that setting in “project” Build Settings. I know that many Mac/iOS app developers who usually jumped into Mac/iOS app dev. after iOS became popular don’t understand the different necessity between the “Target” and “Project” Build Settings.
Anyway, this is not a big deal.

Now, let’s talk about cool things.

Spark Inspector app

As you can see from the above picture, your app runs on a simulator or an actual device while debugging, but the Spark Inspector app intercept that also and displays view hierarchy in list form on its left pane, visual representation of it in the middle pane, and finally, properties of chosen view/layers on the right-most pane. So, while you are debugging and interacting with a real device or a simulator, you can change colors, tints etc by choosing a layer/view on the Spark Inspector and changes some properties of them.
You don’t need to paint your layer/view in your code for debugging purpose anymore!
Isn’t that cool?

Also, the most important and useful feature of this app is the 3D display of those views and layers. When one view occludes an underlying view completely, and if there is some transition is applied to the underlying view ( unexpectedly ), you can still check what’s happening visually.

You can say that recursiveDescription is good enough. (It’s undocumented message of UIView )
However, when there are lots of view/layers, it can be very hard to identify which one is which when you use the message. However, this great helper tool for UI debugging eases debugging very easy.

After the PaintCode, I think this is a must-have tool for iOS developers!
I’ll buy it soon.

BTW, there is one little glitch there. As you can see, the right side of the right-most pane invades the right border of its super view. So, the content on the right-most pane goes beyond the right border.

difference in auto synthesis and “traditional” synthesis

After the introduction of iPhone SDK, many things have been changed very quickly.
Some were changed very publicly, while some didn’t. Even though there is no explanation on those changes, you could figure out some by taking a look at basic template code which Xcode puts by default.
However, some are hidden.
I was away from iOS/Mac development for a while and tried to catch up stuff recently. One of the simple but astonishing one was the internal member variable Objective-C preprocessor creates.

For example, let’s say that interface file looks like this.

@interface JAWindowController : NSObject

@property (retain, nonatomic) IBOutlet UIToolbar *toolBar;
@property (retain, nonatomic) IBOutlet UIButton *buttonOne;
@property (retain, nonatomic) IBOutlet UITextView *textViewOne;

@end

Then when ARC is off and auto synthesis is used, it creates those internal variables which matches their properties with “_” prefixed to the property name.

#import "JAWindowController.h"

@implementation JAWindowController

- (void)dealloc
{
	[_buttonOne release];
	[_textViewOne release];
	[_toolBar release];
	[super dealloc];
}
@end

However, if explicit synthesis is used, it will create the default internal variable names same to their property names like this.

the red underlines means a variable with such a name doesn't exists.

the red underlines means a variable with such a name doesn’t exists.

When ARC is on, it’s the same like the case of ARC is off. The only difference is that it doesn’t create dealloc message for you automatically, because usually it’s not necessary because Objective-C objects are to be released automatically by ARC mechanism.

Getting camera resolution on iOS devices

Apple doesn’t provide easy to use class or messages to retrieve camera resolution. However, people are saying that there is a way to get the information.

So, based on that, I wrote this code.

- (void) setupVideoCaptureSession
{
	self.isSetUpOK = true;
	
	self.cameraCaptureSession = [[AVCaptureSession alloc] init];
	
	self.cameraCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
	bool isBackCamera = ([self.cameraCaptureDevice position] == AVCaptureDevicePositionBack);
	
	NSError *error;
//	NSLog( @"position : %@", ([defaultCaptureDevice position] == AVCaptureDevicePositionBack)? @"Back":@"Front" );
	if (isBackCamera)
	{
		self.cameraCaptureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.cameraCaptureDevice error:&error];

		if( error == nil )
		{
			// Start of bulk configruation :It's not really needed here, but just in case...
			[self.cameraCaptureSession beginConfiguration];
			
			if( [self.cameraCaptureSession canSetSessionPreset:AVCaptureSessionPresetPhoto] )
				self.cameraCaptureSession.sessionPreset = AVCaptureSessionPresetPhoto;
			
			// End of bulk configuration
			[self.cameraCaptureSession commitConfiguration];
			
			
			[self.cameraCaptureSession startRunning];
		}
		else
			self.isSetUpOK = false;
		
	}
	else
	{
		self.cameraCaptureDevice = nil;
		
		self.isSetUpOK = false;
	}
}

- (CMVideoDimensions) cameraResolutionDimension
{
	CMVideoDimensions resolutionDimension = { 0, 0 };
	
	if( self.isSetUpOK )
	{
		if( self.cameraCaptureSession.isRunning )
			NSLog( @"capture session is running.");
		else
			NSLog( @"capture session is not running");
		
		
		for( AVCaptureInputPort *port in self.cameraCaptureDeviceInput.ports )
		{
			if( [port mediaType] == AVMediaTypeVideo )
			{
				self.cameraCaptureInputPort = port;
				CMVideoFormatDescriptionRef descRef = [port formatDescription];
//				resolutionDimension = CMVideoFormatDescriptionGetDimensions([port formatDescription]);
				resolutionDimension = CMVideoFormatDescriptionGetDimensions(descRef);
			}
		}
	}
	
	return resolutionDimension;
}

If setupVideoCaptureSession and cameraResolutionDimension are called in that order, it should retrieve the camera resolution dimension in pixels. However, it doesn’t. A guy told me that it’s a bug. So, I filed it.

But I’m not sure. This is so apparent. How come Apple guys pass this stuff through their SQA process? As a person who have know their quality, it should not happen. Nowadays I notice lots of bugs in their tools, frameworks, etc. What’s happening in Apple nowadays?

Great tip to figure out view hierarchy

According to objcguy, you can figure out view hierarchy with one call.

http://msxfan.com/nsview-subtreedescription

%d bloggers like this: