You are browsing the archive for iOS.

Avatar of marc

by marc

Letting Oxygene and RemObjects SDK wake you up in time for WWDC

April 3, 2013 in .NET, Cocoa, Elements, iOS, non-tech, Nougat, WWDC

On Monday, it being a holiday and all, i found myself with a free half hour before dinner and so i decided i’d write a small little application with Oxygene that can both serve as an example for some cool technology interaction, and also does something useful for me: a Client/Server app that monitors the Apple WWDC webpage for changes and notifies me via Push Notifications on my iPhone when the page changes.

The whole thing was literally done and up on GitHub in about twenty minutes, start to finish (writing this blog post will probably take longer than writing the app ;), and i figured i’d give you a rundown of what it does, how it works and how i did it.

I started by going to developer.apple.com and setting up a new App ID with a Push Notification certificate. Any app using Push Notifications needs a unique, non-wildcard ID, so i could not just use one of my existing IDs and profiles.

After downloading the profile and the new Push Certificate, i exported it from Keychain Access as a .p12 file without password protection (to keep things simple).

(The .p12 file is the only piece missing from the WWDCNotify distro on GitHub. You must create your own to run the app, or else we’d get our streams crossed when more people run the app with the same certificate.)

Next, i created the server app. I wrote that in .NET, so i can use Mono to either run it locally on my Mac, or i move it to one of our Linux servers on EC2, if i wanted to.

I started with the RemObjects SDK for .NET new project wizard. The server is really simple, as it doesn’t define any of its new services, it just links in our open source Apple Push Provider (source on GitHub), which provides two pieces of core functionality needed for Push notifications on the server:

  1. It provides the APSConnect class that encapsulates the protocol for submitting notifications to Apple’s servers.
  2. It provides a ready-to-go RemObjects SDK Service that clients can call to register for notifications — along with all the infrastructure to manage the list of registered devices.

Nothing but these few lines of code are needed to set up the Push service:

var lCertificatePath := Path.ChangeExtension(typeOf(self).Assembly.Location, 'p12');
PushDeviceManager.DeviceStoreFile :=  Path.ChangeExtension(typeOf(self).Assembly.Location, 'devices');
PushDeviceManager.CertificateFile := lCertificatePath;
PushDeviceManager.APSConnect.ApsHost := 'gateway.sandbox.push.apple.com'; // for this app, we're staying in the sandbox
PushDeviceManager.RequireSession := false;

I tell the PushDeviceManager.RequireSession the path to the .p12 file (which i included in the project and set to be copied next to the .exe), the file to store the registered devices in (again, it goes next to the .exe to keep things simple), the URL of the Apple Push Server, and finally i tell it to not bother with requiring clients to authenticate.

And with that, the server is done and ready to let clients register for push notifications…

Of course there are no notifications being sent yet. To handle that, i created a quick static class that uses a timer that fires every five minutes. When that happens, it downloads the content of the website and compares it to the previous version:

var lNewWebsite: String;
using lClient: WebClient := new WebClient() do 
  lNewWebsite := lClient.DownloadString(URL);

if assigned(fLastWebsite) and (fLastWebsite ≠ lNewWebsite) then begin
  …

If that is the case, it will send a notification with message and sound to all registered clients:

for each d in PushDeviceManager.Devices.Values do
  PushDeviceManager.APSConnect.PushCombinedNotification(d.Token.ToArray, 'ALARM ALARM! The WWDC Website has changed', 0, 'default');

It’s that simple.

Because i have a mild case of OCD, i also made the server send a regular notification without sound (every few hours), to assure me that the service is still running. And on startup, it will also send a notification that the server has been (re)started — again really just to set me at ease that everything is working, when launching or re-deploying the server.

Ok, if you think “well, that was easy”, wait till we get to the client. I added a second project to the solution, this time an iOS app based on the Simple App template — which does nothing but show an empty view. (For completeness sake, i went into Interface builder and made the empty view show the Default.png image, instead of just a white screen.)

To communicate with the server, i imported the interface file for our Push Server by going to the RemObjects SDK|Import Service menu and choosing the RODL file from the Push project above (i could also have pointed it to the URL of the running server instead).

Literally all the code that drives the app is in the AppDelegate class:

In application:DidFinishLaunchingWithOptions:, we add one line of code:

application.registerForRemoteNotificationTypes(UIRemoteNotificationType.UIRemoteNotificationTypeAlert or
                                               UIRemoteNotificationType.UIRemoteNotificationTypeSound)

to let the OS know we are interested in notifications, and want alerts and sounds.We then implement two callback functions that will be called either if registration for push was successful, or if it failed (which will happen when running it in the simulator, for example). application:didRegisterForRemoteNotificationsWithDeviceToken: and application:didFailToRegisterForRemoteNotificationsWithError:.

When registration fails, we simply show an alert view with the error message.

The success case is more interesting:

method AppDelegate.application(application: UIKit.UIApplication) didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Foundation.NSData);
begin
  var p := new ApplePushProviderService_AsyncProxy withURL(new NSURL withString(URL));
  p.beginRegisterDevice(deviceToken, UIDevice.currentDevice.name) startWithBlock(method (aRequest: ROAsyncRequest) begin
      p.endRegisterDevice(aRequest);
      var lAlert := new UIAlertView withTitle('All set!') 
                         message('You are registered for Push Notifications!') 
                         &delegate(nil) 
                         cancelButtonTitle('Okay!') 
                         otherButtonTitles(nil);
      lAlert.show();
    end);
end;

Here we do an async call to the RegisterDevice function exposed by the server, passing the deviceToken we received (this is the token the server will hold on to and use to later send a message to our device). We pass a block that gets called back when the call was successful and — just for completeness — we show a message that everything went well when that happens.

And that’s it. I run the server with “mono WWDCNotify.exe”. Run the client app once to let it register, and then forget about it.

Avatar of marc

by marc

Cocoa/CoreFoundation Bridging Explained

April 2, 2013 in Cocoa, Elements, iOS, Nougat, Xcode

“Bridging” is a new language feature introduced to Objective-C alongside ARC, that i believe is not very widely understood, at least not fully.

Cocoa always had the ability to “toll-free bridge” between Cocoa objects, such as NSString and their underlying non-object-oriented CoreFoundation equivalents, like CFStringRef. Before ARC, you could just cast back and forth between them as you pleased, but ARC made the rules a bit stricter, and Objective-C introduced new “bridge casts” to formally express these toll-free bridge casts in an ARC-safe manner. Oxygene also supports these casts, with the bridge<T>() compiler magic function.

Questions?

So how do bridge casts work, when do you need them, and what is the difference between the three distinct types? That are questions that i think a lot of people are confused about. I’ll admit i myself wasn’t quite sure what the differences and implications of “bridge” vs. “transfer” vs. “retain” were, until Carlo and i sat down the other day to really formalize how we would properly expose them in Oxygene (and thus had to understand them really well ;)).

As most Objective-C developers who use ARC will know, the answer to the middle question is the easiest. When do you need a bridge cast? Simple: every time you want to go from a Cocoa object to a CoreFoundation entity or back. You know this, because the compiler will tell you by refusing to compile code that was perfectly fine in pre-ARC, such as:

NSString *s = (NSString *)myCFString;

Instead, you now need to write:

NSString *s = (__bridge NSString *)myCFString;

Or do you? The answer is, it depends. As i mentioned before, there are three different types of bridge casts, and it is important to pick the right one (lest you will end up in the land of chasing down memory leaks and weird crashes, once again).

I say there are three types, but you can really think of them as two groups of casts.

“Regular” Bridge Cast

First, there’s what i like to think of as the “regular” bridge cast. In Objective-C that’s expressed with the __bridge keyword; in Oxygene, it’s the default when calling bridge<T> without a BridgeMode enum value (or with BridgeMode.Bridge, the default):

Objective-C

UIColor *u = [UIColor redColor];
CGColorRef c = [u CGColor]
id o = (__bridge id)c;
[u set]; // or something else that keeps "u" around.

Oxygene

var u := UIColor.redColor;
var c := u.CGColor
var o := bridge<id>(c);

You can think of this as making the original item (a CGColor) available “on the other side” (as featureless “id”, in this case, as CGColorRef is not toll-free bridged to a Cocoa class), without affecting the original.

The original ownership of the CGColor remains with the UIColor object it was obtained from. The cast object is merely a second view onto the same item, in a different form.

The “regular” bridge cast works both ways — going from a Cocoa to a Core Foundation, or the other way around.

Transfer/Retain Bridge Casts

The second type of casts are the transfer/retain bridge casts casts. I lump them together because they form two sides of the same coin. Different than the regular bridge cast, they do not work in both directions; instead, the transfer bridge cast can be used when going from CoreFoundation to Cocoa, and the retain bridge cast when going the opposite way, from Cocoa to CoreFoundation.

In Objective-C that’s expressed with the __bridge__transfer and __bridge_retained keywords; in Oxygene by calling bridge<T> with a BridgeMode.Transfer or BridgeMode.Retained value.

Why this distinction is necessary will become clear soon, but first let’s look at an example:

Objective-C

CFStringRef c = CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding());
NSString *s = (__bridge_transfer NSString)c;
c = nil;

Oxygene

var c := CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding());
var s := bridge<NSString>(c, BridgeMode.Transfer);
c := nil;

As the name implies, the transfer cast transfers the item, and its ownership, to the other side. After the cast from the CFStringRef to an NSString, the NSString (stored in “s”) is the only true owner of the underlying string. The original CFStringRef is no longer relevant, and as you see, we do not (must no) free it.

Essentially, the transfer cast says, “give me a Cocoa object, and then let’s forget the CoreFoundation thing ever existed”.

This is highly useful when writing more concise code. In the example above, we could have used a regular bridge cast, and simply called CFRelease(c) afterwards and everything would have been fine. But imagine the same example written as a single line of code:

Objective-C

NSString *s = (__bridge_transfer NSString)CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding());

Oxygene

var s := bridge<SString>(CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding()), BridgeMode.Transfer);

Here we have no reference to the original CFStringRef object, so the transfer cast is essential.

Conversely, you can imagine that using the transfer cast on the CGColor example above would be disastrous. The Original CGColorRef is owned by the UIColor we received it from; we’d have no right to transfer it and invalidate it underneath the UIColor’s feet. Things will crash, eventually. (In fact, a bug report with just this problem that we received from a tester of Oxygene was what promoted me to write this post ;)).

At this point, you might already begin to understand why transfer bridge casts can only work one way in an ARC language and why on the flip side the retain bridge casts is needed:

Objective-C

NSString *s = [NSString stringWithFormat:"hello, %@", name];
CFStringRef c = (__bridge_retained CFStringRef)s;
...
CFRelease(c);

Oxygene

var s := NSString.stringWithFormat('hello, %@', name);
var c := bridge<CFStringRef>(s, BridgeMode.Retained);
...
CFRelease(c);

When we used transfer bridge casts above, a true transfer happened; the CoreFoundation reference was no longer valid, and we did release it. Going the other way, we do not have this luxury: The original Cocoa object (a string in this case) is managed by ARC, and there is no way to not release it. If a true transfer bridge cast were allowed, ARC would go ahead and over-release an “invalid” object. And that cannot happen.

Instead, the retained bridge cast does the next best thing. It gives us back a CoreFoundation entity we fully own (and have to release), and it leaves the Cocoa object untouched.

You can think of the retain bridge cast as “just like the transfer, but leaving the source object for ARC to deal with”.

When to Use What?

The answer to this question will not always be clear-cut, but a good rule of thumb is to use the regular bridge cast — i.e. __bridge or bridge<T>() w/o mode — when you do not own the original item and/or are merely “borrowing” it to be used on the other side. Use the transfer/retain bridge cast when you do own the original object and want to take ownership of it “on the other side”.

So How Does this Work Under the Hood?

To be honest, you probably don’t really want to know, or at least not think about it, because what the bridge casts do under the hood can be really confusing how you think of them on the higher level.

Let’s start with the transfer bridge cast. It essentially does “nothing”, just as the regular cast would have done before ARC; it converts the pointer type and that’s it, and it does not affect the retain count of the object at all.

Because of how ARC works under the hood, it assumes ownership (or a +1 retain count, if you will) of the Cocoa object pointer and this affectively acts as if the original CoreFoundation object had been released (i.e. gotten a -1 on its retain count). The actual retain count of the item has not changed, but ARC now has staked claim on it.

The regular bridge cast is essentially the same as the transfer, except it does an extra retain on the resulting object when going from Core Foundation to Cocoa. This way, ARC can deal with the object (and eventually release it again). But the underlying CoreFoundation reference is unaffected and keeps its own claim on the entity. When going from Cocoa to CoreFoundation, it does nothing — because ARC is not involved in handling the life cycle of CF objects, it can just pass the original object off as an unowned entity.

Finally, the retain cast works much like the regular bridge, but does an additional retain on the item, before the cast. This way, the original object reference remains retained, and the resulting CF entity is owned (i.e. needs to be freed) as well.

The thing to keep in mind is that there’s a single retain/reference count for each entity. It’s really just a sleight of hand on the compiler’s side how the bridge casts “move” the ownership around between the Cocoa and CoreFoundation references.

But as i said, you probably want to forget about these implementation details, and just think of these bridge casts in the logical terms described above ;).

Summary

I hope you found this article useful and that it helped to provide some insight into the different bridge cast types on the Cocoa platform. Let me know what you think!

Avatar of marc

by marc

“The Truth is in the Cloud” — Why iCloud Data is Failing You, and How Data Abstract can Help.

March 27, 2013 in Data Abstract, iOS, Mac

The past few weeks, everybody has been complaining about iCloud. Or more precisely, they have been complaining about a small subfeature that is crucial to app developers: Core Data syncing via iCloud. Developers are concerned that data syncing via iCloud is difficult and unreliable, and that when things go wrong (and the invariably will), they have little to no recourse to investigate or debug the issues.

Frankly, i’m not surprised about these issues, because from where i stand, Core Data in iCloud uses a fundamentally wrong approach that can only fail. Let’s see how that is so.

Do you remember when Steve Jobs took the stage at WWDC a couple of years back and introduced iCloud? It was going to be better than all of Apple’s previous cloud services, and to explain the reason why, Steve used one catch phrase: “The truth is in the cloud”. Developers rejoiced and gave a standing-o — and rightfully, because Steve was correct.

For a cloud service to work reliably, the “truth” — that is, the authoritative representation of what your data is — needs to be in one central place. The cloud.

And Steve was not lying to us. That claim he made is true for most of iCloud, and if we’re honest, iCloud is working pretty well for most of the services it provides. Cloud-based documents work great. Cloud-based settings (the Key-Value-Store) work great. All the non-developer features of iCloud (Calendar/Contacts, Backups, heck, even things like iTunes Match) work pretty well. The only thing that is causing developers (and by extension, users) headaches is “Core Data in iCloud”. Why is that?

It’s because Core Data in iCloud violates the core promise Steve made about why iCloud is better. Core Data’s truth is not in the cloud. Instead, Core Data merely uses iCloud as a dumb conduit to sync data back and forth between the different devices a user runs your app on — and leaves the onus for sorting out the sync to the individual devices.

And as we all know, “syncing is hard”. And worse, syncing is impossible, if the app doing the syncing has no control over the data flow (for example when the user disables iCloud for a while), and the developer has no way to debug what is going on.

If 15+ years of working with networked data and disconnected clients has taught me anything, it is that this is an unsalvagable situation. In order to have data in your apps and reliably reproduce and “sync” it between multiple devices, you need to take control of that data, and have a single truth source — ideally in the cloud.

It just so happens that here at RemObjects Software, we have spent the past 10 years thinking about these problems, and have developed a technology and libraries around it that solve them.

This blog post is less about selling you on Data Abstract (although i of course hope that you will have a look at it), and more about showing how taking control and hosting your own data will solve your problem in ways that Core Data in iCloud can not — and give your app additional capabilities, to boot. So i will look at this from the perspective of using Data Abstract, our product, but many of the ideas covered will be applicable just as well, should you decide to “roll your own” or use a different infrastructure.

What is Data Abstract?

Data Abstract is a combination of a client library that you link into your iOS or Mac application (it is also available for other platforms), and server-side infrastructure in form of our free Relativity Server.

One of the “downsides” of giving up Core Data/iCloud is that you will need to look at hosting your own data. That seems like a daunting task, but is really not as difficult, or as costly as it might seem. And in fact, you will come to see it as an upside in the long run.

To get started, in most cases a tiny and cheap Amazon EC2 server instance will do the job — we’re talking monthly costs of around $20 or so. This will be enough to handle the initial load of most apps — and of course, if your app sells really well, the extra costs for upgrading the specs, or “scaling out” to more than one server will be peanuts to you, anyways ;).

Setting up the server is really simple. Most Linux servers you can rent or host, including EC2, already come with a database such as mySQL or PostgreSQL (we use the latter a lot, ourselves). All you need to do is install our Relativity Server, and you’re set. You can of course also use Azure, or other more traditional hosting solutions (and we are working on providing a ready-to-use EC2 image that will let you get set up with this even quicker, soon).

You can then design your database as you see fit, and Relativity Server lets you expose the data to your client applications — you decide what tables get exposed and who can access what, and you can write custom logic to control and influence data access and updates via JavaScript. The Relativity Server Explorer makes this easy and visual.

On the client side, Data Abstract is an easy-to-use static library that you can link into your application, and it will handle all the data access for you. The library is built on modern Cocoa principles, for example it uses GCD blocks to handle network access in the background, making it easy to keep your app responsive. Also, it is designed from the ground up for offline data, meaning you do not need to spend a lot of effort worrying about what happens when your user loses network connection — they can work with data while on a plane, and sync back up later when they get back online.

We have a lot of development topics around DA and Relativity server covered in our documentation Wiki, a good starting point is this page: Developing Database Applications for Mac and iOS.

In addition to providing all that Core Data/iCloud promises (but reliably), hosting your own data also provides additional benefits that cannot be achieved (by design) with iCloud data, even if it were working perfectly otherwise:

  • In addition to each user having their own private data, your app can share data between users, where applicable — be it between individual users, or publicly with all users.
  • You can build apps for other platforms, including Android, Windows, or Mac apps not sold in the Mac App Store, that share the same data. (Data Abstract has dedicated libraries for creating native apps for both Android and Windows, as well.)
  • You can build a web front-end for users to view their data, either via server technologies such as ASP.NET, or client technologies such as a pure JavaScript based browser client. (Again, Data Abstract provides libraries for both, and our library for JavaScript is even completely free.)
  • Most importantly, though, you as the app developer are in full control of the data. If one of your users calls you and says that something is wrong with their data, you’ll know exactly where to look.

Summary

I hope you found this article interesting, and that is has given you a fresh take on the intricacies of adding data “syncing” to your app — on iOS and elsewhere.

The key point i hope you will take a way from this is that Core Data in iCloud, being essentially a client-to-client sync mechanism, just like MobileMe and others before it, is fundamentally flawed, so that the myriad of problems many developers are seeing are hardly surprising. And that the solution to that is taking control of your own data, and hosting it with a single “truth in the cloud”.

I’d be lying if i said i didn’t hope you would consider using Data Abstract as your solution for this problem. We’re a small team of developers dedicated to this problem, and i believe we have a great and unique solution to it that provides a lot of benefit and can save you a lot of time and resources. Data Abstract sells as developer license, with no deployment costs or royalties.

Let us know what you think!

Whatever solution you choose, we wish you best of luck with your data-driven apps, and are looking forward to what you’ll produce!

Yours,
marc hoffman

Chief Architect,
RemObjects Software

Avatar of marc

by marc

Creating a Turn-Based Game for iOS: Nougat Tic-Tac-Toe

March 11, 2013 in Elements, iOS, non-tech, Nougat, Oxygene, Visual Studio, WWDC, Xcode

Over the past couple of weeks, i have been working on a new sample project for Oxygene “Nougat” on the side. After having gotten Browse500 into the App Store in January and showing how to reimplement a simple native UIKit control from Objective-C in Nougat last month, i wanted to create another example that illustrates the benefits of how Nougat interacts directly with the native APIs, and i picked a technology i knew nothing about at all to do so: Game Center.

I’m not a big gamer; i don’t find myself playing games much, and i have certainly never written one before, so this was a great opportunity to explore something new.

For those of you not familiar with it, Game Center is a technology Apple ships in iOS (and now also Mac OS X) that allows for games to interact across the network to create multi-player games, and to keep track of achievements. Game Center is not about graphics, or game UI, or anything of the sort (there’s other frameworks for that), it’s only for bringing players together.

I decided to create a simple turn-by-turn game, that is, a game where multiple players (in this case two) can interact, but only one player is active at a given time. Once a player has made their move, it’s the next player’s turn. To keep things simple, i picked a game that everybody knows and that is dead simple to implement, game playing wise: Tic Tac Toe. This way, having to explain the game itself won’t get in the way of the sample code.

To start with, i had to dig myself into the Game Center documentation and i watched a couple of videos on Turn-by-Turn gaming from WWDC 2011 (sessions i didn’t attend at the time). As it turns out, the API for interacting with Game Center for such a game is surprisingly easy and straightforward, and i was up and coding in no time.

Before we get started looking at the code, let’s look at the prerequisites:

  • Here’s the amount of effort anyone from the Oxygene team had spent on thinking about or working on making GameKit (the framework for interacting with Game Center) available to Nougat, before i started this endeavor: 0. Nada. Nil.

  • Here’s the amount of legwork i had to do before i could work with the GameKit APIs, just like every other Cocoa developer would: i added a reference to GameKit to my project. Done.

That’s it. No begging someone to translate header files, or waiting for someone to create a crappy abstraction wrapper class. Add a reference, and use the APIs as Apple intended them — that’s the way development should be.

The Code

Let’s dive into the code.

First of all, the full code of Tic-Tac-Toe is included in the latest Nougat beta, and it’s also available in my Github account for anyone to explore.

There’s really three separate parts that are of interest as a sample project in this app:

  1. The GameKit integration
  2. The game board, implemented as a custom UIControl
  3. The computer player algorithm, generously provided by my good friend and long-time Oxygene user, Jeremy Knowles.

Let’s look at GameKit first.

Working with GameKit

There’s four main classes or concepts that you will work with for GameKit.

The first is the local player, a singleton object that can be obtained via a call to GKLocalPlayer.localPlayer. This objects provides the game with information about the local player — most importantly their ID, and whether the local player is in fact registered and authenticated with Game Center or not. If the player is not set up for Game Center, Tic Tac Toe will simply disable the appropriate UI and just allow local vs. computer game play (although it would be possibly for a game to provide a signup UI, if so desired).

Next is the GKTurnBasedMatchmakerViewController, which provides access to the standard GameCenter UI. It gives the user access to any and all games they might already have going on, as well as the chance to start a new game. In Tic-Tac-Toe, i make this UI available via a button in the navigation bar, and all that’s needed to show the view is code like the following:

var request := new GKMatchRequest;
request.minPlayers := 2;
request.maxPlayers := 2;
 
var mmvc := new GKTurnBasedMatchmakerViewController withMatchRequest(request);
mmvc.turnBasedMatchmakerDelegate := self;
mmvc.showExistingMatches := true;
presentViewController(mmvc) animated(true) completion(nil);

This code brings up the Game Center UI, with the list of games (if any) or straight with the “Start New Game” (if not). Via the GKMatchRequest, we force the number of players to exactly two. (Game Center itself allows games for up to 16 players):

Tic Tac Toe Game Center

The way Game Center works for starting new games is that it lets you either invite a known friend who also plays the game or — much more interestingly — auto-match you with another random player. One thing that’s cool is that after starting a game, it will always be your turn — you will either be thrown into another game that was started earlier by a different user, or you will get to start a fresh game, depending on what games are currently live and waiting for players. If you start a fresh game, you get to make your first move, and then and only then does Game Center go out and try to find someone for you to play with.

Going back to the code level, what we are looking out for is a callback on the turnBasedMatchmakerDelegate that we assigned above. Our root view controller class implements some 4 methods from the IGKTurnBasedMatchmakerViewControllerDelegate interface, and the match-maker view controller will call us back on these when interesting things happen. This is a very common pattern in Cocoa, and is how the platform handles “events”.

In particular, the callback we care about for starting a new game is:

method turnBasedMatchmakerViewController(aViewController: GKTurnBasedMatchmakerViewController) 
       didFindMatch(aMatch: GKTurnBasedMatch);

This method actually gets called any time the user picks a game in the Game Center UI — whether they are starting a new game, or selecting an existing game. This is neat, because it means we can leave all the game management to GameKit, and don’t need to keep track of ongoing games ourselves.

This callback receives the third important class, a GKTurnBasedMatch. “All” we need to do when this method is called is load the passed match as the active game. In the Tic-Tac-Toe app, we do this by calling our own loadCurrentMatch() method, which does all the heavy lifting.

Every match contains a binary blob in the matchData property that describes the current game state. The content of this binary blob is entirely up to our game, but we can use it to store up to 4KB of data, and this data will automatically be passed between all the participants as they take their turns. In turn, our Game will read the data, let the active player make their move, and then store the updated game state, as we will see in a few moments.

Loading a Game

Loading a game is done with two method calls, first, a a small helper function loads the binary data into an NSDictionary, and then we ask the board to load its game state from that dictionary (the idea being that in a future version, our game might store additional info in the dictionary that the board does not care about — that’s why i decoupled the data the Board class reads/writes from the actual binary format).

var lDictionary := dictionaryFromData(fCurrentMatch.matchData);
fBoard.loadFromNSDictionary(lDictionary,);

The same happens in reverse when we later save the updated game state. Of course, when a new game is first started, there will be no data present (GameKit doesn’t know anything about how our game data is structured, after all), so our code will need to be prepared to find an empty NSData object in matchData.

The second part, in addition to loading the board data, is determining the active player (if any) and enabling the game play. Each GKTurnBasedMatch has a currentParticipant property of type GKTurnBasedParticipant which links to the current player (it also has a participants array that contains all (two) players). We can compare this participant’s playerID to that of the local player.

If they match, it’s the local player’s turn, so we display “your turn”, and enable the board. If they don’t match, it’s either the remote players’ turn (if currentParticipant is assigned), or the game has finished. In either case, we show the proper status message, and leave the board disabled.

Playing a Turn

If it was the local player’s turn and we enabled the board, we’re done for now, and await the player to make a move. This all happens inside the Board class, which will call us back via the board() playerDidSelectGridIndex() method, once the player made their move.

What we need to do then is determine the game status (the player might have made a winning move, for example), re-encode the game status, and pass control back to game center.

There are three scenarios we need to cover:

  1. The player has won by managing to place 3 “X” markers in a row.
  2. The board has been filled (and the game just tied).
  3. Any other case — the game is still on.

In the two game-over scenarios, we set the appropriate status (Won/Lost/Tied) on each of the game participants, and then call endMatchInTurnWithMatchData() completionHandler() to tell Game Center that the match has ended as part of the player taking his turn.

In the other case, we call endTurnWithNextParticipant() matchData() completionHandler() to let Game Center know that the local player is done, and game play can move to the next player.

In either case, we will pass the updated information on what our game board looks like now, via the matchData parameter.

It is worth noting that it’s up to our game to tell Game Center “who’s next”. In our case, that decision is trivial (it’s the player that’s not the local player), but Game Center allows for turns to be passed in arbitrary ways, depending on your game’s needs — it doesn’t always have to go around the (virtual) table.

Once we called either of the above fund methods, it’s no longer our turn, and all we can do is wait for the remote player to make a move.

Handing Remote Turns

Of course, eventually the remote player will make their move, and GameKit provides a second delegate interface for this case, IGKTurnBasedEventHandlerDelegate, which we have hooked up to the GKTurnBasedEventHandler.sharedTurnBasedEventHandler singleton.

What will happen once the remote player moved is that Game Center will show a notification banner to the user, saying something along the lines of “It’s Your Turn”, and play that annoying fanfare sound. When and only when the user taps that notification, will we receive a call to the

method handleTurnEventForMatch(aMatch: GKTurnBasedMatch) 
       didBecomeActive(didBecomeActive: Boolean);

method to let our application know that something happened. This is nice, because it saves us from worrying about showing any UI to the user to ask if they, say, want to switch from the game they are currently looking at to the one that has received a response. When we get the callback, we already know that the user has decided to view the game in question.

So all we really need to do is the same as we did in … didFindMatch() above: load the passed match and enable the board, if appropriate.

House Keeping

This basically takes care of all the Game Center interaction needed for our simple game. There’s a few more minor items that i won’t go into detail for this post; for example, there’s a callback you will want to handle to quit games if the user selects to delete them in the Game Center UI. There also are APIs for providing a custom UI for the list of games, instead of relying on the standard UI provided by Game Center (all Tic-Tac-Toe does with this is adjust the Game Center button to either read “Games” or “Start”, depending on whether there are any games ongoing or not).

In Tic-Tac-Toe, all the GameKit interaction is located in RootViewController.pas, which is only ~500 lines of code total, so it should give you a good overview and starting point for your own game.

Caveats

There are a couple of caveats you might want to be aware of when working with Game Center games; these had me stumped for a short while, so hopefully pointing them out here will help save you frustration:

  • In order for Game Center to work, your app needs to be registered on iTunes Connect with the appropriate app ID. Even for the simulator. This is counter-intuitive if you are used to App Store development, because normally you don’t have to go to iTunes Connect to register your app until you’re (almost) ready to go and submit it. For Game Center, you need to register it first. If you don’t, GKTurnBasedMatchmakerViewController will just come up looking all empty and dysfunctional.

  • As best as i can tell, you must specify “gamekit” in the UIRequiredDeviceCapabilities section of your Info.plist file for things to work properly.

  • Finally, and most importantly, notifications do not work in the Simulator. If you worked with Push Notifications before, this might not come as much of a surprise, but realize that callbacks such as handleTurnEventForMatch() … will never, ever be called on the Simulator — which seriously will impact how you test game interaction. (In essence, i found the only way to work around this was to manually invoke the GKTurnBasedMatchmakerViewController and re-select the active game to trigger the app to reload the game data and detect the changed game state.)

The Game Board

The second piece of interest in the game is the Board class, which implements all the UI of the game as a really simply UIControl descendant.

The implementation is fairly straight-forward; the class maintains a 3×3 array to keep track of which player has claimed a particular spot on the game board, and in which move (by keeping track of the move number, the game can show different versions of their “X” and “O” markers, making the board look more dynamic).

The begin/continue/endTrackingWithTouch() withEvent() methods are overridden to keep track of — you guessed it — the user’s finger, and they use animations to fade the user’s game piece in and out, and to move it to the next appropriate spot, as the finger moves. (You’ll notice that while the user can move their finger all over the board, the game piece will always “snap” to a fixed position in the closest matching grid spot with a smooth animation.)

All the game pieces (the grid, the “X” and “O” game pieces, etc.) are pre-created images, and the game pieces come in 5 versions (since 5 is the maximum number of moves any one player can make).

The entire Board class is really straightforward and there isn’t much worth covering here that won’t be clear from looking at the code. Worth pointing out is the makeComputerMove method, which invokes Jeremy’s mean ComputerPlayer class, which is used when not playing in Game Center mode.

Tic Tac Toe Board

Summary

I think that’s it (and it’s probably enough ;). Make sure to check out the code on GitHub, and let me know what you think!

Oh, and: even though the code is written in Oxygene, as are the code snippets here, i hope the general description of how to work with GameKit will also be useful to “regular” Cocoa developers using Objective-C. Another nice thing about Oxygene working directly against the standard Cocoa APIs without any abstractions!

Avatar of marc

by marc

Custom iOS Controls in Oxygene “Nougat”

February 22, 2013 in Cocoa, Elements, iOS, Nougat, Oxygene, Visual Studio, Xcode

A week or so back, Yari D’areglia had an excellent tutorial on his blog on How to build a custom control in iOS that gave a nice rundown of some of the tasks involved, including handling touches, drawing some non-trivial custom UI, and returning events to the application via the target/action pattern.

While Oxygene “Nougat” can of course use any such controls directly and without having to convert or wrap them, i thought it would be fun to try and port the code over to Nougat and see what it looks like (and what kind, if any, challenges would be involved).

We don’t have Oxidizer support for Objective-C yet, so i did this manually, but it was still a very straight-forward process, and below are a few notes:

  • It turns out the new “Auto-Fix” for = vs. := assignments that we are shipping in the February release (which RTMs today) is a huge time saver. Just leave all the “=” in place, and the compiler will fix them for you when you hit build. This is new since i last converted code a few weeks back, and a much appreciated improvement.

  • There’s really only two “repetitive” tasks i found myself doing a lot to convert Obj-C to pascal: (a) changing Objective-C style “[]” method calls to use regular Oxygene “.” or “:” operators and (b) replacing type names with “var” in local variable declarations, such as CGpoint centerPoint = … to simply var centerPoint….

  • There were a couple of C macros used in the original code, which translated nicely into inline methods — a new feature in the Oxygene language for version 6.0.

All in all, i spent maybe 30 minutes last night converting and then tweaking/cleaning the code, and then the control and surrounding sample app was working perfectly (i also found a couple of new compiler bugs — remember Nougat is still beta — which always makes Carlo happy. When i woke up this morning, they were already fixed ;).

 

If you’re at all interested in creating your own controls for iOS (whether in Nougat or in Objective-C), i recommend to check out Yari D’areglia’s post. His original code can be found on GitHub, as can be my ported version.

 

Screenshot

Avatar of marc

by marc

“Nougat”, Beta 3

February 11, 2013 in Elements, iOS, Nougat, Visual Studio, WWDC

Beta 3

On Friday, we shipped BETA 3 of Oxygene “Nougat”, a major milestone in our progress to bring the Oxygene language you know and love to the “Cocoa” platform for truly native Mac and iOS development.

The big benefit of Oxygene “Nougat” over other non-Apple tool chains for Mac and iOS is that it fully embraces the platform and is a native compiler for the Objective-C runtime (which is at the core of Mac OS X and iOS development) that works directly with the native Cocoa API and controls.

This means you get all the benefits of the platform and you can work with and access all the same APIs that Objective-C developers using Xcode can. You can, for example, attend WWDC or NSConference or read and watch any of the trillion online tutorials out there on iOS (and Mac) development — and all the things you see and learn apply directly to the code you write with “Nougat”.

My friend and college Jim has created a great new video to introduce “Nougat” and show you around Beta 3, which you can find here.

Beta 3 is a huge milestone for us, in that we believe it represents a state in the development of the product where we can call it “usable for production work”. That doesn’t mean we’re close to RTM yet — we have big and strict plans for how solid we want the product to be for “1.0” this summer — but it does mean that it is solid enough that you can start doing serious work with it. I should know, as i already have my first app created with Nougat in the App Store: Browse500. (Full source is on GitHub, too).

What’s Next?

As mentioned above, we still have a long way to go before RTM. Beta 1 last October had the goal of, well, getting something out to you guys to play with, and we got a lot of great feedback. For Beta 2 we focused on getting all the basic tool chain support in place (debugging, deploying, etc.) and our main focus for Beta 3, which we just shipped, was stability, so we spent most of our time fixing bugs in the compiler, IDE and toolchain. For Beta 4 we are shifting focus back on features — there are still quite a few things missing in the language, and we have lots of improvements and enhancements planned for the tool chain and the Visual Studio IDE support.

“Nougat” is not standing still, and the next two months should be a whirl-wind of new stuff going into the product.

After Beta 4 (and possibly a Beta 5), we are still on track for an official “1.0” release (actually, it will be 6.0) in late spring/early summer.

Get Nougat!

How do you get “Nougat”? If you bought or renewed Oxygene from us since last October, you already have Oxygene “Nougat” as part of your product portfolio. Simply head over to beta.remobjects.com and get your copy of Beta 3 (and don’t forget to participate in the beta forums as well to let us know what you think).

(If you have a Suite Subscription for Xcode, that of course includes access to Oxygene “Nougat”, as well).

If you have a license for Oxygene for Java or for Embarcadero Prism XE2 or XE3, you can renew to the full suite of Oxygene for all three platforms at $349 in our secure online shop.

If you own Delphi XE2 or later, you can take advantage of our cross-grade offer for $399 to get the full Oxygene package.

And finally, the full Oxygene package is available for new users at $499.

Avatar of marc

by marc

Introducing Browse500, the first Nougat app on the iOS App Store!

January 17, 2013 in Elements, iOS, Nougat, Photography

I’m more than thrilled to announce the immediate availability of Browse500.app, the very first app written in Oxygene “Nougat” to be submitted to and approved for the iOS App Store.

Dog-fooding is important, and as you know, we do a lot of it here at RemObjects. In early December i started out creating a small “real life” iOS app with the goal of (a) putting Nougat thru its paces, test it and find bugs, (b) create a nice sample application that illustrates Nougat and core iOS and Cocoa concepts in a real application and (c) “test” App Store submission.

I did not expect any problems with app store approval — after all, Nougat creates 100% native Cocoa apps that are virtually indistinguishable from those created with Xcode and Objective-C, but i wanted too “prove” that a Nougat app gets accepted (even with “Oxygene” in the compiler meta data, for example).

I was not disappointed. I submitted Browse500 on December 28th, the day the iTunes Connect (the place where you submit apps) was back from its holiday shutdown, and version 1.0 was approved just a few days later. I did not put 1.0 live in the store for two reasons: for one i’ve been working on the app and kept improving it while 1.0 was waiting for review, and for another, there were a few bugs and leaks that would kill the app after some period of browsing because it ran out of memory. Those were easily fixed thanks to Instruments. 1.0.2 was submitted last week and approved last night.

So what is Browse500?

 

From the user’s perspective, it’s a nice little app to browse the 500px photo community. It lets you browse popular and, as they call it, “fresh” photos, view individual photos full screen, and drill into individual user’s portfolios to see all their photos.

It’s simple, it’s quick, and it turns out i actually use it all the time myself to browse photos.

I’ll be expanding it over time; i have a “bookmark” feature in the works that’s not active in 1.0.2 yet (but that i’ve been using frequently), i have more navigation ideas, and i want to add support for logging authenticating (right now the app browses anonymously only), voting, favoriting, etc.

 

From the curious developer’s perspective, Browse500 is an open source app, [available on GitHub], written in 100% Oxygene Nougat that illustrates a wide range of iOS technologies and concepts, including:

  • The awesome and fluid kind of standard UI you get by using the proper iOS frameworks rather that weird hack frameworks that aren’t native
  • Use of UITableViews and iOS 6’s awesome new UICollectionView, which i use to implement the main “album” view of the app
  • Using custom UICollectionViewCells and custom UIViews
  • Working with both XIB-based and all-in-code views
  • Using Grand Central Dispatch to write asynchronous code that loads images and data from the net on demand and in the background — you’ll see that the album view is an endless stream of photos that just keeps filling with more as you scroll until 500px runs out of photos to show you
  • Using iCloud to sync settings (1.0.2 as one setting) and data (the 1.1 will have the bookmark feature alluded to above)
  • Using third party Objectve-C APIs (the app uses the open source PXAPI library to talk to 500px.com)
    … and much more

As mentioned, the app is on the App Store now, so if you are mainly interested in playing around, go get it (it’s free). And of course it’s a Universal app for iPhone and iPad.

The app is also fully open source. You can get the full source code from the GitHub repository (you will need the latest Nougat beta), and i would appreciate feedback, comments and &mdashl of course — pull requests.

Also, don’t forget to rate the app on the App Store!

 




(Disclaimer: The photos in this view are not by me.)

Avatar of marc

by marc

Using Instruments with Oxygene to Profile your Mac and iOS Apps

January 14, 2013 in Elements, iOS, Mac, Nougat, Visual Studio, Xcode

One of the coolest tools in Apple’s Xcode tool chain is Instruments, the profiler.

Profiling is an essential debugging tool for every developer, whether you want to tune the performance of a particularly time-sensitive piece of code, or drill into some memory issues (be it leaks or general memory load). With ARC, just like with Garbage Collection on .NET or Java, regular object leaks are rare, but one scenario where they can still happen (opposed to GC) is with so-called “retain cycles” — where object A holds on to object B, and vice versa.

Because Instruments is such an essential tool for the Cocoa developer, we have deeply integrated support for it into the Oxygene “Nougat” tool chain as well, and i’d like to demonstrate that in a quick (only somewhat contrived) sample.

Let’s say you have the following code:

type
  DummyData = class
  private
    fData: NSMutableArray;
  public
    method init: id; override;
    method Work; empty;
  end;
 
  DummyDataItem = class
  private
    fOwner: DummyData;
  public
    property owner: DummyData read fOwner;
    method initWithOwner(aOwner: DummyData): id;
  end;
 
implementation
 
method DummyData.init: id;
begin
  self := inherited init;
  if assigned(self) then begin
    fData := new NSMutableArray;
    for i: Int32 := 0 to 1000 do
      fData.addObject(new DummyDataItem withOwner(self));
leak
  end;
  result := self;
end;
 
method DummyDataItem.initWithOwner(aOwner: DummyData): id;
begin
  self := inherited init;
  if assigned(self) then begin
    fOwner := aOwner;
  end;
  result := self;
end;

Looks innocent enough. DummyData holds an array of DummyDataItems it initializes on creation; the code (naïvely) assumes the array and everything else to be released when the DummyData object itself goes out of scope.

Except it doesn’t, and your customer calls to complain that the app’s memory footprint is growing. How do you find out what’s going on? Instruments to the rescue.

In Oyxgene “Nougat” (as of BETA 3), Instruments is available right from inside Visual Studio. We’ve added a new menu item to the Debug menu (and you can also add it to the toolbar of course): Start With Instruments:

Hit that and Oxygene will build your app (if necessary), and via the magic of CrossBox, you’ll see Instruments popping up, Mac side — by default asking you what kind of analysis you want to perform:

Select Leaks and that will open an Instruments document, and also start your application running. Play around with the app and trigger the code paths that lead to the memory increase. In the Instruments window, you san see what’s happening, live — the overall memory load of the app keeps increasing (as shown in the Allocations instrument):

Quitting the app and selecting the Leaks instrument shows all the memory that was leaked — that is, not properly released. The picture is quite clear — it seems that 31 DummyData instances were created and never properly released. What’s up with that? After all, your code that creates DummyData is dead simple:

method MainWindowController.buttonClick(aSender: id);
begin
  var d := new DummyData;
  d.Work();
end;

“d” goes out of scope right after it’s used, and that should release the object, right?

Fold open one of the DummyData items in the list and click on the little arrow next to its address to drill into its retain/release history. You’ll see a huge list of roughly a thousand calls to retain. The call stack on the right tells you these happen from within “DummyDataItem.initWithOwner:”. That makes sense — your code creates a thousand of them, after all.

At the very end of the list, you see that from “buttonClick” your DummyData is being released though.

What’s going on? Shouldn’t “d” going out of scope release the array, which in turn releases the DummyDataItems, which in turn… wait, we’re getting close to the problem! It looks like our data structure contains what is called a “retain cycle”. The DummyData holds on to the NSArray, which holds on to the DummyDataItems which, in turn, hold on to the DummyData itself. Even though “d” is going out of scope, its retain count is only going down to 1001, because all the DummyDataItems still have references. As a result, the DummyData object actually never gets freed, and neither does the NSArray or the DummyDataItems inside it, which, in turn, can never give up their hold on the DummyData itself.

Though in this case we found the issue fairly quickly, Instruments has one more tool up its sleeve to make it even easier to find retain cycles: Click on the Leaks item in the navigation bar and select Cycles & Roots:

Instruments has actually detected any retain cycles for us and shows them in a list (in this case, 31 of the same), along with a nice graphical representation of what is going on.

From this view (even without our previous investigation), it becomes immediately clear that the fOwner reference from DummyDataItem back to DummyData is the culprit.

How do you break this vicious circle (assuming you cannot simply drop the owner reference altogether)? Weak references to the rescue!

type
  DummyDataItem = class
  private
    fOwner: weak DummyData;

By default, all variables and fields in Oxygene (and Objective-C with ARC) are strong — that means when an object is stored in the variable, its retain count is increased. By contrast, weak references just store the object, without affecting retain count. In fact, they do one better: they also keep track of the referenced object and automatically get set to nil when said object is released — so you never have to worry about the variable pointing to a stale object (which is a big problem in non-ARC languages).

Sidebar: A third type of object references are so-called unretained references. These behave like regular pointers in old-school languages; they store the object address, and when the object gets released that address will be stale — your code will be responsible for worrying about that.

With the code fixed, hit the Start With Instruments menu again. Your app will launch and Instruments will profile, and as you work with your app, you will notice that the memory load now stays down — as originally expected.

Of course, the Leaks pane will remain empty, but just to confirm, you can select the Allocations instrument, select Created & Destroyed in the sidebar and then locate and drill into one of the DummyData objects. As you can see, the retain/release history is much more sane now — no 1000 extra retains from DummyDataItem — and the object actually was released at the end of “buttonClick”.

Success!

 

So what have we seen in this article? We’ve had a quick look at how Instruments works and can be used to inspect memory allocations (the first phase of the investigation above does not just apply to bona-fide leaks and retain cycles, but can also be helpful if you just want to get a general impression of what memory your app is holding on to, and why), learned about retain cycles and strong, weak and unretained object references and we have also seen how Instruments can be used from Oxygene Nougat (which was so dead simple, it hardly warranted mentioning, wasn’t it?).

Oxygene on the Big Screen

January 4, 2013 in Android, Elements, iOS, Java, Mac, Metro, Windows, Windows Phone

Android powered Ouya ConsoleYou already know Oxygene is the best choice for mobile development – Oxygene for Java on Android, Oxygene for .NET for Windows Phone and the Windows RT Surface and the beta “Nougat” already providing great support for iOS development. But what if you want to develop on the big screen? Like that 50 plus inch TV in your front room?

Enter the Ouya, the Android powered game console for your TV. They just released their ODK (Ouya Development Kit), and since it is Android powered, it is perfectly supported by Oxygene for Java right out of the box. Oxygene for Java is a completely native Android development tool – there are no forced abstraction layers or additional run-times to get in your way or require updating when new variations or versions of the platform come out.

Red Ant Games has just announced they are using Oxygene for Java to move their Subject 33 to Ouya and Android mobile devices. Subject 33 is currently an Alpha prototype on Windows. They also have plans to support iOS and Mac with “Nougat”.

Avatar of marc

by marc

Working with User Interface files in Oxygene “Nougat”

January 2, 2013 in Cocoa, Elements, iOS, Mac, Nougat, Oxygene, Visual Studio, Xcode

In this article, i want to talk a bit about working with user interfaces in Oxygene Nougat.

As you know, Nougat is a native compiler for the Objective-C runtime, meaning that it works directly with the classes provided by Apple’s Cocoa and Cocoa Touch frameworks. This extends from low-level classes such as NSString or NSArray to the high-level visual components based around NSView (Mac) and UIView (iOS).

One common way for Mac and (especially) iOS apps to work with UI is to simply create the necessary views and controls that make up an app’s UI from code. But sooner or later, especially when dealing with more complex or sophisticated user interfaces, you will want to use the visual designer. This works on the same principles, whether you are using Xcode/Objective-C or Nougat.

Mac and iOS interfaces are designed in Interface Builder, which as of version 4 is directly integrated into the Xcode IDE, and when working with Nougat, that is where you will work with your interfaces, getting the same experience and the same power and flexibility of UI design that developers using Objective-C get, as well.

There are two file formats used for designing UI on Apple’s platform — the older XIB format and the newer (and iOS-only) storyboard format. The principles for dealing with these files are similar, but for the topic of this article, we’ll focus on XIB files, as those apply to both Mac and iOS development. In a future article, i will go into some more details specific to storyboards.

Background: What are XIB Files?

So what are XIB files? From the point of view of the UI designer, XIB files contain the views or windows that you design in Interface Builder — the controls, their layout and properties, and their connections to your code.

It is important to understand that on a technical level, XIB files are stored object graphs. That means that an XIB file, essentially, is a hierarchical set of objects descriptions. When an XIB file gets loaded at runtime, all the objects defined in the XIB file get instantiated, configured, and connected as described in the XIB.

These objects can be a combination of standard framework classes (such as NSView/UIView, NSButton/UIButton, etc), classes from third party libraries, or even classes defined in your own application code. When the Cocoa runtime loads an XIB, it goes thru the list one by one, looks for the classes with the appropriate names and news up the necessary objects.

Each XIB file also knows about a special object called the “File’s Owner”. This object will not be created when the XIB is loaded. Rather, the object that initiated the loading of the XIB file will take the place of the File’s Owner within the XIB’s object graph — including any connections and references to it. We will see how that is useful and important, soon.

Loading up an XIB

When and how do XIB files (or storyboards) get loaded? There are several possibilities:

 

NSMainNibFile

If your Info.plist contains an NSMainNibFile entry, the Cocoa runtime will automatically load up that XIB as your application starts up. The global NSApplication/UIApplication instance will become File’s Owner of the XIB, and every object in your XIB will be instantiated.

This mode is common for Mac applications, and in fact you can see it in action in our Cocoa Application template(s). You probably noticed that (aside from the startup code in Program.pas) the project contains an AppDelegate class that is usually used as the “launching point” for your application’s own code.

How does this AppDelegate class get instantiated? Easy: If you own the MainMenu.xib file in Xcode (the xib that is specified to be the NSMainNibFile in Info.plist), you see that — among other elements — it contains an AppDelegate item. This is your own AppDelegate class.

initWithNib:*

For simple applications, you can get away with just putting all your stuff into MainMenu.xib, but as applications get more complex, that’s a bad idea, not only because — as indicated above — when an XIB is loaded, all objects referenced in it are created. If your application contains dozens of windows or views, you don’t usually want all of those to be loaded up as your application starts.

Instead, it is common practice to pair individual XIBs for each view or window XIB with a matching ViewController or WindowController class — a practice that you will see in just about all the iOS project templates, and also in the *Controller item templates we provide with Nougat.

How does this work?

Simple: your application will define a custom class, usually descended from UIViewController (or NSViewController/NSWindowController) where you will put all the application logic for that view or window. As far as your app is concerned, this class is your implementation for that particular view (or window — for simplicity reasons i’ll stick to talking about iOS Views for now, but the same concepts apply for OS X views and windows).

In the initializer for your view controller, you will ask the base class to load up the XIB file that backs your view, for example by calling

self := inherited initWithNib('MyViewController') bundle(nil);

This essentially tells the base class to initialize it by loading MyViewController.xib (from the main application bundle) and creating all the objects defined in it.

So all those objects get loaded up, but how do you then get access to them from your code? Simple: remember when i said above that the object loading the XIB becomes the File’s Owner? When you load an XIB using the initWithNib() call, your view controller class becomes the File’s Owner — and any connections you set up in the XIB between the File’s Owner and the other elements in your XIB will be connected to your view controller class.

Connections

Did i say connections? So how does this work?

Easy, really. XIB files know about two basic kinds of connections between objects: Outlets and Actions.

You can think of outlets as references to other objects. If your view controller class has a property of type UIButton, and your XIB file contains a UIButton, that’s a match made in heaven. You can just Ctrl-drag the button onto the File’s Owner (or vice versa) in the XIB to hook them up, and now you have access to the UIButton from your code, because as the XIB gets loaded and the UIButton gets created, it gets hooked up to your property automatically.

Actions, you may have guessed, can be thought of as events. If something happens with the objects in the XIB (such as a button being tapped), they send out events. Just as above, if your view controller exposes a method with the right signature (that is, any method with exactly one parameter of type “id” or a concrete class), you can Ctrl-drag it into your XIB file to hook them up — and when the event triggers, that method is called.

Of course outlets and actions can be hooked up between any two objects inside your XIB, not just with the view controller. For example, you can cause an action on one control to trigger a method on a different control.

Ok, so how does the XIB designer in Xcode know about the methods and properties on your view controller (or other classes)? Magic! As you write your classes, Nougat will automatically* update the XIB and Storyboard files, behind the scenes, with information about all the relevant classes and their properties and methods — that is any property marked “[IBOutlet]” and any method marked “[IBAction]“. As you work on your XIB file in Xcode, it sees this information, and makes the connections available.

If you need to expose a new control to your code or want to hook up a new event, simply add a new property or method to your code, and that’s it.

Let Me See This in Action

For this example, i’ve created a new “UIViewController with XIB” from the template. I have then added the following items to the “MyViewController” class:

property myButton: UIButton;
property myLabel: UILabel;
method buttonTapped(aSender: id);

The following screenshot explores the XIB (and storybook) designer in Xcode:

Figure 1: On the left side of the window, you see a hierarchical view of all the objects in the XIB — this includes all visual objects (in this case just the one UIView for now, but also other objects such as the File’s Owner).

On the right side, the “Utilities View” has the “Identity Inspector” pane activated, showing details about the selected object (the File’s Owner). Note that the XIB designer knows that File’s Owner is a “MyViewController”. It got that information from the template – but this is editable, so you can just type in or select the right class name. Of course it should match the class that is loading this XIB at runtime.

Figure 1

Figure 2: We have dropped a couple of controls onto the view — you can see them both visually and in the hierarchy on the left. The right pane has been switched over to the “Connections Inspector” tab, which shows all the connections available on our File’s Owner. Among them, you see our two properties and the method. There’s also a “view” property (defined by the UIViewController base class), already connected to the root view.

Figure 2

Figure 3: Click and drag from the little circle right of the “myButton” name to the button to make a connection to the UIButton. (You can drag to the control on the design surface or to the “Button — Tap Me!” item in the hierarchy.)

Let go when you are over the button, and the connection is made. If you were to go and build your app now, the myButton property would give you access to the button from code.

Figure 3

Figure 4: You can also drag from the hierarchy view to a control. When you let go, the XIB designer will present a list of all properties that match — in this case the UILabel qualifies both for “myLabel”, and for the “view” property (because UILabel descends from UIView).

Figure 4

Figure 5: Connection actions work the same way. You can Ctrl-drag from the control to the receiver (here the File’s Owner) to connect the default action of that control (in this case, the button tap) to a method. As you can see, the Connections Inspector also shows a complete list of all actions that can originate from the control, so you can — if needed — assign them all to individual methods.

Figure 5

Now all that’s left to do is maybe write an implementation for “buttonTapped” such as this:

method MyViewController.buttonTapped(aSender: id);
begin
  myLabel.text := myButton.titleLabel.text;
end;

to see both actions and outlet access in — pun not intended — action.

Terminology: XIB vs. NIB?

In the text above, i talk about XIB files, but the method names all mention NIBs. What’s up with that?

XIBs are a newer, XML based format that is used for the UI at design time. When you compile your app, the XIB files are converted to binary NIB files for you, and those binary versions of the files are embedded into your app. All the APIs working with these files predate the new format (and, at runtime, only work with the older NIB format), that’s why all the method names refer to NIB, not XIB. When you pass around names, you never need to (or should) specify the file extension anyway, so this is a distinction that you can largely ignore (unless you want to go spelunking into your .app bundle).

What’s “First Responder”?

Similar to File’s Owner, “First Responder” is another placeholder object exposed in the XIB file that has special meaning. The First Responder is not a concrete object, but essentially refers to “the first object that has focus that can handle this”.

By connecting actions to the First Responder, you can have them dynamically be sent to different parts of your application, depending on the state your app is in. A good example is the “Edit|Copy” menu in a Mac application. If a text field has focus, you would expect the Copy command to apply to the content of that text field. If a different control has focus, different content would be copied. By connecting the menu’s action to the First Responder’s “copy:” method, Cocoa will take care of calling “copy()” on whatever control or view has focus — in fact, all you need to do to make Copy/Paste work with your own custom view would be to implement the corresponding methods, and they would get called if your view has focus as the user invoked the menu item (or Cmd-C keyboard shortcut).

Summary

I hope this gave you a quick introduction to XIB files and how they work. A good 95% of the content of this article is not really specific to Nougat; the same concepts and techniques apply to working on XIB files with Objective-C — that’s by design, because Nougat is a true first class citizen on the Cocoa frameworks and Objective-C runtime.

Footnotes

(* in the current beta drop, this update does not happen automatically yet. You can right-click your .XIB or .storyboard file in Solution Explorer and choose the “Sync XIB”/”Sync Storyboard” to trigger an update.)