You are browsing the archive for iOS.

Avatar of marc

by marc

“Native platform development is going to be the approach”

September 12, 2012 in Android, iOS, non-tech

Mark Zuckerberg about the new native Facbeook app (via Appleinsider, The Verge):

“Native [platform development] is going to be the approach that we go with for iOS and Android”. “We’re betting completely on it.”

Smart thinking, and much in line with our own philosophy on the matter.

He goes on:

“The biggest mistake we made as a company was betting too much on HTML5 instead of native [platforms],” and, “We burnt two years.”

Avatar of marc

by marc

What is “Nougat”? — Part 1

September 12, 2012 in iOS, Mac, Nougat, Oxygene

When we launched our new Oxygene website and Oxygene 5.2 last week, we also gave a sneak peek at an upcoming new edition/platform for Oxygene, codenamed “Nougat“.

This is the first in a series of posts about “Nougat”, in which i want to go into a few more details about our plans and the technologies behind Nougat, so you can get a feel for what to expect from the product, as we wait for the first beta to be made available.

So what, exactly, is Nougat?

Nougat is a third independent target for the Oxygene language and compiler, targeting the Apple Cocoa and Cocoa Touch development platforms.

More strictly speaking, Nougat is Oxygene for the Objective-C Runtime.

What does that mean?

Similar to Java, the term Objective-C has overloaded meanings. Of course there is Objective-C, the language, which is what most people think of when they hear the name. It’s the language that Apple’s Xcode IDE uses to let developers create native applications for both of its platforms: (Mac) OS X and iOS.

But underneath the language (and to a large degree influencing how Objective-C as a language works) lies the Objective-C Runtime (OCR, for short). That runtime (oversimplified, a set of C APIs) defines how objects look in memory, manages run-time type information, handles the passing of messages (a.k.a. method calls) to objects, and so on.

The way i like to think about it, the Objective-C runtime puts Cocoa someplace in the middle of “managed” platforms (such as .NET and Java) and “unmanaged” development architectures such as Delphi or C++. So when talking about this, i often call Objective-C “half managed”.

“Nougat” brings the Oxygene language to this Objective-C runtime, in that it compiles Oxygene language code into objects that natively live in this runtime, and seamlessly interact with other objects in the same runtime. It is not a “bridge” (such as MonoTouch, RubyCocoa, or the (now deprecated) Java/Cocoa Bridge, but a fully native second language — in no way second to the Objective-C language itself — that runs on this runtime.

This is important for several reasons:

You’re creating true Objective-C objects

The classes your define in your Nougat application will compile down to true OCR objects. The runtime will see these objects and interact with these objects in the same way that it does with objects created by an Objective-C developer in Xcode. In fact, the runtime cannot even tell them apart.

When you, say, define

type
  RootViewController = class(UITableViewController)

then this “RootViewController” class you are defining will be a true descendant of UITableViewController — with no bridging magic inbetween. If the table view sends a cellForRowAtIndexPath: message to get data to display, the runtime will dispatch that call directly to the cellForRowAtIndexPath() method that you hopefully implemented.

You’re interacting with true Objective-C objects

Just like your classes are true Objective-C classes, all the classes and object instances you interact with will be true Objective-C classes, as well. If you hold a string object, that’s a true NSString instance, and if you are calling

myString:hasPrefix('foo')

you are simply sending the object the hasPrefix: message, just as an Objective-C developer would be with [myString hasPrefix:@"foo"]. (Note that Objective-C’s message sending is nil-safe, and thus corresponds to Oxygene’s colon operator, while a call such as myString.hasPrefix('foo') would throw an exception on nil calls, as you would expect from Oxygene code.)

No awkward manual mappings

Just to be completely clear, there is no manually defined “mapping” between APIs defined in Cocoa and the APIs Oxygene sees (or vice versa), as there is in most Cocoa bridge solutions. There’s no magic table in Oxygene that tells the compiler how to match a call to hasPrefix('foo') to the right method on the NSString.

The Oxygene compiler, instead, simply has full direct knowledge of the Objective-C APIs and does those calls directly — just as Objective-C itself would: it takes the name, packs it up in a selector, and calls the OCR’s objc_mmsg_send() function.

In fact, if you have a variable of type dynamic (or, aliased to that type, id), Oxygene will let you make just about any known method call on that object, just like Objective-C does.

Beautiful Cocoa-style method calls

This also means that Oxygene has full support for Objective-C’s more verbose method naming convention — something that is crucial, really, as a developer would want to interact with the Cocoa APIs as they have been designed and intended (for better or for worse — i personally find Cocoa beautiful).

I purposely picked a simple and uncontroversial example with hasPrefix: above, but what Cocoa APIs are known for are of course the infamous “muti-part” method names, where the method name reads like a sentence with the individual parameters interspersed in between. Consider for example stringByPaddingToLength:withString:startingAtIndex:. How would you call this in Oxygene?

Most bride-based solutions go for one of two options: they would either provide an (often overloaded) method named after just the first part, e.g. stringByPaddingToLength(20, " ", 5) or they would concat the entire name into one big chunk of text, such as stringByPaddingToLengthWithStringStartingAtIndex(20, " ", 5).

For one, yuck. For another, this would require manually crafted mapping tables, which Oxygene does not use — as explained above, Oxygene just handles the Cocoa APIs, any Cocoa APIs, straight up.

So how do you call this method in Oxygene? Simple:

myString.stringByPaddingToLength(20) withString(' ') startingAtIndex(5);

Simple, elegant, and it preserves the “readable as a sentence” aesthetics of the underlying API. What’s more, the syntax seamlessly works with any method an OCR object might declare.

The same goes, of course, for declaring methods in your own classes — both when implementing things such as delegates, but also when designing your own class APIs in Cocoa style:

method stringByPaddingToLength(aLength: Integer) withString(aString: String) startingAtIndex(aStartIndex: Integer);

What’s Next?

With this first post, we have only just begun to scratch the surface of “Nougat”. Stay tuned for more in this series over the next few weeks.

Oh, and be sure to buy or renew your copy of Oxygene now to be among the first to get access to Nougat when the beta hits early next month.

And let us know what you think in the comments below!

See also part 2 . . .

Avatar of marc

by marc

The new Oxygene website (Oh, and some exciting new Oxygene announcements, too)

September 6, 2012 in iOS, Mac, Metro, Nougat, Oxygene, Platforms, Visual Studio, Windows

Yesterday, we launched the major revamp of our “Oxygene” product homepage, available at remobjects.com/oxygene, along with announcing the 5.2 release, a significant update to the product.

Let’s have a quick tour of the new content.

What’s New in 5.2

First, and most importantly, there’s the updated What’s New page, updated to list the new features in 5.2 and providing back access to previous release notes as well.

5.2 introduces some significant (and dare i say ground-breaking) improvements to error handling, with better fix-it support, auto-fix-its for select (safe to fix) issues and — my personal favorite – the new Treat Fixable Errors as Warnings, which can be an enormous timesaver if you just wanna code and test some quick changes. Of course there’s much more to 5.2 — such as our new IDE-integrated Gendarme Code Analysis, support for language-native tuples, Visual Studio 2012, Metro, and more.

Nougat

Next to 5.2, the second biggest announcement has been the first peek at “Nougat“. Nougat is the codename for a new (third) platform for Oxygene, namely Cocoa and the Objective-C runtime for creating truly native Mac and iOS apps. Right now it is just a teaser — we’ll be releasing more details about “Nougat” here on the blogs over the next few weeks.

The good news is that “Nougat” is already part of our new Oxygene shop SKU — so anyone buying (or renewing) Oxygene now will be among the first people to see the Nougat beta (roughly within the next month) and get the final product when it ships in 2013.

We’re very excited.

The Language

The new website also contains a sizable new section focusing on the Oxygene Language and its Object Pascal heritage. We have five pages detailing the most exciting language features. We also have an overview of Oxygene evolved over the years (even i rediscovered cool features i had forgotten about, as i wrote this page ;), and Jim has written an excellent history of the Pascal Language since the 1960s, including a cool diagram that shows how it all fits together:

History of Pascal

The Platforms

Finally, there’s a new section that looks at Oxygene from the perspective of target platforms. With the introduction of Nougat, Oxygene now literally covers every single major target platform that matters today — from desktop and mobile to the server. The Platforms page serves as a central point to discover all the possibilities Oxygene opens up, and for most platforms, links to a dedicated “platform hub” page with details, links and videos about using Oxygene for the platform.

Jim has also created an excellent new WPF Development with Oxygene video to go along with the “Windows Desktop” platform, which, oddly, was underrepresented in the video department.

We expect this section to grow and expand over time, with more potential targets added, and the information for each target getting more comprehensive.

One More Thing: Sugar

Hidden away on the page about the three supported core Frameworks, you’ll find another sneak peek at something we are working on: an open source cross-platform base library for Oxygene, built on the awesome Mapped Types feature introduced in Oxygene 5.1.

Having a cross-platform language such as Oxygene is great, and one of Oxygene’s strong points is that it targets the platform-native APIs on each platform. The downside is that even the base types — simple stuff such as Strings or Dictionaries — can vary widely between platforms, making it tough to share code of any reasonable complexity.

The goal of “Sugar”, which is the codename of this project, is to create a toll-free mapping library that will allow Oxygene developers to write common code that will compile for all three platforms and work with the platform’s base types using a shared API.

This is even cooler than it sounds ;)

The Shop

Before we forget: of course the new Oxygene 5.2 is available now at $499 for new users — that includes all three platforms. Users coming from Prism XE2 (or our own Oxygene for Java) can renew for $349 — which also includes all three platforms.

We also have cross-grade pricing for users of Delphi. If you currently use Delphi, you can cross-grade to the full Oxygene package (again, you guessed it, all three platforms) for $399.

Let us know what you think!

Over the past month or so, we have put a lot of work into the new website. Let us know what you think, like, dislike, or are missing.

Of course even more work and sweat has gone into Oxygene 5.2 (in my humble opinion our most solid release yet, and i am very proud of what the team has delivered), and work already continues to go into the upcoming September and October interim releases, and towards “Nougat”

If you haven’t yet, try Oxygene — we have a free 30-day trial version for the .NET and Java editions. We hope you like what you see, and please do let us know what you think!

yours,
marc

Avatar of marc

by marc

Comparing Data Abstract and Core Data (with and without iCloud)

August 6, 2012 in iOS, iPad, iPhone, Relativity, ROFX, Xcode

People often ask us what the difference between Core Data and Data Abstract is, and why they should choose one over the other.

The answer to that second question frequently is “it depends”, because while on first glance Core Data and Data Abstract might seem like technologies that solve the same problem (“database access”), they are actually quite different technologies, and designed with very different goals.

Core Data is, in essence, a local data access technology and ORM. It is designed around the concept that your application has a certain data model, expressed as a suite of objects, and wants to persist that data between runs (or to save runtime memory footprint), locally. As such, Core Data is largely a front-end for SQLite (although it supports other storage options) that abstracts the developer from dealing with the actual database storage, table structure, and SQL queries, and exposes data as regular in-memory objects that magically persist.

Don’t get us wrong, that is an awesome feature for many scenarios, and Core Data is a great solution in that space.

Data Abstract on the other hand is designed around the concept of data stored on a “big” server somewhere on the network, off your iDevice or Mac, or “in the cloud”, and that the database on this server (or these servers) contains data that is shared between many users of the application (which of course does not mean that each user cannot have their own private set of data).

These servers could be anything, from an existing database in a large Oracle cluster that already provides the backbone for an enterprise, to a fresh database you just designed solely for your iOS app. The target application could be anything from — say — a view into said enterprise’s customer relations system, over an iOS front-end to your web site, to the client app for the next Social Network you are building.

To achieve this, Data Abstract is build around the so-called Multi-Tier concept, where the client applications you build using Data Abstract talk to a “middle tier” server that enforces data consistency and access restrictions.

 

The central difference between Core Data and Data Abstract is that the former is focused around simplifying how an app can persist its application state locally, while the latter is designed around accessing, presenting and working with data that exists elsewhere, usually (but not necessarily) in a context that is much larger than an individual application and an individual user.

So Core Data and Data Abstract aren’t really that much in competition, but target pretty different scenarios. In most cases where Core Data is a good solution, Data Abstract would be overkill or even useless, and in the cases where you need what Data Abstract provides, Core Data won’t do much good.

But What About Core Data in iCloud?

On first glimpse, it might seem as if the new Core Data Syncing via iCloud expands Core Data onto Data Abstract’s turf. And to a certain degree that is true; iCloud certainly expands what you can do with Core Data, but there are still some pretty severe limitations.

When Steve Jobs took the stage at WWDC in 2011 to announce iCloud, he gave the reason why iCloud was going to be better than previous syncing technologies: Rather than syncing information between devices he said that with iCloud the “truth, is in the cloud”, and each device — iOS or Mac — syncs against a well-known set of data in that single location.

That is the right way to do it, and that is how iCloud works in general, but: it is not how Core Data syncing via iCloud works, unfortunately.

At the time of this writing, Core Data syncing via iCloud consists of each client storing change logs in the cloud and these diffs getting transferred between devices. In other words, iCloud syncs Core Data between devices, without a single truth “in the cloud”. As Drew McCormack has outlined in his excellent series of articles on the topic, this comes with a myriad of problems, caveats and corner cases to look out for.

This is, of course, in sharp contrast to how data access with a multi-tier solution such as Data Abstract is handled. Data Abstract’s model (or any other database-centric multi-tier architecture) does put the truth in the cloud, just as Steve Jobs suggested it should be.

Another crucial limitation of Core Data is that any data it stores in iCloud is still an island: it can only be accessed by the applications that created it, and is isolated per user. That is fine for many scenarios (e.g. in cases where you’re 100% focused on in-app presentation), but imposes some serious limitations, such as:

  • not being able to provide a web-based front-end to user’s data outside of their iOS apps.
  • not being able to provide access to the user’s data on iOS/Mac on the one side, and client applications on other platforms (be it Android, Windows, or even just non-App Store Mac) on the other.
  • not being able to offer options for users to share data among themselves, or share data publicly.

Also, the fact that data is self-contained within each user’s store means that as the application developer, you have no access to it, for example to investigate if users are reporting problems. On the one hand, this is a win for user privacy, as users only need to trust Apple with their data, not you as the App Vendor, but on the other, it severely limits what apps can do and how you as an app developer can trouble-shoot or assist users when they have problems with their data.

So, Which Option Should You Choose?

Indicators that Core Data is the right solution would be:

  • You have a fairly straightforward data model and not more data than can easily it on the device.
  • Your data is internal to the application, and you never want to use it outside of the app (aside from, say, letting the user explicitly export it).
  • Your entire data is tied to a single user and you have no need to share (part of) the data between different users of your app.

Indicators that you might want to use Data Abstract include:

  • You are building a front end to already existing data managed in a database (e.g. an app for your Enterprise database).
  • Your app’s data is part of a larger data infrastructure shared (in parts) by all or some users of your app.
  • Your app’s data should be accessible (in parts) outside of the application itself, for example via a web site.
  • Your app’s data should be available on platforms not covered by iCloud, for example Windows or Android clients.
  • Users of your app should be able to share (parts of) their data, whether explicitly or implicitly.
  • Your application contains shared data common to many or all users.
  • You want or need full control and access to the data and how it is stored.

The one advantage of Core Data, of course, is that it works “out of the box” with just the user’s devices, and (optionally) iCloud, and you do not need to worry about setting and maintaining any database and server yourself.

If your application can live within these constraints, that can be a significant saving in both cost and management effort. But in most cases, you either need the extra flexibility of hosting the data yourself, or you don’t — and if you do, Core Data and iCloud give you absolutely no wiggle room and hosting your own data will be the only solution.

Data Abstract makes that easy and cost efficient too, and with our free Relativity Server that can be hosted on just about any co-located server and on many cloud services, such as Amazon EC2, you can be up and running with your own hosted middle-tier quickly.

Interested?

If this got you interested, please check out some of our other resources on Data Abstract for Xcode (and for our other platforms) to see what DA can do for you and how to get started.

In particular, i recommend reading the first available chapters of our “Data Abstract for Xcode Book” and to check out the videos on RemObjects TV, especially Introduction to Data Abstract for Xcode narrated by yours truly and Relativity Server Overview.

And of course we have a free 30-day trial versions of Data Abstract for all platforms.

We hope you will find Data Abstract useful — and don’t hesitate to contact me directly or our support team if you have any questions.

— marc

Avatar of marc

by marc

It’s Podcast Time!

July 5, 2012 in Cocoa, iOS, Mac, non-tech, Oxygene, Podcast, Relativity, ROFX, Xcode

i know it’s been a while since we have put out an episode of RemObjects Radio, and we apologize for that.

In the meantime however, there have been some other podcast events that might interest you:

  • Yesterday, i had the honor of being invited to join Scotty and John of iDeveloper TV for Episode 58 of their podcast, aptly entitled “More than Two Tiers”.

    We ended up spending pretty much the entire hour of the show talking about Data Abstract, Relativity Server and general technical concepts, challenges and ideas related to multi-tier database access from the perspective of Mac and iOS developers.

    You can find the episode to download and listen to here, although i really recommend subscribing to the entire podcast series, as John and Scotty just do an awesome job of providing information for Mac and iOS developers week after week (and RemObjects Software is proud to have been supporting the show thru sponsorship from day one).

  • Last month, Jim was on the IMI tech Talk Podcast and talked about Augmented Reality, Google Glass and more. Have a listen, Jim’s segment starts around 12 minutes into the episode and goes on thru the end (note that unfortunately the .mp3 link on that page seems to be wrong; the direct link to the right mp3 is here).
  • Finally, the Podcast @ Delphi.org turned the tables in late May, making regular host Jim McKeeth the interviewee in honor of the 50th episode of Delphi developer’s favorite podcast. While the episode touches on many topics, Jim, Jamie and Stuart spend a good deal of the time discussing RemObjects-related topics, including the Oxygene language and compiler, our cross-platform development philosophy, and a lot more. Go check it out here.

Using Remote Commands with Data Abstract for Xcode

June 5, 2012 in iOS, Mac, ROFX, Xcode

Recently, we have added some new functionality to the DARemoteDataAdapter for working with Data Abstract Commands.

Let me briefly refresh your memory about what Commands are and when they can be helpful.

Data Abstract Commands are part of the DASchema and represent a reference to certain Database Stored Procedures or just keep custom SQL expressions we need to execute.

The most common commands perform INSERT/UPDATE/DELETE actions for given tables.
In addition, they can be used to perform calculations in the database and return the results to the user.

Before now, we could only perform command calls by using the DataAbstractService_Proxy directly.
I’ve posted the workaround for that some days ago Support for RemoteCommands in DA/Xcode?.

But with the next release it will be much simpler.

To execute commands from the sample mentioned above, we just have to perform the following code:

[remoteDataAdapter executeCommand:@"Insert_BPWorkers" 
      withParameterValuesAndNames:@"John1",        @"FirstName",
                                  @"Doe1",         @"LastName",
                                  @"444-22-33-22", @"Phone",  
                                  [NSDate date],   @"BirthDate",
                                  @"Manager",      @"Position", nil];

The same can easily be done in an asynchronous way.

But let me show you how it works on a more complex sample with stored procedures that have output parameters.
Imagine you have an MSSQL database with the following simple TestStoredProcedure:

CREATE PROCEDURE [dbo].[TestStoredProcedure] 
  @groupId INT = 0, 
  @name nvarchar(255) OUTPUT,
  @COUNT INT OUTPUT
AS
BEGIN
  SET NOCOUNT ON;
  SELECT TOP 1 @name = p.Name FROM Products p WHERE p.GroupId = @groupId;
  SELECT @COUNT = COUNT(*) FROM Products p WHERE p.GroupId = @groupId;
  RETURN 157;
END

As you have noticed, this stored procedure returns @name & @count as output parameters and some “magic number” as the result. So let’s use it.

Note
Don't forget that Data Abstract doesn't work with the database objects directly, 
but with schema objects (tables, commands etc).

If you need to get back the output parameters, you need to use the ExecuteCommandEx method.

Beside the usual arguments like command name and parameters, it takes another NSDictionary as the output argument which will contain the output values.

The code for the asynchronous call will look something like this:

 
-(IBAction)callTheCommandEx:(id)sender {
  NSString *COMMAND_NAME = @"TestStoredProcedure";
  NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:10], @"groupId", nil];     
  DAAsyncRequest *request = [dataAdapter beginExecuteCommandEx:@"TestStoredProcedure"
                                                withParameters:params 
                                                         start:NO];
  [request setDelegate:self];
  [request start];
}
 
     - (void)asyncRequest:(DAAsyncRequest *)request 
didFinishExecutingCommand:(NSString *)commandName 
               withResult:(int)result 
          andOutputParams:(NSDictionary *)outParams
{
    NSLog(@"Called ExecuteCommandEx for %@ with result %i", commandName, result);
    NSLog(@"%@", outParams);
}

Or the same but using blocks:

-(IBAction)callTheCommandEx:(id)sender {
  [dataAdapter beginExecuteCommandEx:@"TestStoredProcedure"
                      withParameters:params 
                           withBlock:^(int result, NSDictionary *outParams) {
                                        NSLog(@"Called ExecuteCommandEx for %@ with result %i", @"TestStoredProcedure", result);
                                        NSLog(@"%@", outParams);
                                     }];

In both cases we’ve got the following results:

Called ExecuteCommandEx for TestStoredProcedure with result -1
{
    "RETURN_VALUE" = 157;
    count = 42;
    name = "APC ProtectNet PNET1GB";
}
Avatar of marc

by marc

What, exactly, is “native” development?

April 19, 2012 in Android, iOS, Mac, Metro, non-tech, Oxygene, Platforms, ROFX, Windows, WP7

Some developers, mostly those tied to unmanaged languages such as C++ or Delphi, define nativeness as compiling directly to the byte code expected by the physical CPU. That’s certainly one way to look at it, but we think it’s imprecise, and doesn’t take into account the full picture and the complexity of today’s software systems. Consider this for example: if you compile an application for x86, and then run it on a x64 CPU – is that really “native”? Arguably not.

CPU-native, unmanaged code, is becoming less and less relevant these days, and we believe true nativeness of code, of applications, and — most of all — of the developer experience defines itself by other criteria.

Here at RemObjects, we pride ourselves on providing truly native software development solutions for a variety of platforms. We consider two different and separate levels to determine what we consider “native” development: a native user experience, and a native developer experience.

A Native User Experience

What makes a native user experience? For a long time, there was only one platform for mainstream development: Windows. This has changed, and users are, by and large, choosing their work environment by preference. Even when avoiding to get into the “OS wars”, it cannot be disregarded that each platform out there today has its own distinct user paradigms, and that customers usually choose their computing platform carefully and want their applications to work and behave well on that particular system, adhering to their platform’s paradigms.

Windows users expect applications to behave “the Windows way”, and Mac users want them to work “the Mac way”. Similarly, iOS users want applications for their iPhones and iPads that fit in with that platform’s design philosophy, and Windows Phone (7) applications once again need to adhere to completely different UI paradigms than what Android users expect from their platform of choice.

Obviously, the degree to which applications need to fit in with their surrounding platform varies — most games, for example, usually sport more esoteric and platform-independent UIs (after all, they aim to take you out of your daily routing and immerse you in an entertainment experience), while business and productivity applications usually should adhere to the platform most strictly.

Nativeness also isn’t purely driven by using stock UI controls and themes exactly as prescribed. For example, many of the most famous and most well-respected iPhone applications add subtle textures or nuances to the OS provided controls. But they continue to feel “native”, because they stick to the basic UI paradigms, and the controls — while looking visually refined — look, feel and, most importantly, behave according to the user’s expectations.

This is generally achieved by using what is often referred to as the “native widget sets” of the platforms. Whether it’s a standard Win32 “Button” control or a native Mac NSButton, each widget set provides its own unique look and feel — from the spacing of text within the confines of the surrounding rectangle, over font sizes, styles and gradient strengths and directions, to the intricate details of how the control reacts and animates when it is clicked or touched. These subtle details are ingrained in the user’s mind; the user has subconscious expectations for how the control will feel when used, often down to the timing of animations. What may seem like unnecessary attention to detail becomes crucial to the user’s experience, and the user will feel an “Uncanny Valley” effect, if their expectations are not met.

But nativeness extends beyond just user controls. Most operating systems provide a lot of general infrastructure that users are used to seeing and working with — from the standardized Open/Close or Print dialogs on desktops to OS-provided Email or Tweet sheets on phones.

We believe that in order to create a truly native user experience with your application, your development tools need to let you work with the native widgets and infrastructure of the platform. No matter how much effort is put into “one size fits all” libraries, no cross-platform button will ever truly feel like a standard Windows button, like a standard Mac button, like a standard iOS button. In order to treat your customers to a truly native application, you need to choose a development tool chain that lets you work against the native platform.

Currently, such tool chains include .NET/WPF, Metro/WinRT, Delphi/VCL (for Windows), Objective-C/Xcode (for Mac and iOS), MonoMac and MonoTouch (for Mac and iOS, respectively), Java (for Android) or MonoDroid (also for Android).

It goes without saying that here at RemObjects we try to support developers with all of these tool chain choices. On the compiler side with Oxygene, we don’t have full coverage, but we can provide support for .NET and WinRT, all the Mono variations, as well as native Java/Android with our new Oxygene for Java. With our Data Abstract product suite, we have you covered on literally each and every one of the combinations listed above.

But: we believe that a native user experience, while key, is only half the story for successful app development.

A Native Developer Experience

Back in the day when Win32 was the gold standard of operating system APIs (and before), developer tools needed to provide strong abstraction layers for developers to work against — because the OS APIs themselves were so basic that working against them directly was akin to working in assembly language (or was, in fact, working in assembly).

When tools like the later Turbo Pascals, Visual Basic, or Delphi first came out, development against the core DOS or Win16/Win32 APIs was a chore, so developers welcomed abstraction layers that made coding easier, from basic class libraries to UI abstraction layers such as TurboVision, OWL, the VCL, or MFC.

But platforms have evolved, and with the likes of Microsoft’s .NET and WinRT, Apple’s Cocoa (and Cocoa Touch) or Android’s Java-based Dalvik, OS APIs have long reached a level that is developer friendly, a level that can and should be coded directly against.

Further abstractions on top of these APIs are a distraction, not a help to the developer, as they add an extra layer of unnecessary overhead to both the application and the development experience. And such abstractions have repeatedly shown to be failures, like when VCL.NET tried to reconstruct Delphi’s well-liked class library on top of the (already much more evolved and sophisticated, but orthogonal and thus incompatible) .NET Framework (then at early version 1.1).

Unnecessary abstractions of already good (or great) APIs serve no purpose to the developers using them. On the contrary, they separate developers from the platform, and from each other. For every article, sample or blog post provided by, say, Apple or the Cocoa community that shows how to use a feature of iOS, there has to be the equivalent “and here is how you do it in MonoTouch”, “and here is how you do it in FireMonkey”, “and here is how you do it in …”. The abstraction keeps developers from being able to (re)use the platform vendor’s documentation or samples. Worse, it fragments the developer community on the same platform, keeping programmers from interacting and sharing code — every Cocoa control written in MonoTouch is a Cocoa control that can’t be easily reused by a developer using the native Xcode/Objective-C toolchain (nor by a developer using FireMonkey, or Titanium, or any other abstraction layer).

Abstractions also keep developers from adopting new platform features quickly and easily. When the latest SDKs from the platform vendor come out, developers using the native tool chains usually can start working with the new technologies from day one (or even earlier). The very moment a new Android SDK hits, native Java developers can consume the new APIs. The very day a new iOS version becomes available, Cocoa developers can start getting their fingers dirty with the new goodness. All the while developers stuck behind a non-native abstraction layer need to wait for their tool vendor to abstract the new APIs for them.

Not to mention that non-native development tools will often lock you in and force you to stick with the abstraction layer.

The main selling point and attractiveness of a non-native tool chain usually is “familiarity”, the notion that the abstraction layer will let you get into a new platform without the steep learning curve of, well, learning a new platform.

But that is misleading and frequently turns out not to be the case. The main learning curve on a new platform is usually not the development language, or even the class framework — it is getting to know the platform itself and how to write great applications for that platform (looping us back to our first criterium: the native user experience).

Working with an abstraction layer turns out to actually have the opposite effect than intended, by making it harder to understand the platform vendor’s documentation (which is all tailored towards the platform-native tools, of course) and making it harder to re-use existing code samples found online.

To go back to the example of iOS: having to look at and understand documentation or samples written for Cocoa’s Objective-C APIs might seem difficult, if one is not yet familiar with the paradigms of Objective-C. But what’s actually more difficult is having to look at that same documentation or sample and then having to figure out how it translates to your — say — C#-based abstraction layer.

And no abstraction layer is ever perfect. Eventually, the underlying platform and its APIs will leak through and will have to be dealt with. Any efforts to avoid getting to know and understand the platform before developing on it is misguided and only delays the inevitable. Eventually the abstraction is missing a feature and the developer has to dig down to the base APIs and implement it themselves. Or a bug arrises that needs more debugging than the abstraction layer supports.

As with the native user experience, here at RemObjects Software we have made it our mission to support (and encourage) developers to use platform-native development tools; you’ll notice we’ll even encourage developers to go for the more native tool chain in cases where recommending a less native solution would mean an additional sale for us.

On the compiler front, Oxygene supports platform native development on classic Windows, Metro (Windows 8) and Android, and it is also a great choice for cross-platform servers based on Mono. The one notable omission is iOS and Mac, for which we recommend the excellent Xcode and Objective-C, even though Oxygene can support it via non-native development tool chains such as Mono and MonoTouch or Java.

With the Data Abstract suite, we support native development for all current major platforms: classic Windows (via .NET and Delphi), Windows Phone, Mac and iOS, as well as Android and other Java-based platforms (Data Abstract for Java is currently in beta).

Other Concerns, Such as Code Reuse

We realize of course that other factors play into the decision for the development tool chain. Considerations such as code reuse might rank higher on the list of priorities than a native development experience, and that is ok.

Our philosophy is that, all other things being equal, developers should aim for a toolchain that is native on both accounts: user experience and developer experience. If necessary, a compromise in developer experience can be made — it is after all a compromise that affects only the developer, if pursued correctly. No compromise, in our experience, should ever be made with regard to providing a truly native user experience.

In terms of code reuse between platforms, we at RemObjects Software aim to help, both on the language front (by providing the common Oxygene language as developer-native language for .NET, WinRT and Java/Android, at least) and on the back-end database front, by keeping Data Abstract wire compatible and letting you share a common server infrastructure for all your native client applications.

Read More

You can find out more about our cross-platform, platform-native products, Oxygene and Data Abstract, at remobjects.com/oxygene and remobjects.com/da, respectively.

And you can find an overview matrix of how our products fit into the various native (as well as semi-native and non-native, if you must go there) development chains, at remobjects.com/products/toolchains.

Thank you for reading, and we are looking forward to your feedback and comments.

Tools and Abstractions on iOS

April 16, 2012 in iOS, iPad, iPhone

I just came upon this Hanselminutes episode from back in February with John Sonmez about MonoTouch and Mono for Android, and it even mentions PhoneGap. If you are interested in working on iOS with any tool, I recommend you listen to the podcast, as he discusses the pros and cons of the different levels of abstraction and how to get the most out of the level you choose.

What do you think about his points on the different levels of abstraction? Remember, whatever level you choose we’ve got you covered with Data Abstract and RemObjects SDK for Xcode, .NET or JavaScript.

Creating a Data Abstract client widget – Part 4

March 9, 2012 in iOS, iPad, JavaScript, ROFX

This is the 4th article in a 4 part series (the last for now)

  1. Using DashCode to create an interactive widget
  2. Creating an interactive widget without Dashcode
  3. Creating a RemObjects SDK client widget
  4. Creating a Data Abstract client widget (this article)

In this article we will look at Data Abstract client widgets created without using Dashcode.
Read the rest of this entry →

Creating a RemObjects SDK Client Widget for iBooks – Part 3

March 1, 2012 in Books, iOS, iPad, JavaScript, ROFX

This is the 3rd article in a 4 part series

  1. Using DashCode to create an interactive widget
  2. Creating an interactive widget without Dashcode
  3. Creating a RemObjects SDK client widget (this article)
  4. Creating a Data Abstract client widget

If you are new to creating widgets, take a look at the previous articles where I outline creating them with Dashcode and without. This article discusses using RemObjects SDK in both Dashcode widgets and in iBooks 2 on the iPad via iBooks Author.

When I first heard that iBooks Author supported interactive widgets powered by JavaScript, I immediately wondered if it would work with a widget that was a JavaScript client for a RemObjects SDK server. I started using Dashcode to create the widget, so that is where we will start in this article.

Read the rest of this entry →