You are browsing the archive for Mac.

Avatar of marc

by marc

iOS 7 and OS X Mavericks

June 17, 2013 in Cocoa, Data Abstract, Elements, iOS, Mac, 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 Alex

by Alex

Data Abstract for Cocoa: New methods for adding rows

June 5, 2013 in iOS, Mac

In the last release we have introduced two new methods in the DADataTable which allows adding new row with data in one go

The first one is public -addNewRowWithDataFromDictionary:inEditMode:

It returns new row with values from specified dictionary which contains key-value pairs with field name as the key and value – as value for given field.

NSDictionary *data = @{
  @"WorkerBirthDate" : date,
  @"WorkerLastName"  : @"Doe",
  @"WorkerPosition"  : @"Boss",
  @"WorkerFirstName" : @"John"
};
 
DADataTableRow *row = [table addNewRowWithDataFromDictionary:data inEditMode:NO];

Since it takes a dictionary, and we know to what field given value belongs, then there is no matter in what order you will put the data – it can differs from order of fields in the table.

This method also perform some basic validation. If you will specify value for field which does not belongs to the table then it throws an exception saying that given field does not exists in the table.

I also need to say few words about adding rows for tables with autoincrement fields. As you might know, when you insert new row to the table with autoincrement key, Data Abstract, at the client side, will provide temporary key value. It is an negative integer value in order not to interfere with existing positive values.

-addNewRowWithDataFromDictionary:inEditMode: method does not allow you to specify custom value for such autoincrement key. Though it does not firbid to change temporary key value before sending an updateData request.

To avoid ambiguity, if you include value for autoinc field to the dictionary then adding new row will throw an exception saying that you cannot specify custom value for autoincrement field.

So general recomendation here will be – If your table has an autoincrement key field then just omit passing its value. It will be generated automatically.

And finally you don’t need to pass values for ALL fields. You can specify only ones you need. It also can be handy for setting defaults.

The second method -addNewRowWithDataFromArray:inEditMode: is less safe. It just takes an array of values for new row. Thus, orders of values here plays the very important role. There is no special validation and checkings of the passed arrays. So you must be sure what you are passing there.

For these reasons, we make this method as internal. You can use it when import proper header file like shown in code snippet below.

The benefit in using this method is in its simplicity and conciseness.

#import <DataAbstract/Internal.h>
...
NSArray *data = @[
   [NSNull null],
   @"Bond",
   @"James",
   date,
   [NSNull null],
   @"Spy"];
 
DADataTableRow *row = [table addNewRowWithDataFromArray:data inEditMode:NO];

As I’ve said, order of values here is important so when I want to skip value for certain field then I need to pass a null object there.

Avatar 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 remobjects.com/oxygene and wiki.oxygenelanguage.com.

 

Yours,

marc hoffman
Chief Architect,
RemObjects Software

Avatar of marc

by marc

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

March 27, 2013 in Data Abstract, iOS, Mac

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

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

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

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

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

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

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

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

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

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

What is Data Abstract?

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

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

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

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

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

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

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

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

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

Summary

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

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

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

Let us know what you think!

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

Yours,
marc hoffman

Chief Architect,
RemObjects Software

Avatar of marc

by marc

Using Instruments with Oxygene to Profile your Mac and iOS Apps

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

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

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

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

Let’s say you have the following code:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

type
  DummyDataItem = class
  private
    fOwner: weak DummyData;

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

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

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

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

Success!

 

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

Oxygene on the Big Screen

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

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

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

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

Avatar of marc

by marc

Working with User Interface files in Oxygene “Nougat”

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

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

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

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

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

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

Background: What are XIB Files?

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

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

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

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

Loading up an XIB

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

 

NSMainNibFile

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

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

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

initWithNib:*

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

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

How does this work?

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

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

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

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

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

Connections

Did i say connections? So how does this work?

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

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

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

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

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

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

Let Me See This in Action

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

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

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

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

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

Figure 1

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

Figure 2

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

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

Figure 3

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

Figure 4

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

Figure 5

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

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

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

Terminology: XIB vs. NIB?

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

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

What’s “First Responder”?

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

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

Summary

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

Footnotes

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

Avatar of marc

by marc

Using RemObjects SDK and Data Abstract with Oxygene Nougat.

December 25, 2012 in Cocoa, Data Abstract, iOS, Mac, Nougat, Oxygene, 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

Oxygene “Nougat” BETA 2 is out!

December 3, 2012 in Elements, iOS, Mac, Nougat, Oxygene, Visual Studio

On Friday, we shipped BETA 2 of Oxygene “Nougat“, the next major platform for our Oxygene language (in case you have missed it or have been living under a rock, Nougat is “Oxygene for Cocoa” and brings your favorite programming language to native Mac and iOS development. You can read more about it here and in my previous blog posts).

Jim also recently spent some time on a great “Oxygene Overview” video that went live today and gives a first peek at Nougat, too.


 

It’s been about 8 weeks since we shipped BETA 1 (and we shipped updated builds to testers more or less weekly since then), and the team has been really busy and made great progress on all fronts. BETA 1 was a very early look at the product — it was still very rough, the “this is what you need to know to get started” list was way long, and many things did not (by design) work yet. But we wanted to let the early adopters get started, and we’ve gotten great feedback for this first part of the beta cycle.

BETA 2, out now with build .1139, is a lot more robust, should provide a fairly decent “out of the box” experience to get started, and — most importantly — sees most core functionality working decently.

BETA 2 supports running and (still limited) debugging of Mac apps (Cocoa and console) and iOS apps on both the Simulator and actual devices. BETA 2 has fully integrated the deployment toolchain, so that with the press of a single key (F5, a.k.a. “Start”), your app gets compiled, linked, packed up, code signed, and uploaded to your device. The compiler has been vastly improved in BETA 2, with lots of bugs fixed and lots of features and improvements all thru-out; the corresponding IDE experience has improved as well, for example with code completion and related editor smarts fully understanding the new “multi-part” method name syntax, everywhere.

Of course we still have miles and miles to go before we reach RTM. As promised from the get-go, we are shooting for a release of “1.0” (or rather “6.0”, as it may be) in the “first half of 2013″. Now, we strongly plan for that to not mean “on June 30″ (we’re not Apple ;), but we are taking our time to get everything right, and we do still have a good 5-6 months ahead of ourselves in terms of getting Nougat to final.

But, we also know that you are anxious to get started, and a lot of you have been holding off jumping into the dangerous waters with BETA 1. But if you are at all adventurous and inclined to live on the edge a bit, BETA 2 (and its continuing semi-weekly updates) is as good a point to get your feet wet as any.

So what are you waiting for? Assuming you have already ordered your copy of Oxygene, head over to beta.remobjects.com to grab your copy of “Nougat” BETA 2 now! Make sure to check out my “Getting Started” post, as well.

(If you don’t have Visual Studio 2012 installed yet, grab the latest Oxygene for .NET or Java installer from here first, and then install the Nougat beta on top (this will upgrade all three editions to the latest bits)).

Also, don’t forget to let us know what you think — leave your comments here, or join the discussion in our private beta forum at connect.remobjects.com/categories/nougat-beta.

Yours,
marc

Avatar of marc

by marc

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

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

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!