You are browsing the archive for Cocoa.

Avatar of marc

by marc

iOS 7 and OS X Mavericks

June 17, 2013 in Cocoa, iOS, Mac, Oxygene, ROFX, WWDC, Xcode

As you have probably heard by now, last week Apple announced iOS 7 and OS X Mavericks, new major versions of both its flag-ship operating systems. I had the privilege of being on site in San Francisco and attending WWDC in person, but the keynote with the core announcements is available for public viewing by anyone, and the remaining ~100 sessions of the conference are also available for free to all registered developers (major kudos to Apple for that, and more importantly, for making these videos available so fast, in most cases on the same day as the actual presentations!).

iOS 7 is a major new release and – most observers agree – a game changer. It’s a whole new UI paradigm for the OS, and will be a very exciting release for both users and developers; there are a whole bunch of new technologies that will let you create even better iOS apps, and will make the whole iOS experience even better for the user — in the core OS or with your apps.

Due to the massive UI overhaul, most iOS apps will need a serious rethinking for iOS 7 to stay relevant – which means extra work for developers, but also extra opportunities. From what i can tell (and am allowed to tell), switching an application over to the core iOS 7 “look” will be simple, but really making an app feel at home on iOS7 will require a lot of thought — no way around it.

I have already started moving two of our (internal) apps to iOS 7 while on site in San Francisco, simply because after (foolhardily) upgrading my main phone to the new OS, i could no longer stand looking at the old UI ;). One app is “done” and was relatively straight-forward – mainly a matter of rebuilding with the iOS 7 SDK, and making a few adjustments here and there to better embrace the new style; the other will be more work.

OS X Mavericks (if you don’t like the name, you are not alone. Virtually everybody i talked to or heard talk about it found it “weird”) is a smaller upgrade, by comparison, but also a significant release with a ton of exciting technologies for developers – two that were highlighted in the keynote include the new Maps API and cool new energy-saving APIs and technologies. (And if you’re not excited by being able to make your apps more power-efficient, then you have no business developing Mac apps! ;).)

Of course the big question you’re all asking is how Oxygene for Cocoa is working with the new iOS 7 and OS X Mavericks. The good (and slightly unexciting, because expected) news is: it works just fine. We’ve long had an article on the Wiki that discusses the (simple) steps for hooking up Oxygene with new beta SDKs, and Oxygene is working fine with iOS 7 and with Mavericks (although i do recommend grabbing the latest beta drop of Oxygene, as we already made some tweaks and improvements there).

All the new APIs (IIRC Apple mentioned a number of 1500 new APIs being available) will work with Oxygene out of the box – no need to wait for anyone to create any wrappers or headers for you, and re-building your Oxygene apps with the iOS 7 SDK will give you the new iOS 7 look right away (but not save you from re-examining how to really embrace iOS 7 best with your app, of course).

There are also a few new non-API features that we’ll be embracing with Oxygene as well, but unfortunately those are (afaict) all under NDA, so i cannot talk about them yet. But suffice to say over the next few months we will of course be doing a lot of testing with Oxygene and the new APIs and SDKs to keep Oxygene up to date with the SDKs and the Xcode 5 tool chain.

Of course we’ll also be testing Data Abstract and RemObjects SDK for Cocoa with the new SDKs, and (where applicable) expanding them with support for new APIs. In my testing so far, they work great (both the apps i mentioned above are DA-based, and run fine on iOS 7, for example).

Support

Talking about new iOS and OS X SDKs is always a tightrope walk, as there’s a lot of information that’s under NDA (but available to all registered Apple developers – so do make sure you check out the beta builds and all the videos from WWDC). But Oxygene, as well as RO/DA for Cocoa, are already working great with the new operating systems, and we’ll be working hard to expand those parts that do need explicit support and work to fully embrace the new OSs.

If you have any specific questions regarding support for or issues with the new SDKs, there’s two places to get help: for one, we’ll be monitoring and participating in Apple’s beta forums, so you can post questions about Oxygene there (maybe add “(Oxygene)” to the subject so we can find them easier). And you can also always directly email support.

We cannot discuss the iOS 7 or OS X Mavericks Beta SDKs on Connect; you could be violating your NDA by posting details there, and we’d be doing the same by answering. So be careful.

Summary

I’m very excited about both iOS 7 and Mavericks (and i assume i’ll eventually get over the name, too), and so should you. I’m looking forward to seeing what you’ll build on the new OSs with Oxygene and Data Abstract.

Avatar of marc

by marc

Announcing Oxygene 6 and the new Oxygene for Cocoa

May 28, 2013 in .NET, Android, Cocoa, iOS, Java, Mac, Oxygene, Prism, 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 remobjects.com/oxygene and wiki.oxygenelanguage.com.

 

Yours,

marc hoffman
Chief Architect,
RemObjects Software

Avatar of marc

by marc

…then i might as well learn Java?

April 23, 2013 in .NET, Cocoa, Delphi, iOS, Java, Oxygene, 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.

Avatar of marc

by marc

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

April 3, 2013 in .NET, Cocoa, iOS, non-tech, Nougat, Oxygene, 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, iOS, Nougat, Oxygene, 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!

Top 10 Reasons to use Platform Native APIs

March 14, 2013 in .NET, Cocoa, Cooper, non-tech, Nougat, Oxygene, Prism

What are native platform APIs? They are the APIs provided by the platform vendor that define the platform. On Android this is the Android SDK. On iOS it is the Cocoa Touch Frameworks. On Windows and Windows Phone it is WinRT and the .NET Framework. There are undocumented APIs, and even calls that circumvent the platform APIs, but they are not considered part of the platform API.

In addition to the native development tool provided by the platform vendor, there are 3rd party development tools providers (such as ourselves) with their own solutions. The 3rd party tools typically either focus on providing a better solution for the specific platform, or sacrifice native platform support with the objective of cross-platform simplicity. There is no reason to sacrifice platform support, as you will see in these top 10 reasons to program to platform native APIs.

Platform Native APIs are Great

Those who programmed MS-DOS applications or the early Windows API no doubt remember what a pain those APIs (or lack of) were to work with. Back then it was great to have a good abstraction to make the platform easier to work with. Today’s platform native APIs encompass all the productivity enhancements that are found in the the best abstractions. Typically, the productivity enhancements that come from additional abstractions are only in the form of familiarity and developer’s resistance to learning a new API and framework. You know things are getting carried away when there is a Java abstraction for developing Windows Phone 8 applications and a .NET abstraction for building Android applications.

The Law of Leaky Abstractions

All non-trivial abstractions, to some degree, are leaky.” If your tool forces you to use some non-trivial abstraction on top of a platform’s API, at some point it will leak – there will be something that the abstraction cannot do, or somewhere the abstraction behaves differently from platform to platform. If you are serious about developing for any platform, you need to understand the platform’s native API. The more non-trivial the abstraction, the less of the platform it can abstract successfully and the more likely you will need to move to the platform native API. If you are going to need to learn the platform API anyway, you might as well start there. No need to learn both the abstraction and the platform API – that is twice as much work.

Native Documentation

Documentation is a lot of work. Good documentation is even more work. On each platform, the platform vendor provides the documentation of the platform along with all the best practices and examples. For each additional level of abstraction that requires another level of documentation to consult. Chances are that the documentation will eventually refer you to the platform API documentation. Wouldn’t it be nice to just start at the ultimate authority and not have to wade through incomplete and outdated layers of documentation?

No Bloatware

If your abstraction adds additional graphic libraries or run-times, your application suffers with bloat. These abstractions replace the functionality already present in the platfrom and make your app bigger, slower to start-up and less responsive at runtime. Some of these add-ons are worthwhile, but if you need to double (or more) the size of your app just to write “hello world”, then you are probably using the wrong solution.

Rapid Release Cycle

When a platform vendor releases a new API you want to be able to take advantage of those features right away. It may surface new hardware features, or just introduce better ways of doing things. If you are forced to use an abstraction, you need to wait for the 3rd party to update their abstraction. This may be fairly quick, or you may have to wait for their release cycle, which, depending on where they are in development, could mean the release after the next. No matter how fast a vendor has been in the past at updating their abstraction library, a point will come where they are not updated when you need them.

Support for Platform Deviations

If a hardware vendor comes out with their own SDK extensions or variations on a platform, they will provide their support at the level of the platform API. If you are stuck behind an abstraction, you will not have access. The openness of Android is a great example with extensions like Google TV, Epsion Moverio, Ouya, and Google Glass. If you are interested in cutting edge platforms like these, you need a development tool that doesn’t lock you behind an abstraction.

Native User Experience

Each platform has a typical user experience. This comes from the native platform user interface widgets and the way they behave. It also comes from design guidelines provided in the platform documentation. If you are using an abstraction for your user interface, even one that tries to look and act like the native one, it will get in the way of this native user experience. When it comes to user experience, close isn’t close enough. Using the native platform user interface controls is the only way to give your users the experience they expect.

Less Points of Failure

Everything always works great in the demonstrations, but the more layers of interoperability and wrappers required to make your application run, the more points of failure. When you develop for the platform API directly, you are not handicapping yourself with black boxes or other points of failure for your app. The first time you find yourself debugging into that abstraction layer, you will really wonder if it was worthwhile to shackle yourself with it.

Maximum Developer Flexibility

Platform APIs are huge. In the process of creating a wrapper, choices are made to simplify or eliminate options. These simplifications and eliminations result in less flexibility for the developer. Tying a project to a subset of the features of the platform reduces what you can do with your project. Don’t tie your hands!

3rd Party Support

The majority of 3rd party components and books are going to support the platform’s API. The further you are from that, the less support you are going to have. Want to use a cool 3rd party custom control? Hope they port it to your favorite framework. And what are the odds of a book about the specific features of the platform you want to explore covering it via your specific pair of shackles?

Summary

Cross-platform abstractions are only going to get in your way and tie your hands. Any benefit in getting you up to speed faster will be lost in the long term when you hit the rough edges of the abstraction. That is the reason Oxygene is designed to use the platform native APIs directly. There is no forced or complex abstraction to get in your way of using the platform and making the best app possible.

Avatar of marc

by marc

Custom iOS Controls in Oxygene “Nougat”

February 22, 2013 in Cocoa, iOS, Nougat, Oxygene, Prism, 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

Working with User Interface files in Oxygene “Nougat”

January 2, 2013 in Cocoa, iOS, Mac, Nougat, Oxygene, Prism, 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.)

Avatar of marc

by marc

Using RemObjects SDK and Data Abstract with Oxygene Nougat.

December 25, 2012 in Cocoa, iOS, Mac, Nougat, Prism, ROFX, Visual Studio, Xcode

Nougat is, of course, designed to work with any existing Objective-C libraries out there, because it directly consumes and generates code for the Objective-C runtime. As such, it should come as no surprise that Nougat is ready to use RemObjects SDK and Data Abstract for Xcode, out of the box.

That said, with the new Alpha builds of RemObjects SDK and Data Abstract that we shipped on friday (build .1069), we have made a few improvements that make it even easier to get started with RO/DA in Nougat. These are three-fold:

Read-to-Use .fx files

Unlike .NET and Java, Cocoa libraries do not include easy to parse metadata for compilers to consume. Instead, it depends on .h files to define the available APIs — which is fine when consuming the libraries from a C compiler. Because .h files are slow and complicated to parse, Nougat introduces an intermediary format in the form of .fx files. You can think of an .fx file as “pre-compiled headers” file for a given framework or library; a set of metadata that represents all the information expressed in the framework’s .h files, but encoded in a way that it is easy and quick for the Oxygene compiler (and IDE toolchain) to process, when compiling, driving Code Completion etc.

While Nougat comes with the necessary tools to generate .fx files for any of your favorite third party libraries (and of course ships with .fx files for the supported base SDKs), that is an extra step we want to alleviate, so the new build of RODA/Xcode includes .fx file for those libraries out of the box. After installation, you will find the files next to the corresponding binaries in ./Bin.

All you need to do to use the SDK or Data Abstract from Nougat is to go to “Add Reference”, select the .fx file for your platform (i.e. OS X or iOS) to add a reference. That’s it.

libDA.fx Reference

From the .fx, Nougat will automatically know about all the types in the RO/DA library, and will take care of getting the static library and any dependencies linked in.

Static Libraries for OS X

In the past, RODA/Xcode included precompiled binaries in the form of a framework for OS X and static libraries for iOS. Frameworks are easier to deal with in Xcode, because they combine a binary with its accompanying header files, which is why we chose to ship OS X binaries as a framework. iOS does not support the framework format for third party libraries, so the choice there was easy: static libraries are the only option.

For Nougat, the benefits of a framework (on OS X) are diminished, because metadata is provided in the .fx file anyways, so a static library is just as easy to deal with, and has fewer files involved. For that reason, we have added a static library version of RODA/OS X to the product (in addition to the Framework). Xcode developers can choose to use either version, depending on their preferences (the static library has the benefit of being linkable straight into the executable, which is nice if you’re creating command line tools that use RO/DA); Nougat developers will mostly want to use the new static library alongside its .fx file.

CodeGen for Nougat

For pure Data Abstract use, you’re pretty much all set with the above, but if you’re building custom RemObjects SDK services that you want to talk to, there’s one more step missing: Interface code.

Talking to RO services depends on having strongly typed interfaces generated for your local proxy classes and any complex types you are passing back and forth between the client and the server — and until last week, RO/Xcode generated this code in Objective-C only.

That was not a complete showstopper for Nougat. Remember, Nougat can use any Objective-C library, so you could compile those files using Xcode and the use them from Nougat (in fact, that’s what i’ve been doing with for small RODA project i have been working on over the past few weeks). But that’s not ideal, of course.

The new alpha now includes native Nougat CodeGen for your services, so you can generate an Interface .pas file and add it straight to your Nougat project — as it should be.

The new CodeGen is exposed in three places:

  1. Of course the codegen2.exe command line utility has been updated, so if you generate code from the command line, you can use the /lang:nougat option to have interface files written for Nougat.

  2. Service Builder has also been expanded to support Nougat alongside all the other languages (that menu is getting mighty big!):

Service Builder

  1. Finally, we also added Nougat CodeGen to our rodl2objc.app on the Mac (which is now really becoming overdue for a rename ;). While we were at it, we also revamped the UI for this tool a bit to make it (simple as it is) nicer to use, and look at:

rodl2objc

(and as the beta progresses, CodeGen will also be available directly inside the Visual Studio IDE, as well)

So with that you should be all set to build your first great client application for the Mac or iOS, using RemObjects SDK/Data Abstract and Oxygene “Nougat” over the holidays ;)

Let us know how it all works out!

yours,
marc

Avatar of marc

by marc

Getting started on truly native Mac and iOS development with Oxygene “Nougat”

November 10, 2012 in Cocoa, iOS, Mac, Nougat, Oxygene

In preparation for “Nougat Beta 2″, our next milestone coming up in a couple of weeks, i wanted to sit down and write up a quick “getting started” article on how to get going with Mac and iOS development in Nougat, including some aspects applying to Mac and iOS development in general (i.e. whether using Nougat or Xcode) that we should not take for granted for people w/o existing Xcode background to know.

Setting up Shop

While Nougat itself works inside Visual Studio 2012 on Windows (for now), it also interacts with some infrastructure on the Mac side that needs to be set up in order to get going. Nougat provides the CrossBox helper application that bridges this gap and allows Visual Studio to hand off tasks to the Mac as needed (and to communicate with iDevices attached to the Mac for on-device deployment and debugging).

Install “Nougat” using the setup we provide.

After you install Nougat on your Windows PC or VM, you will find a CrossBox.zip file in the install folder. Simply copy this zip file over to your Mac, unzip it and run the contained CrossBox.app. Done. (for now CrossBox.app requires Mono because it is a RemObjects SDK for .NET server).

CrossBox

To do any reasonable work with Mac and iOS development, you will also need a copy of Xcode installed on your Mac. You can get Xcode for free on the Mac App Store (and sometimes you can get newer beta versions at developer.apple.com).

Note that different versions of Xcode come with different versions of the iOS and OS X SDKs. At the time of this writing, the latest version of Xcode is 4.5.2, and it contains iOS 6.0 and OS X 10.8. Nougat lets you build applications for different versions of these SDKs, but you will need the matching version of Xcode. So if you want to build your application against iOS 5.1, you will need the older version of Xcode, 4.4, that comes with iOS 5.1. Similar, if in the future there’s a beta of, say, OS X 10.9, you will need the proper version of Xcode that comes with that beta.

You can have multiple copies of Xcode installed on your Mac, and you can select the active version in two ways:

  1. In Xcode (whatever version), you can invoke Preferences (⌘,) and on the Locations tab you will find a popup where you can select the version to be active for “command line tools” (which is what Nougat will use):

    Selecting an Xcode Version

  2. Via the command line (i.e. in Terminal.app or via ssh), you can run

sudo xcode-select --switch /path/to/Xcode.app

to select which version of Xcode.app is active (you can also call xcode-select with the –print-path option to see which version is currently selected — in fact, that’s what CrossBox does to decide which version it uses).

With that, you’re almost done. For Mac development (or iOS development with the Simulator), you would be all set, but for creating iOS applications that run on your iDevices, or to create Mac apps for the Mac App Store that use iCloud, you need to set up a developer account with Apple, and create and download some profiles and certificates.

Assuming you went ahead and created a developer account (for either iOS or Mac development or both) at developer.apple.com, simply go into Xcode and open the Organizer (choose Window|Organizer from the main menu, or press ⌘⇧2). Select the Devices tab at the top and the Provisioning Profiles item in the source list of the top left.

If you’re already set up in Xcode, you might see some items, if not, the list is most likely empty. Worry not, simply press the Refresh button on the bottom right and Xcode will automatically reach out to developer.apple.com and download or create the necessary certificates and profiles to get you started. When done, your Organizer window should look something like this (but probably with fewer items):

Organizer Window

At the very least, you should see profiles called “iOS Team Provisioning Profile: *” and/or “Mac Team Provisioning Profile: *”, depending on which programs you signed up for.

Not displayed here, matching code signing certificates should also have been created in the Keychain for you, called “iPhone Developer: X” or “Mac Developer: X”, where X is your name.

With this, you’re all set on the Mac side, so let’s switch over to Nougat in Visual Studio on Windows and start your first project. For this topic, i’ll walk you thru an iOS project, as that is the more complex scenario compared to OS X.

Your First iOS App

In Visual Studio, select File|New|Project, and browse for the Oxygene Nougat folder. For now, Nougat has a handful of templates, but this number will increase over the beta period and for RTM next year. Right now, let’s pick the “Universal Master/Detail App” to create an app that can run on both iPhone and iPad. This template will use Storyboards for the UI, but we’ll go into those in a future topic.

New Project

Once you press OK, the project will be created and the AppDelegate.pas file will open in Visual Studio. The template already creates a basic runnable application, so let’s ignore the code for this article and focus on building and running the app as is.

As first step, you will want to have a look at the “CrossBox” menu item in the Visual studio toolbar. If you’re freshly starting out, Nougat probably doesn’t know about your Mac running CrossBox yet. There’s two ways to rectify that:

  • Our recommended approach is to install Bonjour on your Windows PC or VM, if you have not already done so (or gotten it as part of, say, iTunes). With Bonjour, Nougat will automatically find local Macs running CrossBox, and you should see them in the CrossBox menu when you click it open. Simply select your Mac and choose Connect.

  • If you don’t want to use Bonjour, or your Mac is remote, no worries: simply choose Add Server… from the CrossBox menu, and you can manually enter the address of your Mac to connect:

    Add Server

No matter which way you picked your Mac, the very first time a connection is established, you will need to authenticate. This is to prevent just any random Nougat user on the local network (or even the internet, if you use CrossBox on a Mac at a remote location) connecting to your Mac and running their apps there. On the Mac side, CrossBox will show a four-digit number in the menu bar, next to the little Oxygene icon (and on Mountain Lion or later, you will also see a Notification Center message pop up). Simply enter that code in Visual Studio on the Windows side and you are set.

You won’t have to do these steps again (unless you get new Mac or a new Windows PC or VM, of course).

Nougat can maintain a list of several Macs running CrossBox, so if you — like me — have a desktop and a laptop running CrossBox, you will see both in the menu, and can choose where to run your apps.

With that setup out of the way, open the CrossBox menu again, and underneath your Mac’s name you should now see the different device options to build for:

CrossBox Meu

  • iOS Simulator: This option, obviously, lets you build your iOS app as i386 executable that can be run in the iPhone or iPad Simulator.

  • iOS Device: This option represents a generic iDevice and allows you to build your app for deployment, even if no real device is found (you can compile, but not deploy or run when this option is selected, obviously).

  • Peter’s iPhone: Any real iDevice you have connected to your Mac will show up here as well.

For now, select your real device name, if you have one, or select iOS Simulator if you don’t.

We could build and (probably) run the application now, but lets have a quick look at some of the project options for Nougat applications before we do. For that, right-click the project node in Solution Explorer and choose Project Properties (or choose Project|Properties from the main menu).

Project Settings

Most of what you see here will be familiar from Oxygene for .NET and Java, but there’s a handful of new options.

First let’s look at the Nougat tab:

Per-config Options

There are two important options here. The first is the Provisioning Profile Name. As you can see, Nougat automatically obtained all the profiles from Xcode on your Mac already.

Every iOS app needs a profile to govern installation on devices, so it is important that you choose one here. By default, the “iOS Team Provisioning Profile: *” is a good choice; as you create other profiles manually on developer.apple.com, you can select them here.

Along with the profile goes a certificate that will be used to sign your application. As mentioned before, Xcode automatically created one for you, and to start with, your best option is to select that. Each profile is tied to a specific certificate, so as you create more profiles for real app deployment, you might or might not choose to create different certificates as well. It is important to select matching pairs of profile and certificate, or device deployment will fail.

You will notice that the settings on this page are “per-configuration”, and as you get ready to ship your app, it will be common to use different profiles and certificates for your Debug vs. your Release builds.

Two other settings on this page might be interesting.

The first is the list of Architectures. Nougat is fully capable of creating what Apple calls “Universal Binaries”, which are executables that contain code for more than one CPU type. When we started out with Nougat early this year, we thought it would be a while until anyone would see this support (since we’re not supporting 32-bit Mac apps), but Apple surprised us by introducing a new CPU type, “armv7s” with the iPhone 5′s A6 processor. So here you can choose what CPU types you want your app to support; in general it makes sense to support both, which is the default. (If you uncheck “armv7″, your application will only run on the iPhone 5 and iPad 4; if you uncheck “armv7s”, your app will run on any modern iOS device, but not fully leverage the A6 or A6X.)

The second option is “Create .IPA”, which instructs Nougat to automatically package up your app into an “.ipa” file that is ready to be uploaded to the App Store or sent to beta testers, for example via testflightapp.com.

Let’s switch over to the Application tab, which contains general project-wide options, some of which are specific to Nougat:

Per-project Options

The first crucial option is the Target SDK, which determines the version of iOS your app is built for. If you simply select “iOS” (or “OS X” for a Mac app), your app will automatically be built with the latest version of the SDK. But you can also select a specific version, for example if you always want to build your app with the older iOS 5.0 SDK, instead of 6.0.

As mentioned before, you will need a matching version of Xcode that contains the SDK you are building against.

Closely related to the Target SDK is the Deployment Target. This setting (optionally) specifies the lowest version of the OS that your app will run on. Different than what you might be used to from Windows, OS X and iOS bind very loosely, so it is entirely possible to build an application against the latest iOS 6.0 SDK and make use of new features from that OS version, and still have the application run on older versions of the OS (provided of course you are careful at runtime to not use features that aren’t available). This option enabled this, and i’ll explore some code techniques for conditionally using newer SDK features in a future article.

If you have an older device that does not run iOS 6 yet, now might be a good time to set the Deployment Target of your project to, say, 5.0.

An option that becomes important when you start creating your own provisioning profiles is the Application ID, as it will have to match the ID specified in the profile you use. The default wildcard profile we saw before will work with any ID, so if you use that, the value here does not matter (much).

There are some more advanced options such as Output type or a custom Entitlements File for code signing that go beyond the scope of this post.

Run!

So, having reviewed these project settings, your app is ready to build and run. Simply press the Start button and Nougat will do the rest; after a few seconds, you should see your app be deployed to the device and start up in the debugger.

Mac Apps

For a Mac app, things work similar, but are less complicated to set up initially.

Once again, choose File|New|Project, this time selecting the Cocoa Application template.

New Project

In the CrossBox menu, you will see only one “device” is available for each CrossBox server, and that is the Mac itself. Select the option on the Mac that you want to build and run your app on (if there’s more than one), and you’re set. As above, simply press Start and your app will build and after a few second it will pop up on your Mac’s desktop

The project settings for Mac apps are similar to those we have seen for iOS. You can pick a provisioning profile (but you only need that if you are using iCloud in a Mac App Store app), and you can (and should, but don’t need to) pick a certificate to sign your app.

Only one architecture is supported for OS X apps right now: 64-bit intel. Nougat does not support 32-bit, because, frankly, that is a thing of the past and a legacy architecture. And despite recent rumors, ARM-based Macs are probably still a few years away ;).

Summary

Hopefully this has given you a quick introduction on how to get set up and get started with Oxygene Nougat to create Mac and iOS apps. The steps outlined here are based on “Beta 2″ which we plan to have out to testers within the next couple of weeks, but most of it should already apply to the current “Beta 1″ drops that are available now.

Of course, details and the workflow might be subject to change and further fine-tuning between now and RTM next year.

How can you get your hands on the beta? Easy: If you already bought your copy of Oxygene, simply head over to beta.remobjects.com and get started now. If you haven’t, well, what are you waiting for: shop.remobjects.com.

Let us know what you think!