Mocking a UIKit Delegate Protocol with Kiwi

I'm experimenting with mock objects in Kiwi and decided to try and mock the UIAlertViewDelegate. I ran into two issues. 1. Order is important when creating the mock delegate object. It needs to be setup with all the delegate method receive calls before you use the object associated with the delegate protocol.

2.  The delegate protocol methods need to be mocked in the order they are invoked, or you'll receive a test failure. This can be trial and error, if you don't know how the delegate protocol works.

a. For each mock delegate test, I just kept running until I was able to get the mock delegate calls passing.

b. I also discovered that the didDismissWithButtonIndex and  clickedButtonAtIndex were not invoked after using the dismissWithClickedButtonIndex method call.

[objc] #import "Kiwi.h" #import "PSMessages.h" #import "PSMessageConstants.h"

SPEC_BEGIN(PSMessagesTest)

describe(@"Create an alertview", ^{ __block PSMessages *messages = nil; beforeEach(^{ messages = [[PSMessages alloc] init]; });

NSDictionary *urlMessage = @{ @"type" : @"url", @"url" : @"http://www.PhotoTableApp.com", @"message" : @"Create a collage for the next holiday.", @"title" : @"Design Collages", @"buttons" : @[@"Yes", @"No"] };

context(@"with a url message", ^{ __block UIAlertView *alert = nil; beforeEach(^{ alert = [messages alertForMessage:urlMessage]; }); it(@"the cancel button is pressed", ^{ id delegateMock = [KWMock mockForProtocol:@protocol(UIAlertViewDelegate)]; alert.delegate = delegateMock;

int buttonIndex = alert.cancelButtonIndex;

[[[delegateMock shouldEventually] receive] alertViewShouldEnableFirstOtherButton:alert]; [[[delegateMock shouldEventually] receive] didPresentAlertView:alert]; [[[delegateMock shouldEventually] receive] willPresentAlertView:alert]; [[[delegateMock shouldEventually] receive] alertView:alert willDismissWithButtonIndex:buttonIndex]; [[[delegateMock shouldEventually] receive] alertView:alert willDismissWithButtonIndex:buttonIndex];

// Note: delegate methods not called for programatic UIAlertView dismiss [[[delegateMock shouldEventually] receive] alertView:alert didDismissWithButtonIndex:buttonIndex]; [[[delegateMock shouldEventually] receive] alertView:alert clickedButtonAtIndex:buttonIndex];

// Invoke methods after the delegateMock object is setup [alert show]; [alert dismissWithClickedButtonIndex:buttonIndex animated:NO];

});

it(@"the ok button is pressed", ^{ id delegateMock = [KWMock mockForProtocol:@protocol(UIAlertViewDelegate)]; alert.delegate = delegateMock;

int buttonIndex = alert.firstOtherButtonIndex;

[[[delegateMock shouldEventually] receive] alertViewShouldEnableFirstOtherButton:alert]; [[[delegateMock shouldEventually] receive] didPresentAlertView:alert]; [[[delegateMock shouldEventually] receive] willPresentAlertView:alert]; [[[delegateMock shouldEventually] receive] alertView:alert willDismissWithButtonIndex:buttonIndex]; [[[delegateMock shouldEventually] receive] alertView:alert willDismissWithButtonIndex:buttonIndex];

// Invoke methods after the delegateMock object is setup [alert show]; [alert dismissWithClickedButtonIndex:buttonIndex animated:NO];

}); });

}); SPEC_END [/objc]

Duplicate Code Signing on Xcode with Any iOS SDK

Working with Xcode code signing is a pain. You may have encountered a situation where there are more than two code signing identity's in Xcode. This means that you potentially have to change four different code signing settings to update your app, rather than just two. I think this is cruft from upgrading to the newest Xcode version or something. Here's what it looks like and here's how to fix it. It's very annoying when developing and testing with adhoc and app store builds.

 

Code signing in Xcode 4

 

The issue is visible with the "Any iOS SDK" seen as a subitem to the Debug and the Release builds. Things won't work correctly if the two don't match in my experience. So I end up having to change two at a time.

Solution

You can close Xcode or keep it open. It seems to work either way before you start the next steps.

1.Open your project folder in finder. (Right click project in Xcode and choose "Show in Finder")

Show in finder

2. Right click on the Xcode project file in Finder -> "Show Package Contents"

Xcode project Show package contents

3. Right click on the project.pbxproj and choose "Open With" -> "TextEdit"

Xcode project in Textedit

4. Search for "Sign" and delete any lines that look like the following. Xcode will regenerate, so don't worry about deleting them. I believe the first two are the root of the problem.

"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";

"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";

CODE_SIGN_IDENTITY = "iPhone Developer";

Textedit code sign identity

5. Open the project settings in Xcode and see the duplicate "Any iOS SDK" are removed and Xcode regenerated the default Code Sign Identities.

Fixed code sign duplicates

6. Update with your credentials for Debug/Release.

Update code sign

Enjoy.

Learn iPhone Programming via Skill Share in Rochester, NY

I'm teaching a small hands-on course for iPhone development in Rochester, NY on April 21st 10am-12pm.

Signup

Space is limited: http://skl.sh/rIUWEE

About this Class

Learn how to get started with iPhone/iPad development and start making iPhone/iPad apps today. Install the tools and create an app without prior experience.

Lecture: 30-45 minute lecture on getting started

  • Xcode - Code editor
  • Objective-C - Computer language
  • Setting up developer credentials

Workshop: 1:30 hours

  • Learn how to start programming
  • Build your first app - hands on learning

Recommended Reading

About Paul Solt

  • Computer science graduate student at RIT
  • Worked at Apple Inc. and Microsoft.
  • 4 years as a computer science student instructor at RIT
  • 5 apps on App Store
  • 12 years of programming experience

Prerequisites

  • Mac computer (Macbook Pro, Macbook Air, iMac)
  • Install Xcode 4.3+ from the Mac App Store. http://developer.apple.com/xcode/
  • (Optional) Bring iPhone/iPad with usb cables
  • (Optional) Register as a iOS Developer $99/year: https://developer.app

The Potential of Siri

I've been working on iPhone development for several years and I have been very excited to see how the iPhone SDK has progressed. See my original article on how I envisioned the iPad revolutionizing the computing experience. Siri takes the iPhone platform to an entirely new level.  Feature article by MD

If you're curious as to how the potential of Siri will impact iOS App development, then look no further than the video Apple used to demonstrate the technology, despite its somewhat heavy-on-the-awesome slant. The fact of the matter is, this is voice recognition technology that's approaching the level of sophistication you saw in Startrek Voyager as a kid, and it could do wonders for 3rd party App developers.

"Load Angry Birds. New game, please. Aim 45 degrees off the starboard. Lower 3 degrees. Fire. Raise 3 degrees. Fire. Down with the piggies! Fire."

It sounds far fetched, but is it? Voice control to do anything from text messaging to calling, and it's not difficult to imagine it controlling things that are not traditionally based around natural voice input. It'd also be a great idea to work in some camera/augmented reality games, as playing "I Spy" with Siri could only make the device even more intuitive, when you're not ringing your husband, friend or O2 without even touching your handset.

An open API to Siri will help push developers in a new direction building innovative software for the iPhone 4S, given that Siri pushes the boundaries in a way that encourages people to try something new. Google Goggles was a great example of this - it took what QR codes were doing and pushed it farther than anyone had expected it to go - I certainly didn't expect to be able to use my voice to dictate a text message, make two calls and send an email to my boss, did you?

The best thing about it is the potential it awards developers working with voice and hardware interaction, as unless you're paranoid about SkyNet and HAL-9000 becoming a reality, it certainly puts a friendlier face on an already friendly looking phone. All that's left is for us to enjoy the adventures many app programmers are embarking on with Siri, in addition to the talented invidiual who's just ported it to the iPhone 4. Good times to come, ahead.