You are browsing the archive for iOS.

Profile photo of marc

by marc

Announcing Oxygene 6 and the new Oxygene for Cocoa

May 28, 2013 in .NET, Android, Cocoa, Elements, iOS, Java, Mac, Oxygene, Visual Studio

Hello everyone.

We are more than pleased to announce the release of Oxygene 6, the next major milestone of our Oxygene language. This new version includes a significant update to the existing “Oxygene for .NET” and “Oxygene for Java” editions, but – most excitingly – it also marks the first release version of our all-new Oxygene for Cocoa.

Oxygene for Cocoa is a brand-new edition of our Oxygene language, and it targets native Mac and iOS development with the Cocoa frameworks, using the same great language you already know and love from .NET and Java. We are very excited about Oxygene for Cocoa, and we think it will be a game-changer for how you create apps for Mac and iOS.

Oxygene for Cocoa is a very unique product, in that it is the only language (next to Apple’s own Objective-C) to truly natively target the Cocoa platform and the Objective-C runtime. It gives you access to all the great frameworks and libraries provided by the platform, lets you use all the native UI controls, and generates executables that are lean, mean and blazingly fast – and compiled directly for Intel x64 (Mac) or ARMv7 and ARMv7s (iOS).

Get Oxygene now

Support for all three platforms is available in the new Oxygene 6 package, which is a free update for all active subscribers who bought Oxygene form us since last August. It is available for new users at only $699 (again including all three platforms!), and individual platform support is also included in our Suite Subscriptions for .NET, Cocoa and Java, respectively.

Special renewal pricing is available for existing Oxygene for Java or Prism customers $499, as well as a special $599 cross-grade offer for any users of Embarcadero Delphi or of older Embarcadero Prism versions (XE2 and below).

We’re also for the first time ever introducing a new academic pricing for students, teachers and non-profit researchers, at an amazingly low $99.

And of course, as always, theres a free fully-functional 30-day trial version available, as well.

This is only the beginning

But we’re just getting started with this release and have many further exciting things planned for this year and beyond, including two minor updates for June and July, a significant “6.1” release in Fall, as well as several related products and technologies that will extend the Oxygene ecosystem that we’re not quite ready to talk about yet.

In the meantime, we hope you will enjoy the first release of Oxygene 6.0 and Oxygene for Cocoa – and we’re looking forward to hearing what Apps you will be building with it!

You can learn more about Oxygene at and



marc hoffman
Chief Architect,
RemObjects Software

Profile photo of marc

by marc

…then i might as well learn Java?

April 23, 2013 in .NET, Cocoa, Delphi, Elements, iOS, Java, Windows

One of the most frequent comments i hear when people dismiss or decide against considering Oxygene as their development tool of choice goes along the lines of the title of this blog post:

“With Oxygene i need to learn all the new platform APIs. If that’s the case, i might as well learn C# [or Java or Objective-C].”

That’s certainly true. When moving to and learning a new platform, there’s a vast number of things to learn — new classes, new APIs, new concepts, new ways of doing things. Learning a new language, especially if it’s one from the same broader family of languages you already know (i.e. Object Oriented languages) is only a small and insignificant part of that.

But, i think it is missing the point of Oxygene, to think its whole reason d’être is to save you from learning a new language. Quite the contrary.

Oxygene is based on Object Pascal, and is, at its root, very close to the “Delphi” language (which basically represents the state-of-the-art of Object Pascal ca. 2003). The main reason for that is not that Delphi developers (which the creators of Oxygene were too, at the time) do not have to learn a new language. The reason for that is that Pascal — as much as it has gone out of fashion over the past 20 or so years — is a freaking amazing base point for a programming language. It’s clean, well structured, easy to learn, and — very importantly — easy to read.

Many developers underestimate this, but they spend a lot more time re-eading their (and other’s) code than they originally spent writing it — so having a language that makes code easy to parse and understand by the human brain is a very important and undervalued feature of a language. One that Oxygene shines at like no other.

So that’s the why Oxygene is what it is, but is that enough reason to choose it over C#, Java or even Objective-C? No, of course not.

The biggest selling point for Oxygene in my opinion is not that it’s Pascal based, and is not that is allows you to natively compile for today’s three major platforms (.NET, Java and Cocoa) with the same code base, and it most certainly not that it saves you from doing anything (be it learning a new language, or be it spending more money on a more expensive development tool).

The biggest selling point of Oxygene is — quite frankly — that it is an amazing modern language, with features that developers using the other mainstream languages don’t even begin to dream about.

Going into details on all the features that make Oxygene unique and powerful, the features that will change your life as a developer, would require several posts on its own. But the scope ranges from Class Contracts to language-integrated parallelism, from nullable types to the amazing Future types, from small but powerful things like the colon operator and double boolean comparisons to “for” loop expressions (not to be confused with regular “for” loops), and from duck typing to language-native tuples.

The list could keep going on.

So when you’re looking at Oxygene (and i know you are), don’t just look at it from the perspective that it will let you keep coding in Pascal without having to learn a new language. Sure, that’s a big factor too. If you’re a Delphi developer, you probably love Pascal (like we do), and have been using it for the past 10, 20 or even more years. And being Pascal certainly is one thing that makes Oxygene attractive to you.

But don’t stop there; you’re doing Oxygene and yourself an injustice, if you look at that as the main benefit.

Instead, think of using Oxygene as switching to the most powerful and modern object oriented language out there, today. That it’s Pascal-based is just the icing on an already very delicious cake.

Profile photo 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 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 := ''; // 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

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);
  var p := new ApplePushProviderService_AsyncProxy withURL(new NSURL withString(URL));
  p.beginRegisterDevice(deviceToken, startWithBlock(method (aRequest: ROAsyncRequest) begin
      var lAlert := new UIAlertView withTitle('All set!') 
                         message('You are registered for Push Notifications!') 

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.

Profile photo 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.


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):


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


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:


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


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:


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


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:


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


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

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 ;).


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!

Profile photo 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.


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!

marc hoffman

Chief Architect,
RemObjects Software

Profile photo 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);

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.


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


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!

Profile photo 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.



Profile photo 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 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.

Profile photo 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, 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
    … 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.)

Profile photo 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:

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

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);
  var d := new DummyData;

“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!

  DummyDataItem = class
    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”.



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?).