Cocoa Samurai

Saturday, August 18, 2018

A modest proposal for optional methods in Swift protocols

Swift contains protocols in which you can declare methods, which something claiming to adhere to the protocol must implement. One thing Swift protocols can’t do are optional methods... sort of. In Objective-C we’d specify an optional method in a protocol like so

@protocol MyProtcol<NSObject>
-(void)someRequiredMethod:(id)param;
@optional
-(void)someOptionalMethod:(id)param;
@end

In Swift you can put the optional keyword next to a method if the protocol is annotated with @objc.

@objc protocol MyProtocol {
func someRequiredMethod()
optional func someOptionalMethod()
}

This solves the problem of optional methods in a protocol, but makes us forever dependent on Objective-C for this feature. Additionally you can only use this with classes, and not structs. This should be possible in Swift alone without relying on Objective-C features. There are some other options, like you could split the protocol up into 2 protocols like so

protocol MyProtocol {
func someRequiredMethod()
}

protocol MyOptionalProtocol {
func someOptionalMethod()
}

And finally the more elegant solution is to provide a default implementation for the optional methods in a protocol extension. This feels like the native Swift way to do it.

protocol MyProtocol {
func someRequiredMethod()
func someOptionalMethod()
}

extension MyProtocol {
func someOptionalMethod() {}
}

This works great, but is poor at communicating intent. In this particular case it is easy to spot the optional method, but that will not be the case with any non trivial project. I want to signal to future developers that these method(s) are optional at the place I declare a protocol, without forcing you to read each methods documentation, or requiring them to read 2 chunks of code, connect the dots, and then realize that the method is intended to be optional. You should be able to glance at a protocol, and easily understand what is optional, and what is not.

The Solution

The solution it seems should be rather simple as it mostly just enforces what the swift compiler already does. At least as of Xcode 10 if you
(1) declare a protocol
(2) provide a default implementation for the optional methods in a protocol extension and
(3) declare something as adhering to the protocol, and you haven’t implemented any of the methods
Then Xcode will only stub in your “required” methods in a fix it, after you declare a type that adheres to the protocol.

So why don’t we just enforce this practice in the compiler? It would work like this. You would annotate a func in a protocol with the optional keyword like so.

protocol MyProtocol {
func someRequiredMethod()
optional func someOptionalMethod()
}

If you haven’t provided a default implementation in a protocol extension, you will get an error/fix-it like this

"Error. Function annotated with optional in a protocol declaration must have a corresponding default implementation. Add stub(s) for the default implementation?"

For this case we’d just implement an empty method body since it doesn’t return anything

extension MyProtocol {
func someOptionalMethod() {}
}

This way we both declare intention at the place the protocol is declared, and avoid optionals in dealing with the protocol. Under this new system everything pretty much works as it already does, the only difference is the compiler now lets us annotate our intention and enforces a practice swift devs already use for swift protocols.

Thanks to Rob Rix and Mustapha for discussing this issue with me, which lead to this solution.

Thursday, March 07, 2013

Basic MVVM with ReactiveCocoa

Update: This article has been updated to reflect the changes in the latest stable ReactiveCocoa v2

MVC - One Pattern to Rule them all

The MVC design pattern has existed since the late 1970s and has been in use in the Foundation, AppKit & UIKit Frameworks for a long time now. At its heart is a very simple design and a good idea. The Design is this

As you can see we have 3 components

  • Model - The Data model our view is managing
  • View - The User Interface on screen consisting of things such as text fields, buttons, etc.
  • Controller - The Controller in MVC exists to decouple the view from the model.

In the MVC design pattern, the controller separates the model from the view so that each can change independently. If we didn't have such a decoupling then every time the model changed, the view would need to change as well. In this design pattern interactions happen like this

  1. A view triggers an action to happen on the Controller
  2. The Controller executes said action and updates the model
  3. The controller may receive a notification from the model that it was updated.
  4. The Controller updates the view

This is the MVC waltz that we do when working with this design pattern, overall it works fairly well. The reason we use this is because this pattern decouples the view from the data model, letting the controller be an intermediary between the 2. This allows the controller to access the parts of the data model that need to be accessed and allows for the controller to do things like properly format the data for the view.

MVVM - For a Better World

MVVM stands for Model-View-ViewModel, and comes from Microsoft and is based off of the MVC design pattern. To be more precise, it is based off of Martin Fowlers Presentation Model. To some people at first it looks very similar to the MVC design pattern and people become confused as to how its different. So let me show you the pattern and then we'll see how its different

In this pattern we still have 3 components, the same as MVC however there are differences. In MVVM I and others tend to group the View Controller in with the View so that those 2 things are treated as 1 component. The most important part is that we've introduced the View Model and that the view gets updates pushed at it from the view model through some sort of observer. In this article ReactiveCocoa will be that observer.

In the MVVM pattern the View Model encapsulates data/properties that the view can bind to and any validation logic and actions that can be performed. For Instance if you had a button that needs to change its title text you would have a property on the view model that the button can bind its title property to. The same goes if you need to change the color of a control or enable and disable the control. In this pattern we are essentially taking the state of our app and putting it into a view model. Its also good to note that as far as the View Model is concerned it doesn't care where it gets this state from. It doesn't matter if it gets it from its init method, a file on disk, Core Data, a database, etc.

Because we are encapsulating the state of our view in such a way this has several benefits.

We don't need to test the UI

In terms of standard controls we don't need to test our UI's at all since the controls are just binding their state to the view model. Apple should be testing the controls that we are using, and you should be testing the custom controls you create. This means that as we bind our controls state to the view model we don't need to query the controls for their state as we should be able to access it within the view model itself. This feature tends to lending itself well to the next feature...

We can easily Unit Test the View Model

The View model has access to all the properties the views are binding to, and because of this we can have validation logic on the view model. This also makes it extremely easy to unit test the model and unit test the various states our UI can get into. I think Justin actually phrased this excellently "A good litmus test for MVVM is whether you’re able to write automated tests for your UI behavior without actually having a live UI." I completely agree with this and think it excellently encapsulates the core idea of MVVM.

Its easier to change the UI

Because the UI is just binding to the view model, this means you should be able to swap components out and just bind the apppropriate properties to the view model and your UI should work the same as before. This should also make it easier for UI designers to experiment around with different views in your app.

ReactiveCocoa: An introduction

As I mentioned ReactiveCocoa is an implementation of Reactive Extensions .NET for Cocoa. The API is not an exact mapping of the API from Rx to Cocoa as explained in the project docs. ReactiveCocoa is also built using the concept of Functional Reactive Programming.

Functional Reactive Programming (FRP) is a programming paradigm for writing software that reacts to change.

FRP is built on the abstraction of values over time. Rather than capturing a value at a particular time, FRP provides signals that capture the past, present, and future value. These signals can be reasoned about, chained, composed, and reacted to.

By combining signals, software can be written declaratively, without the need for code that continually observes and updates values. A text field can be directly set to always show the current timestamp, for example, instead of using additional code that watches the clock and updates the text field every second.

Signals can also represent asynchronous operations, much like futures and promises. This greatly simplifies asynchronous software, including networking code.

One of the major advantages of FRP is that it provides a single, unified approach to dealing with different types of reactive, asynchronous behaviors.

Lets jump right into ReactiveCocoa through a couple examples and explain what is going on.

[RACObserve(self,name) subscribeNext:^(NSString *newName){
    NSLog(@"Name changed to %@",newName);
}];
self.name = @"Hypnotoad";
self.name = @"Nibbler";

When this runs it'll give the output "Name changed to Hypnotoad" and then "Name changed to Nibbler". What we did was create a signal around a key path in self, and then subscribed to that signal and received events on the stream from that signal. Think of it this way, once we create a signal around a key path in this manner anytime the value of that key path changes the signal will see this and send a -next signal with the updated value. We automatically subscribed to this signal when we called -subscribeNext on it.

Signals only send 3 types of messages

  • next : This is how we get updated values from the stream
  • error : This is sent anytime the signal could not complete
  • completed : Sent to let you know that there will be no more signals on the stream

Lets create a signal of our own so you can see what is going on here

-(RACSignal *)urlResults {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSError *error;
    NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]
     encoding:NSUTF8StringEncoding
        error:&error];
    if (!result) {
        [subscriber sendError:error];
    } else {
        [subscriber sendNext:result];
        [subscriber sendCompleted];
    }
    return nil;
 }];
}

Although we could achieve this through other means, I wanted to create this manually. This method returns a signal which was created to get the string contents of a URL address and then return them to us. For this I used NSStrings built in method to retrieve a string from a URL. All we need to do is check to see if we have a result and if we don't then we can send -next and then -completed because we don't intend to send anymore messages.

Besides receiving updated values which we'll likely use for assignment to variables, signals also can be used in validation.

NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:@" "];
RACSignal *nameFieldValid = [RACSignal combineLatest:@[ self.usernameField.rac_textSignal, self.passwordField.rac_textSignal ]
 reduce:^(NSString *username, NSString *password) {
    return @((username.length > 0) && (password.length > 0) &&
            ([username rangeOfCharacterFromSet:charSet].location == NSNotFound));
 }];

This particular example would work on iOS if you had a Username field, password field and you wanted to know if it was filled out correctly. For the purposes of this example we will only concern ourselves with making sure the username & password has a length greater than 0 and doesn't have any spaces in the user name. The combineLatest part of the method makes sure that we get the latest values from the textfield signal, then in the reduce section we are simply returning a number (0 or 1) to indicate if this is valid. When we hook this up to the enabled property of a control we get...

RAC(self.loginButton.enabled) = nameFieldValid;

and from there on out we get a button that is automatically enabled & disabled when the correct conditions arise from the signal we binded it to. Similarly we can bind controls to a view model like so...

RAC(self.textField.text) = RACObserve(self.viewModel,title);

What is going on here is that ReactiveCocoa is implicitly setting up all the necessary infastructure to bind a field to a signal. If you expand the RAC fields you get something like...

[RACSubscriptingAssignmentTrampoline trampoline][ 
[[RACSubscriptingAssignmentObjectKeyPathPair alloc] initWithObject:self 
keyPath:@(((void)(__objc_no && ((void)self.self.resultLabel.string, __objc_no)),
 "self.resultLabel.string"))] ] = 
 [self rac_signalForKeyPath:@(((void)(__objc_no && 
 ((void)self.self.aTitle, __objc_no)), "self.aTitle")) 
 observer:self];

Be thankfull you don't have to write all that every time you wanted to bind properties in your code.

What is the ViewModel?

So i mentioned the View Model earlier as being the thing that our user interface binds its properties to as well as containing the actions that can be done to the view model and any validation logic. Lets show a simple example and get started figuring out how the VM in MVVM works. Here is a screenshot of the UI we'll work with...

And here is the ViewModel interface...

#import <Foundation/Foundation.h>

@interface CDWPlayerViewModel : NSObject

@property(nonatomic, retain) NSString *playerName;

@property(nonatomic, assign) double points;
@property(nonatomic, assign) double stepAmount;
@property(nonatomic, assign) double maxPoints;
@property(nonatomic, assign) double minPoints;

@property(nonatomic, readonly) NSUInteger maxPointUpdates;

-(IBAction)resetToDefaults:(id)sender;

-(IBAction)uploadData:(id)sender;

-(RACSignal *)forbiddenNameSignal;

-(RACSignal *)modelIsValidSignal;

@end

and the implementation

#import "CDWPlayerViewModel.h"

@interface CDWPlayerViewModel ()
@property(nonatomic, retain) NSArray *forbiddenNames;
@property(nonatomic, readwrite) NSUInteger maxPointUpdates;
@end

@implementation CDWPlayerViewModel

-(id)init {
    self = [super init];
    if(!self) return nil;

    _playerName = @"Colin";
    _points = 100.0;
    _stepAmount = 1.0;
    _maxPoints = 10000.0;
    _minPoints = 0.0;

    _maxPointUpdates = 10;

    //I guess we'll go with the ned flanders bad words
    //change this to whatever you want
    _forbiddenNames = @[ @"dag nabbit",
                      @"darn",
                      @"poop"
                      ];

    return self;
}

-(IBAction)resetToDefaults:(id)sender {
    self.playerName = @"Colin";
    self.points = 100.0;
    self.stepAmount = 1.0;
    self.maxPoints = 10000.0;
    self.minPoints = 0.0;
    self.maxPointUpdates = 10;
    self.forbiddenNames = @[ @"dag nabbit",
                          @"darn",
                          @"poop"
                          ];
}

-(IBAction)uploadData:(id)sender {
    @weakify(self);
    [[RACScheduler scheduler] schedule:^{
        sleep(1);
        //pretend we are uploading to a server on a backround thread...
        //dont ever put sleep in your code
        //upload player & points...

        [[RACScheduler mainThreadScheduler] schedule:^{
            @strongify(self);
            NSString *msg = [NSString stringWithFormat:@"Updated %@ with %.0f points",self.playerName,self.points];

            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Upload Successfull" message:msg delegate:nil
                                                  cancelButtonTitle:@"ok" otherButtonTitles:nil];
            [alert show];
        }];
    }];
}

-(RACSignal *)forbiddenNameSignal {
    @weakify(self);
    return [RACObserve(self,playerName) filter:^BOOL(NSString *newName) {
        @strongify(self);
        return [self.forbiddenNames containsObject:newName];
    }];
}

-(RACSignal *)modelIsValidSignal {
    @weakify(self);
    return [RACSignal
            combineLatest:@[ RACObserve(self,playerName), RACObserve(self,points) ]
            reduce:^id(NSString *name, NSNumber *playerPoints){
                @strongify(self);
                return @((name.length > 0) &&
                (![self.forbiddenNames containsObject:name]) &&
                (playerPoints.doubleValue >= self.minPoints));
            }];
}

@end

A short note about @weakify(self); and @strongify(self);, this is one of the things you can do in addition to using __weak id bself = self; in your apps to avoid retaining self. This particular bit of code is was originally from libextobjc and then incorporated directly into ReactiveCocoa itself. In particular this has the same effect of creating a weak reference to self. I like this approach because you just keep using self.[property]... in your code and you don't have to constantly remember to create a bself variable. Check out EXTScope.h in libextobjc or RACEXTScope.h in ReactiveCocoa.

as you can see its relatively simple because we are only really concerned with a couple properties related to the player. The other properties are for controls to bind to and for some validation. We also have a single action method and a couple signals. The one thing you'll notice is the View Model has no clue what the UI it'll bind to is like at all. This is great because it means you have flexibility in what you bind things to and you can hook up to the view model in ways that make sense for the class thats binding to it.

Now lets look in our ViewController and how it is using these properties and signals...

__weak CDWViewController *bself = self;

To make sure we don't retain self in our blocks we need to use a weak reference. The ReactiveCocoa Project also has @weakify and @strongify for doing this in blocks, but i'll let you investigate that and see if you want to use it.

//Create the View Model
self.viewModel = [CDWPlayerViewModel new];

obviously start with creating a ViewModel instance

//Start Binding our properties
RAC(self.nameField.text) = [RACObserve(self.viewModel,playerName) distinctUntilChanged];

[[self.nameField.rac_textSignal distinctUntilChanged] subscribeNext:^(NSString *x) {
    bself.viewModel.playerName = x;
}];

The first control is the UITextField for the player name, so we need to bind its text property to the view models playerName property. We also need to make sure we update the view model with updates from the text field. This ensures that the text field receives any updates from the view model and also makes sure that the view is updating the player name property on the view model.

//the score property is a double, RC gives us updates as NSNumber which we just call
//stringValue on and bind that to the scorefield text
RAC(self.scoreField.text) = [RACObserve(self.viewModel.points) map:^id(NSNumber *value) {
    return [value stringValue];
}];

We need to bind the labels text property to the view models points property. The view models points property is a double, but ReactiveCocoa gives us updates to this as NSNumber's so we need to map this to a NSString which the label can use.

//Setup bind the steppers values
self.scoreStepper.value = self.viewModel.points;
RAC(self.scoreStepper.stepValue) = RACObserve(self.viewModel,stepAmount);
RAC(self.scoreStepper.maximumValue) = RACObserve(self.viewModel,maxPoints);
RAC(self.scoreStepper.minimumValue) = RACObserve(self.viewModel,minPoints);

Simple binding and setup. Give the stepper the initial value from the view model and bind the properties (stepValue,min,max) to the view model.

//bind the hidden field to a signal keeping track if
//we've updated less than a certain number times as the view model specifies
RAC(self.scoreStepper.hidden) = [RACObserve(self,scoreUpdates) map:^id(NSNumber *x) {
    return @(x.intValue >= bself.viewModel.maxPointUpdates);
}];

//only take the maxPointUpdates number of score updates
[[RACObserve(self.scoreStepper,value) take:self.viewModel.maxPointUpdates] subscribeNext:^(id newPoints) {
    bself.viewModel.points = [newPoints doubleValue];
    bself.scoreUpdates++;
}];

We'll enforce a rule from the view model that at any given time you can only update the points 10 times. To do this I created a NSUInteger property (in fact the only property we ever actually add to the view controller.) Then bind the hidden property to a signal which reduces to a 0 or 1 based on if the number of times we've updated is greater or equal to the number of times we've updated the points. So as soon as it hits the number we want this will return 1 and flip the hidden property to YES. To update the points we subscribe to the value property of the stepper and anytime it updates we update the view model and increment the player points.

//this signal should only trigger if we have "bad words" in our name
[self.viewModel.forbiddenNameSignal subscribeNext:^(NSString *name) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Forbidden Name!"
                                                    message:[NSString stringWithFormat:@"The name %@ has been forbidden!",name]
                                                   delegate:nil
                                          cancelButtonTitle:@"Ok"
                                          otherButtonTitles:nil];
    [alert show];
    bself.viewModel.playerName = @"";
}];

If you remember the view model has a validation signal which indicates if any names given are forbidden. My list is really bad and not representative of what I personally think are bad words by any stretch of the imagination. The beauty of this is that we don't need to know any of the details of what the view model thinks is a "bad word", but it can just provide a signal to indicate that it thinks something should be forbidden. The view model can provide signals for many things like this that it thinks are important to let you know about it. In this case all we've decided to do is show an alert view and reset the player name.

//let the upload(save) button only be enabled when the view model says its valid
RAC(self.uploadButton.enabled) = self.viewModel.modelIsValidSignal;

Another signal that the view model provides to us is a signal letting us know if the view model as it exists it valid or not. In this case i've hooked this signal to the enabled property of the upload button. So we should not be able to upload the player stats if the state of the view model is bad. The signal here is simple

-(RACSignal *)modelIsValidSignal {
    @weakify(self):
    return [RACSignal
            combineLatest:@[ RACObserve(self,playerName), RACObserve(self,points) ]
            reduce:^id(NSString *name, NSNumber *playerPoints){
                @strongify(self);
                return @((name.length > 0) && (![self.forbiddenNames containsObject:name]) && (playerPoints.doubleValue >= self.minPoints));
            }];
}

So for the purposes of this simple demo, we are just concerned if the name length is greater than 0, the name isn't in the forbidden names and the points are greater than the minimum. Really we should be concerned with more, but I won't extend it further. We could even just put the forbidden names signal in if we changed it to use map and return a NSNumber with 0 or 1 and so we could use it here inside this signal.

//set the control action for our button to be the ViewModels action method
[self.uploadButton addTarget:self.viewModel
                      action:@selector(uploadData:)
            forControlEvents:UIControlEventTouchUpInside];

The button is set to trigger the View Mode's upload data action. This method in the sample code simulates uploading something then presents an alert view letting you know about the success of uploading.

//we can subscribe to the same thing in multiple locations
//here we skip the first 4 signals and take only 1 update
//and then disable/hide certain UI elements as our app
//only allows 5 updates
[[[[self.uploadButton rac_signalForControlEvents:UIControlEventTouchUpInside]
   skip:(kMaxUploads - 1)] take:1] subscribeNext:^(id x) {
    bself.nameField.enabled = NO;
    bself.scoreStepper.hidden = YES;
    bself.uploadButton.hidden = YES;
    }];

Here since there is already signals enabling the button now the number of uploads need to be limited. This is subscribing to the signal for the UIControlEventTouchUpInside event and on the nth update where n is kMaxUploads. On the nth update the namefield is disabled, and the score stepper and upload buttons are hidden.

All of this results in a UI that just binds its properties to a view model, sets its actions to actions on the view model and receives signals from the view model indicating things of interest. I admit this particular example is a bit weird, but it demonstrates using a view model and using the basic aspects of ReactiveCocoa. There is a lot more to ReactiveCocoa in particular that I haven't shown here for the sake of not introducing too many concepts all at once. Additionally we could build some better view models for dealing with networking code and could deal with child view controllers, but that will have to wait for another article.

So what have we seen here?

  • MVVM stands for Model-View-ViewModel
  • The View model contains things like properties to bind to, validation logic and actions to be done to the view model
  • The View Model should not know anything about the UI that will bind to it
  • ReactiveCocoa is an implementation of many of the API's in Microsofts Reactive Extensions for .NET in Cocoa
  • We learned how to bind & subscribe to properties
  • We learned how to create signals

The biggest thing you can see with reactive cocoa is that all the code and signals are just reacting to events. When we chain these responses together and filter events properly we heavily reduce the need to create tons of variables and methods just to keep track of the events going on. This leads to more reliable code and with the view model we can easily test it and simulate a UI without actually having a live UI in our app.

The complete source code thats shown here is located here https://github.com/Machx/MVVM-IOS-Example.

So check out ReactiveCocoa on github, and I've provided some helpful links at the bottom to help understand these concepts. If people want i'll dive deeper into ReactiveCocoa in later articles.

Update Since first publication this article has been updated to address a couple minor issues

  • Make sure we don't retain self in blocks
  • Update a piece of code where -map could simply be used in place of -combineLatest:reduce:
  • The github sample code repo code has been updated

Thursday, August 30, 2012

Cover up those ivars

It all started with a tweet a couple mornings ago...

I completely agree with this. Objective-C has evolved over time from where everything was public and had to be included in the header files to now where only the bare minimum needs to be exposed in the header file. Now its completely bad practice to put anything in the header file that doesn't need to be exposed.

There are several Good reasons for this

When designing a class from an external point of view all I should really need to know is what your class name is and what its api's are, what I need to pass them, if anything, and what they return. When you see internal implementation details and variables there is a temptation to use them. This is bad, because you as a consumer of the class should only be concerned with what the class promises to do, and when you reach into the class to access stuff that was never really intended to be exposed you will be bitten with bugs if the implementation details ever change.

I think of methods as fulfilling contracts, I agree that I will pass them what they need if they accept arguments and they agree to return something or cause some effect (i.e. NSLog() piping text to console,etc.) As a writer of classes in a Framework, i've never been concerned about completely changing the details of how the classes work, because I have Unit Tests that test these contracts with my methods to make sure they work as advertised. It's also just cleaner design-wise and the more you can leave out of your header file the better, it makes the header file easier to read and scan for what I am looking for.

How do you do this?

Ideally the rule of thumb should be this: Expose as little as you possibly can in your header file!

This means several things: (1) If you can not declare methods in the header and instead declare them in a class extension in the implementation file(.m) do it (2) If you need to expose properties make them readonly if possible (3) if you need to have ivars declare them right after the @implementation declaration. This doesn't mean hide everything all the time, but generally I like to think of this as designing a class and then only putting in the header file what needs to be exposed to make the class useful.

Here is a class extension

@interface MyClass()
-(NSUInteger)somePrivateMethod;
@end

Here is an example of declaring a method in a class extension. Class extensions are like categories, except that a class extension really just extends the @interface section of a class declaration in another location, so unlike a category if you declare a method and forget to implement it, the compiler will warn you.

If you need to declare properties try to hide them in your extensions, if you need to make them public, make them readonly if possible. This still gives people access to them, but prevents them from doing anything with the variables and screwing up your class. Like so

@interface MyClass : NSObject
@property(readonly, retain) NSString *currentPath;
@end

then in your implementation file you can redeclare it with read & write capabilities. 

@interface MyClass()
@property(readwrite, retain) NSString *currentPath;
@end

This way, publicly you can give people access to bits of information about your class, but only have rights to change them in the implementation. You can also use these extensions to declare properties that are only used in the implementation file.

Another way of declaring variables that didn't exist till very long ago is to do so only after the @implementation declaration like so

@implementation MyClass {
    NSString *internalVar1;
    NSNumber *internalVar2;
}

this is equivalent of 

@interface MyClass : NSObject {
    NSString *internalVar1;
    NSNumber *internalVar2;
}

@end

 except now that this isn't in your header file polluting it. 

How do my Subclasses use these vars?
A legitimate question that someone asked me this afternoon was essentially "If my class hides all these variables in extensions, how could I ever use them in subclasses?" Thats very worth asking. In this case instead of declaring these variables in a class extension in the implementation file you would create a "MyClass_private.h" file where the class extension is. Then your .m file and any interested subclasses can import this header in their implementation files and use it. I would even go so far to write methods into your class such, that to the extent possible, you don't even need to access these internal only vars in your subclasses. 

Why Does this matter if its code just for me?
A couple people asked me this. All I can really ask is why would you write bad code just for yourself? Nobody writes perfect code, well maybe except for me(I kid I kid), but you're not me. But why would you write intentionally bad code for yourself? I always write my classes using these principals, even for stuff thats just for play. Well designed classes means not having to spend tons of time ripping & rebuilding them just to make them presentable later on, it means you can instantly take them and use them in anything without much worry. 

In Conclusion
The less you expose in your headers the cleaner they are, they become easier to read, they don't expose anything that could become future bugs or crashes later on. This makes it easier for you to completely rewrite or change implementation details at will.  

Follow Up
Rich in Comments makes a good point about also putting IBOutlets & IBActions in class extensions. When I said to hide vars and methods I also meant these. The IB component in Xcode iirc didn't see those initially. However for a while now it can see IBOutlets and IBAction methods declared in Class Extensions.

When I said that some of this is "new" in this article, generally I mean in the grand scheme of Objective-C's history at Apple it's new.

Eric made a good point, and I saw and forgot about this in the WWDC videos, that in LLVM Compiler 4.0 its no longer necessary to declare private methods as the compiler scans the implementation for those methods and thus won't give you an error if you forget to declare it.

I was asked if I put my ivars in a class extension or declare after the implementation, generally I declare them in my class extensions.

Tuesday, January 31, 2012

Clang Source Annotations

Recently I was faced with a dilemma. I was writing code I needed, and then I triggered a Clang Static Analyzer issue. Here is the code a category on NSColor, see if you can figure out whats wrong with it from a Static Analyzer perspective...

-(CGColorRef)cw_cgColor { 
NSColor *nscolor = [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
CGFloat components[4];
[nscolor getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]];
CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGColorRef cgColor = CGColorCreate(space, components);
CGColorSpaceRelease(space);
return cgColor;
}

While all the code here is perfectly valid, and converts a NSColor to a CGColorRef just fine, the Clang Static Analyzer will trigger an issue on the last line. Why? Because of this

CGColorRef cgColor = CGColorCreate(space, components);

We've created a Core Graphics or Core Foundation object with a create method which means it needs to be freed later on. However we are just returning that object in this method so the compiler has no way to really know that we will free this object later on. If only there was a way to let the Clang Static Analyzer know that whoever calls this needs to free the object and therefore this code isn't leaking.  Well there is, its called Source Annotations. All I did was add CF_RETURNS_RETAINED to the end of the method declaration in the header file and the Clang SA issue went away. So now the declaration looks like

#import <AppKit/AppKit.h>
@interface NSColor (CWNSColorAdditions)
-(CGColorRef)cw_cgColor CF_RETURNS_RETAINED;
@end

This says to the Clang Static Analyzer whoever calls this method will be receiving a Core Graphics object thats retained and therefore the caller needs to free it when its done. I could have also put 'create' or 'copy' in the name of the method, but I wanted it to be nearly identical in name (remember always prefix your names of methods where your extending Apple classes, cw_ is mine in this case) to the name of the CGColor property on UIColor. This is not the only annotation, but if you haven't seen Clang Annotations, you should see whats available for when you run into issues trying to convey to the Clang Static Analyzer what your code is doing.

Clang Static Annalyzer Source Notations http://clang-analyzer.llvm.org/annotations.html The above code is from my Zangetsu Framework

Enjoy.

Thursday, April 07, 2011

Singletons: You're doing them wrong

This post feels a bit odd, as generally I fully agree with Dave Dribin on how wrong singletons are and that you should avoid them if possible. However on Stack Overflow i've seen far too many people write bad code that is horrible for several reasons.

Basic Example

Singletons are fairly easy to create. Here is a basic example...

+(MyClass *)singleton {
 static MyClass *shared = nil;
 
 if(shared == nil) {
  shared = [[MyClass alloc] init];
 }
 return shared;
}

However this is wrong on several levels. Firstly, this isn't thread safe, so what happens if multiple threads all try to access this at the same time? There is no reason 1 thread couldn't be in the middle of allocating the object while the other one is trying to access the object. This is actually what Apple shows in its documentation.

If you must use singletons, use dispatch_once()

dispatch_once() solves the problem of safely being able to create a singleton in that (1) it guarantees that the code in the block will only be called once for the lifetime of the application (2) its thread safe as I noted in a previous article and (3) its faster than other methods like using @synchronize(),etc...

"If called simultaneously from multiple threads, this function waits synchronously until the block has completed."

So you should be writing it like this...

+(MyClass *)singleton {
 static dispatch_once_t pred;
 static MyClass *shared = nil;
 
 dispatch_once(&pred, ^{
  shared = [[MyClass alloc] init];
 });
 return shared;
}

This is a safe way to create a singleton. There is no way to accidentally create it twice, its fast and it is thread safe.

Conclusion

Avoid singletons if at all possible because it is easy to abuse them. Unlike Dave Dribin I don't think they are evil, but I really try and avoid them when possible. If you must create them, do it right and don't create them like the first example, use dispatch_once(). It is less code and the correct way to do it.

Wednesday, March 09, 2011

Xcode 4 Keyboard Shortcuts now available!

Xc4 kbsc

The Xcode 4 Keyboard Shortcuts are now available. I've decided to make forking it and creating your own version easier by putting it up on Github. This will make it easier to browse forks and merge new formats in. Additionally it makes it easy to have a consistent go to place that doesn't change for updates to the shortcuts.

You can download the Xcode 4 keyboard shortcuts here:
Xcode Keyboard Shortcuts Repository
Xcode 4.0 Keyboard Shortcuts (Blue)
Xcode 4.0 Keyboard Shortcuts (Black and White)

Believe it or not I got a few requests to actually charge for the shortcuts. For something like this, it is just not my style, but if you want to contribute maybe so I can afford some better tools than pages or spend more time on maintaining them and updating them faster, then you can donate whatever you feel like here http://pledgie.com/campaigns/14858.

Wednesday, February 23, 2011

Practical Design Patterns with Blocks and Grand Central Dispatch

Introduction

When Mac OS X 10.6 was introduced, the Mac got a very powerful duo of developer tools that made development on a lot easier. With iOS 4.0 developers finally got access to these tools as well. These tools are known as Blocks & Grand Central Dispatch. This article is not an introduction to these technologies as i've already covered them before here http://cocoasamurai.blogspot.com/2009/09/guide-to-blocks-grand-central-dispatch.html. What this article is, is a introduction to some design patterns I use and have seen other developers use in 1 handy article.
Many of the design patterns I am displaying here are actually in use in my Zangetsu Framework which is open source under the MIT License on Github.
Iterative Callbacks
/**
 Ruby inspired iterator for NSArray in Objective-C
 */
-(NSArray *)cw_each:(void (^)(id obj))block
{
    for(id object in self){
        block(object);
    }
 
    return self;
}
Blocks are really good for doing callbacks and one of the things you can do already is enumeration. Now while Objective-C is definitely expressive with high level english like syntax, sometimes it is unnecessarily verbose in my opinion. When I started reading through my Ruby 1.9 book one thing I loved was ruby's enumeration with each. It's so simple and while it could be slightly more verbose it's succinct enough. So I decided to implement each in Objective-C with blocks since I could actually make it work. The result is what you see above.
Additionally you can use grand central displatch and make this asynchronous.
-(NSArray *)cw_eachConcurrentlyWithBlock:(void (^)(id obj))block
{
    dispatch_group_t group = dispatch_group_create();
 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
    for(id object in self){
  
        dispatch_group_async(group, queue, ^{
            block(object);
        });
    }
 
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_release(group);
 
    return self;
}
In this example I am using dispatch groups and getting a reference to a global queue and then basically enumerating over the objects and then calling dispatch_group_wait() to make sure that all the blocks complete. This type of thing is great when you want to be both asynchronous, but also ensure that the method itself is synchronous.
/**
 Simple mapping method using a block
 */
-(NSArray *)cw_mapArray:(id (^)(id obj))block
{
    NSMutableArray *cwArray = [[NSMutableArray alloc] initWithCapacity:[self count]];
 
    for(id obj in self){
        [cwArray addObject:block(obj)];
    }
 
    return cwArray;
}
Here is a good example of putting that callback capability to good use. In this example I wanted to map one array to another one. This is basically exactly the same as my cw_each method above except that inside this method I am creating an array that the new (mapped) array is being stored in and returning an object from the block. If you wanted to you could be selective in mapping an array to another by simply checking that the object returned from the block is not nil and only then adding it to an array you are mapping to.
Enclosing Blocks
Another clever use for blocks is to enclose them in between other code for various purposes. For example in this case I was experimenting with only executing a block when I am building debug code. So instead of doing...
#ifdef DEBUG
    NSString *myString = ...
    //do something with string
#endif
I think this is more clear and less cluttered
//in .h
typedef void (^DebugBlock)(void);
void CWInDebugOnly(DebugBlock block);

//in .m
void CWInDebugOnly(DebugBlock block)
{
#ifdef DEBUG
    block();
#endif
}
This way in code I can do
CWInDebugOnly(^{
    NSString *myString = ...
    //do something with string....
});
This relies on DEBUG being defined only in your debug builds. I have this set up to only be defined in my Debug and Analyze configurations. I've also seen Mike Ash cleaverly do this exact same thing with NSAutoreleasePools like so...
//in .h
typedef void (^VoidBlock)(void);
void inAutoreleasePool(VoidBlock block);

//in .m
void inAutoreleasePool(VoidBlock block)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    block();
    [pool drain];
}
Completion Blocks
Completion Blocks are especially good things to have around. They are very useful on objects that are performing some operation, usually asynchronously, and we would like to know when the operation has been completed. We may or may not care about the implementation details, but we need a mechanism to do something when this is done. This is where completion blocks are excellent helpers. In the past before blocks we may have used notifications or delegates and created methods especially to deal with this 1 specific application. Now it's as easy as assigning a block as a variable and executing it when you are done. One prime example of this is NSOperation. You can create it, add it to a queue, and go on and do other things, and once the operation is done it executes your completion block. These completion blocks are also excellent because we can do these things on threads in grand central dispatch and simply in the completion block dispatch back to the main thread and update the user interface
NSData *data = //..data from a file or internet
MyOperation * operation = [[MyOperation alloc] initWithDataToParse:data];

[operation setCompletionBlock:^(NSString *result){
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [self updateUIWithString:result];
    }];
}];

[queue addOperation:operation];
This code is easy to read and follow what it is doing. Let's see how we can do this in our classes.
//.h
typedef void (^TaskCompletionBlock)(void);

@interface MyClass : NSObject {}
@property(nonatomic,copy) TaskCompletionBlock block;
-(void)doTask;
@end

//.m
@implementation MyClass

@synthesize block;

-(id) init
{
    self = [super init];
    if(self){
        //
    }
    return self;
}

-(void)doTask
{
    //do some task here...

    if(self.block) {
        self.block();
    }
}

@end
Dispatch_Once
Out of all the API calls I saw in grand central dispatch the one that initially impressed me least was dispatch_once. However after reading its documentation and using it a bunch I realized how useful this one API call is. Not only it is a dead simple way to ensure that code only gets executed once, but it is also thread safe. From the API...
"If called simultaneously from multiple threads, this function waits synchronously until the block has completed."
This means its perfectly safe to run code like this from multiple threads...
+(NSString *)coreDataKeyNameForWebAPIKey:(NSString *)name
{
    static dispatch_once_t dictPrec;
 
    dispatch_once(&dictPrec, ^{
  
        coreDataKeyMappings = [[NSDictionary alloc] initWithDictionary:NSDICT(
            kCDEntityNameKey,           kWebEntityNameKey,
            kCDEntityDateKey,           kWebEntityDateKey,
            kCDEntityTimeStampKey,      kWebTimeStampKey,
            KCDEntityUpdateKey,         kWebEntityUpdateKey)];
    });
 
    NSString *translatedKey = [coreDataKeyMappings valueForKey:name];
 
    return translatedKey;
} 
Conlcusion
Grand Central Dispatch and Blocks are just awesome. Even just blocks by itself makes many things possible that weren't before. With grand central dispatch and blocks many problems that have been traditionally associated with multithreading go away. These 2 technologies don't eliminate all these problems, but they certainly do make them much more manageable.

 
...