You are browsing the archive for Uncategorized.

Profile photo of Alex

by Alex

Strong Typed Rows in the DataAbstract for Cocoa

September 1, 2014 in Uncategorized

Challenge

In DataAbstract for Cocoa, you can retrieve the values for a particular table field using the KVC approach, where the field name is passed as a string key:

DADataTableRow *row = [[self table] rowAtIndex:idx];
NSString *name = [row valueForKey:@"ClientName"];

Later, with help of the new indexing syntax for arrays and dictionaries, this code can be rewritten in a more simple manner:

DADataTableRow *row = self.table.rows[idx];
NSString *name = row[@"ClientName"];

But there is one flaw to that approach – the field name is passed as a string constant and thus can’t be checked in design time or selected in the code completion system.
The user still has to work with DADataTabeRow instances, where data is represented by the dictionary, rather than by business objects.

Solution

With the help of some “Magic” in Objective-C, we can now offer another approach for getting values for a particular column in a row.
You can just operate with a particular field in the table row as with a usual property.
This means that you can call any property in a row instance like this:

id fieldValue = [self.dataTable.rows[idx] MyFieldName];

If there is no such field in the table, you will get a proper exception, otherwise you will get its value.

It would also be great though if we could choose available fields using the Code Completion system inside the IDE.
This would simplify the code and allow to avoid various possible mistakes in specifying field names when working with data of the row.

And the answer is yes, we can do that.
All we need to do is to represent the available table fields as properties of a special protocol (interface) that the row can support.

This approach can be used in two ways:
The most simple way is to just generate protocols ad later cast the row instance to the row protocol. For example:

 
// Protocol
 
@protocol DepsTableRow_Protocol <NSObject>
@property (strong) NSString *DepName;
@property (strong) NSNumber *DepId;
@property (strong) NSString *DepPhone;
@end
 
 
// Code for obtaining data 
 
id row = self.dataTable.rows[0];
id<DepsTableRow_Protocol> typedRow = row;
NSNumber *depId = [typedRow DepId];
NSString *depName = [typedRow DepName];
NSString *depPhone = typedRow.DepName;// you also can use dot(.) for accessing field property
 
NSLog(@"%@(%@): Phone:%@:", depName, depId, depPhone);

Another approach is to provide a special row class for the particular table.
This class must be inherited from the base DADataTableRow class, but in addition, it can expose different properties:

//Protocol:
@protocol DepsTableRow_Protocol <NSObject>
@property (strong) NSString *DepName;
@property (strong) NSNumber *DepId;
@property (strong) NSString *DepPhone;
@end
 
// Custom row class 
@interface DepsTableRow : DADataTableRow <DepsTableRow_Protocol>
// you don't need to implement DepsTableRow_Protocol for declaring its properties
@end
 
// Code for obtaining data:
// First we need to register our custom row class for the particular table
// It should be done once per application start 
// The init method of the DataAccess module is usually a good place for doing that
[DADataTable registerRowClass:[DepsTableRow class] forTableName:@"Deps"];
 
// then later each row in the table rows array is the instance of our custom row
DepsTableRow *typedRow = self.dataTable.rows[0];
NSNumber *depId = [typedRow DepId];
NSString *depName = [typedRow DepName];
NSString *depPhone = typedRow.DepName; // You can use a dot(.) to access fields as properties
 
NSLog(@"%@(%@): Phone:%@:", depName, depId, depPhone);

Supporting Strong Typed Rows in Nougat

The same approaches are also available for Nougat projects and Oxygene:

// Protocol
DepsTableRow_Protocol= public interface
    property DepName: strong NSString read write;
    property DepId: strong NSNumber read write;
    property DepPhone: strong NSString read write;
end;
 
// Code for obtaining data 
var row: id := self.dataTable.rows[0];
var typedRow : DepsTableRow_Protocol :=  duck<DepsTableRow_Protocol>(row);
 
var depId := typedRow.DepId;
var depName := typedRow.DepName;
var depPhone := typedRow.DepPhone;
 
NSLog("%@(%@): Phone:%@:", depName, depId, depPhone);

and for RemObjects C# (Hydrogene):

// Protocol
public interface DepsTableRow_Protocol
{
    __strong NSString DepName { get; set; } 
    __strong NSNumber DepId { get; set; }
    __strong NSString DepPhone { get; set; }
}
 
// Code for obtaining data 
id row = self.dataTable.rows[0];
DepsTableRow_Protocol typedRow = duck<DepsTableRow_Protocol>(row);
 
NSNumber depId = typedRow.DepId;
NSString depName = typedRow.DepName;
NSString depPhone = typedRow.DepPhone;
 
NSLog("%@(%@): Phone:%@:", depName, depId, depPhone);

Generating protocols

The one remaining question is how to get those row protocols?

For Nougat projects created in MS Visual Studio, these protocols will be generated automatically by the New Project Wizard.
You can also update/regenerate these protocols any time you want – just run the wizard by clicking Create Table Definition Classes in the Solution Explorer window. TableDefinitions Wizard

For Xcode projects, you can generate the protocols directly from the schema node inside the Relativity Server in the Server Explorer for Cocoa tool. It allows to generate Objective-C, Oxygene and RemObjects C# protocols for Nougat projects. TableDefinitions Generator

Samples

Take a look at the StrongTypedRows (iOS) samples written in Nougat, Oxygene and RemObjects C#. We are providing them with the DataAbstract for Cocoa package.

Thanks for reading!

Profile photo of Alex

by Alex

Using DataAbstract and RemObject SDK for Cocoa libraries in Swift

September 1, 2014 in Cocoa, Uncategorized

As you probably already know, Apple recently announced a new programming language called Swift, a new and fresh look at programming for the Mac.
The main and obvious purpose of Swift is to replace Objective-C in the future.

To develop for the Mac, RemObject Software offers two products, DataAbstract for Cocoa and RemObject SDK for Cocoa.
These products are designed using native Apple technologies and are written in Objective-C.
They are available as frameworks and as static libraries.

This brings us to the important question: Can I use existing libraries written in Objective-C in a program written in Swift?

The answer to that question is yes.

In order to access classes from Objective-C libraries from Swift, you need to create a so-called Bridging Header File and name it according to your product module name followed by -Bridging-Header.h.
Then you need to edit this file to expose your Objective-C code to your Swift code.
Just import every Objective-C header you want to expose to Swift. In our case, this will be the root Data Abstract header:

//
//  DAWithSwift-Bridging-Header.h
//
 
#import <DataAbstract/DataAbstract.h>

Then go to the project settings and locate the “Swift Compiler – Code Generation” section at the “Build Settings” tab, where you need to specify the bridge header file for the “Objective-C Bridging Header” build setting.
The path must go directly to the file itself, not to the directory it’s in.
The path should be relative to your project, similar to the way your Info.plist path is specified in Build Settings.
For example:

DAWithSwift/DAWithSwift-Bridging-Header.h

Also, do not forget to set the other build options to allow your application to locate and link it with the RemObjects libraries:

Library Search Path = "/Developer/RemObjects Software/Bin/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"
Other Linker Flags = -ObjC -all_load -lxml2 -lDataAbstract

And that’s it, now all public Objective-C headers listed in this bridging header file will be visible to Swift.

The Objective-C functionality will be available in any Swift file within that project automatically, without any import statements.
You can now use DA/RO classes with the same Swift syntax that you can use with system classes.

 
//SWIFT
 
// Set up rda and server access
var dataAdapter: DARemoteDataAdapter
let url: NSURL = NSURL(string:"http://localhost:7099/bin")
self.dataAdapter = DARemoteDataAdapter(targetURL:url)
dataAdapter.dataService.serviceName = "DataService"
println("dataAdapter: \(dataAdapter.dataService.channel.targetURL)")

At the moment, most of Swift is covered by the Apple NDA until it is released, but after that we are going to simplify even those steps above.

Thanks for reading!

Profile photo of marc

by marc

Announcing Elements: Oxygene 7 and RemObjects C#

March 2, 2014 in Uncategorized

Dear readers,

we’ve shipped some pretty significant releases this past weekend that i wanted to take a moment to talk to and update you about.

First, and probably most interesting to our existing users, we shipped version 7 of Oxygene. This is a pretty significant new release of our Oxygene language and toolchain, with many cool new features that we are very excited about. As always, you can find an overview of What’s New and a Full Change Log on our website, but i also want to go into some of the improvements in more detail.

Most exciting to me, personally, is the introduction of LINQ for the Cocoa and Java platforms. LINQ has always been one of the modern language features on .NET that i found really helpful, because it brings a clean structured way to working with filtering, sorting and otherwise manipulating lists of objects — in a type-save manner. With Oxygene 7, this feature, and most standard LINQ query operations, are now available across all three platforms. This means that you can now use LINQ syntax to sort or filter NSArrays on Cocoa for example.

One example i saw mentioned just yesterday that i would never have thought of is to use LINQ to find a particular view in your Cocoa app:

var wideView := (from v in view.subViews where v.frame.width > 300).FirstOrDefault

As you can see, LINQ is useful in many areas, not just when working with what we traditionally think of as “data”.

But LINQ is not the only item where we have updated the language to bring the platforms closer together. Multi-part method names, originally introduced because “we kinda needed them” for Cocoa are now available on all platforms. Many of you (and many of us) really liked this feature as a regular language syntax, and we saw no reason to hold it back to be Cocoa-only — so you can now write expressive and readable APIs for your classes, regardless of platform. We’ve also unified support for Iterators, the notify keyword and anonymous classes across all platforms, and added a bunch of standard attributes commonly used on .NET across platforms, via Aspects.

If you read between the lines, you gather that cross-platform is a big theme for this release, so we’ve also added a new Cross-Platform Compatibility Mode to the compiler. By default, Oxygene is strict about platform differences — when you write code for .NET, it tries to be a good .NET citizen; if you write for for Android, it is a good Java citizen instead. Turning on the Cross-Platform Compatibility Mode option (which can be done per-project or per-file), this dynamic changes. The compiler will be more lenient, and let it slide if you use a syntax feature needed on one platform, but not on the other. For example, you might want to mark a file as weak for Cocoa, and the compiler will simply ignore that keyword on .NET. The compiler will also be more helpful in letting you know when you write code that won’t be cross-platform. This way, when you’re set to build for .NET and write shared code, you’ll get early warnings if a language feature you are using might be problematic on Cocoa or Java, for example.

Finally, there’s the big one: Sugar. Sugar has been in the works for a while, and finally is being included as “version 1.0” officially in this release. What is Sugar? Sugar is a library of cross-platform classes that you can use on your code, so that you can share it across all three platforms. All three platform — .NET, Cocoa and Java — provide their own versions of basic types, from strings over dictionaries to XML processing, HTTP requests or file system access. Code that uses those APIs will often be platform-specific, without needing to be. Sugar provides a way to write base “business logic” code for your applications that can be easily shared between different platforms — for example if you are writing the same app for iOS, Android and Windows Phone. And it does this in a smart way (using mapped classes under the hood) that comes with no runtime overhead, even when crossing from platform-specific code into shared code and back.

These are the four whoppers, but there’s a lot more good stuff in Oxygene 7 that we think you’ll love. And as always, Oxygene 7 is of course a free update to all users with an active subscription.

But that’s not all!

Introducing RemObjects C#

In addition, we’ve also shipped a brand new product based on the same tool chain as Oxygene — a sister project to Oxygene, so to speak, and that product is called RemObjects C#.

You may have heard us talk or hint about RemObjects C# before under the code name “Hydrogene”, and that code name really illustrates well what RemObjects C# is in relation to Oxygene: It’s an implementation of the C# language for Cocoa, Java (and of course .NET), based on all the principles that make Oxygene great. In essence it is “Oxygene for people who’d rather use C#”.

RemObjects C# has all the things that make Oxygene great — a unified language and tool set that allows you to compile for the .NET CLR, for the Java JVM and for Cocoa’s Objective-C Runtime. It has the same great editor features — from our inline errors to Fix-Its. It has our Visual-Studio integrated debugging support for Java and Cocoa. It uses our CrossBox toolchain for deploying, running and debugging your applications on your Mac, your iOS or Android devices or the emulators/simulators right from Visual Studio. The only thing that’s different is the language itself.

RemObjects C# is a 100% true and ECMA—spec conform implementation of the C# language that millions of developers already use to build .NET apps. Except — like its sister product Oxygene — that language is now available to target the other development platforms as well.

Leaving the language aside, Oxygene and RemObjects C# will, from now on, evolve in parity, because they use all the same technologies under the hood (including even the most parts of compiler, except for the language front-end). So RemObjects C#, despite being a brand new product, immediately builds upon over a decade of experience and work that went into the underlying toolchain. And moving forward, 90% of the work we invest in the product will benefit both languages.

Which Language to Choose?

We approach the development of the two languages slightly different and that might influence that decision.

Oxygene has always been “our” language. Ever since we started off in 2003 with a language that already then provided vast improvements over the “standard” Object Pascal implementation in Delphi, we’ve been driving and improving Oxygene aggressively. As a result, Oxygene is one of the most powerful, versatile and expressive mainstream development languages out there today. And we will continue in that fashion — Oxygene will evolve, and get better and better

C# is a language designed by Microsoft, and well-defined in an ECMA specification. For our implementation, we tried to stay as close to that specification as we could (and only extend it in clean, tasteful and spec-conform ways, where really necessary). We will continue developing RemObjects C# in that fashion — we will evolve it as the official C# language evolves, but we will not be adding our own language features to it, just because we think they’d be neat language features. We feel that C# is not ours to evolve.

So if you’re already die-hard Oxygene (or Pascal) fan, and you want a language that’s advancing quickly and embracing new language features that enhance your development experience often, you will most likely want to stick (or start with) Oxygene. If you’re already a C# developer (or generally prefer other C-based languages) and/or not a big fan of Pascal, then RemObjects C# is the language for you.

Of course you don’t necessarily have to choose at all. You can use Oxygene and RemObject C# together. In fact, because both languages are built on the same back-end compiler, you can even use them together in the same project.

Ways to get Oxygene or RemObjects C#

As already mentioned, Oxygene is of course a free update, if your subscription is active as of March 1 — and if it’s not, now is as good a time to renew as ever.

Similarly, RemObjects C# is of course available at no extra charge to all customers with an active Suite subscription for the appropriate platforms (i.e. .NET, Cocoa or Java). If you’re a Suite subscriber, you should see new “Elements” SKUs for download on your licensed downloads page — these will install both Oxygene and RemObjects C#.

We also have the following purchasing options available.

For new users:

  • Oxygene is available at $699 per user, including all platforms — same as it has always been.
  • RemObjects C# is also available at $699 per user, including all platforms — in other words: same as Oxygene, just a different language.
  • The bundle of Oxygene and RemObjects C# is available at $999 per user, including all three platforms and both languages.

For current Oxygene users:

  • If your Oxygene subscription expired, or expires soon, you can renew at $499 for another year of upgrades to Oxygene.
  • If you want to add RemObjects C# to the mix, you can renew both for $699. Only $200 extra, and you get a whole new language — we think that’s a pretty sweet deal. Also, both Oxygene and RemObjects C# will get the same new renewal date — so if your current Oxygene subscription is still good for a while, that’s an extra benefit for renewing early.
  • Finally, if you just want to add RemObjects C# to your existing Oxygene license (and with the same renewal date), you can do that for just $399 (but really, the previous item at $699 is the better value, no matter your current subscription status).

The first two of thee options are also available to all customers of Prism XE3 or later, who currently enjoy a complimentary license extension to Oxygene for .NET from us as part of their SA coverage.

We’ve also recently made two adjustments to our online store (which also has been completely revamped and improved) that might benefit you:

First, if your subscription has expired more than 6 months ago, the store will now automatically apply what we call “amnesty renewal” when you purchase a renewal. Amnesty renewal makes sure that you always get at least the current release and six months of free updates from the purchase date. This holds true even if your previous subscription expired years ago.

Second, we’ve improved our volume discount program, so that you now start saving on multi-user license purchases for as little as 2 users. Volume discounts start at 5% (for two to five users) but can go all the way up to 30%. Our shop will handle all of that for you automatically.

That’s it for now

I think that’s it, for now (probably more than enough, wouldn’t you say? ;).

As you can probably tell, we are very excited by this new release — both with the new features added to Oxygene 7 (which, i should have mentioned, are all available to RemObject C# as well) as well as the brand new RemObjects C#.

We hope you enjoy them, too — and that if you’re not already a customer, you’ll grab the free 30-day trial and take the products for a spin. (It goes without saying that the RemObjects C# trial works well alongside your licensed copy of Oxygene as well.)

Oh, and last but not least: Scotty has created an awesome set of Getting Started videos for RemObjects C# (and similar videos for Oxygene are coming soon). Make sure to check them out!

Yours,
marc hoffman
Chief Architect

Profile photo of Scotty

by Scotty

Setting Up For Android Development with Oxygene

January 9, 2014 in Android, Cooper, Elements, Uncategorized, Visual Studio

The purpose of this article is to help you set up Oxygene ready to develop Android applications. It assumes you have already installed Oxygene, but will walk you through installing the Java and Android SDKs, as well as setting up a virtual Android device and configuring your physical device for development. If you have already been developing for Android using another platform or have already set these things up independently, you do not need to read this article.

Android is an operating system for devices such as mobile telephones and tablet computers developed by the Open Handset Alliance led by Google. Application development is focused on targeting the specialized Dalvik Virtual Machine (VM), which is a mobile-optimized VM similar to the Java VM. Oxygene ships with templates for creating Android projects, and produces both native Java JAR files and the Android APK file necessary for deployment to an Android device.

The Pre-Flight Check

Each time you create an Android project with Oxygene, it will do a ‘pre-flight check’ to ensure that it can locate the things it needs, notably the JDK and the Android SDK.

Java Pre-Flight Check

If you’ve installed them into custom locations and it fails to find them, this gives you an opportunity to specify the installation folders by selecting the “Manually Specify The JDK Path” link from the dialog.

Java SDK Paths

Java SDK

Oxygene requires version 6.0 or later of the Java Development Kit (JDK) to be installed. For Windows, we recommend installing the “x86″/”i586″ release of version 7 JDK.

If you have not yet installed the JDK, you can download it from here.

Installing the JDK simply involves downloading the installer and running it, accepting all the defaults.

Install JDK

Once the JDK is installed, click Retest on the Pre-Flight Check dialog. If all has gone well, the dialog should change to report that the Android SDK is missing.

Android SDK

To create Android applications, Oxygene requires the Android SDK to be installed, in addition to the JDK.

If the JDK is installed, but not the Android SDK, the Oxygene pre-flight check will report this.

Android Pre-Flight Check

Download The Android SDK

The Android SDK can be downloaded here.

For Windows, we recommend using the .exe installer available under the “SDK Tools Only” section that is displayed when you expand the “Download for Other Platforms” area of the SDK download page , as it will automatically register the Android SDK with the system so that Oxygene can find it.

Android SDK Download

NOTE: If you download the .zip version of the SDK and manually extract it, you will need to manually configure the path to the Android SDK in the IDE options, as described further down on this page.

NOTE: If the Android SDK installer complains that the JDK cannot be found, that may be because you have the x64 version of the JDK installed (see above). Simply install the x86 (i.e. 32-bit) as well to solve this problem.

Once you have downloaded the Android SDK Installer, run it and accept all the defaults.

Android SDK Installer

After installing the Android SDK, setup will automatically offer to launch the Android SDK Manager. Leave this checked.

Android SDK Installer Finished

The SDK Manager

In the SDK Manager, check to install the “Android SDK Platform-tools” and at least one API version (usually the newest) and click “Install Packages” to install.

Android SDK Manager

In the subsequent dialog you will need to accept any licenses that apply and press “Install” again.

Android SDK Manager License

You should periodically run the SDK Manager to check for any updates to the tools and platforms.

Android Virtual Devices

When the tools and platforms are all installed, you might want to create an Android emulator, also known as an Android Virtual Device or AVD. This will allow you to test your application, in case you don’t have an actual device (or don’t want to use your device for development).

AVD’s are created from the Android Virtual Device Manager, which is accessible from either the SDK Manager by choosing Tools – Manage AVDs or by starting the AVD Manager program directly or from the Oxygene Visual Studio tool bar.

Launch AVD Manager From Visual Studio

The AVD Manager

The first time you launch the AVD Manager there will be no configured AVD’s.

Android Virtual Device Manager

Create an AVD

To create a new AVD, click the “New” button. You will need to give the emulator a name. The AVD manager is pretty strict about what characters you can use in an AVD name, but will warn you when you use invalid characters.

Define a Device

The quickest way to set up an AVD is to emulate an actual device the DVD Manager already knows about. If you select the Device drop down, it will offer you a number of different Google devices it can emulate along with a set of generic devices.

AVD Device Selection

If one of these predefined devices match the type of device you are targeting, then simply select it from the list.

If none of the devices in the list match the device you wish to target, you can set up all the fields in the AVD manager manually. For a full list of settings check out the AVD Hardware Options Documentation.

Select an API

You will also need to select the API level for the Target field. You can choose any installed API level, for example Android 4.4 – API Level 19.

AVD Target Selection

Device Memory

When you choose a predefined device it will set the RAM setting for the AVD to match the actual device. In practice, this number may be too high to properly emulate and you could get a warning.

AVD Memory Warning

In this case, you will probably need to adjust the RAM setting to something more appropriate. (What’s appropriate will depend on the amount of memory in your development machine.)

Save The Device

Once the AVD is defined, click OK to save it. You will be shown a dialog confirming all the settings that will be used to create the AVD.

Save Setting Dialog

On clicking OK, the new AVD should now appear in the list of available AVD’s. If the AVD seems to be fully configured correctly, it will have a tick next to it in the list.

AVD in List

Test The Device

Once you have created an AVD, you can run it by selecting it in the list and clicking the “Start” button.

You will be presented with some launch options where you can simply click OK unless you need to change something.

AVD Launch Options

The AVD will then begin to start.

AVD Start Progress

After a few seconds, a blank emulator screen will appear. From this point, depending on the spec of your development machine, it could take several minutes for your device to appear in the emulator.

AVD In The Emualtor

Testing Your AVD Setup

Now you are ready to test your setup. Leave the device running. From within Oxygene, start a new Android Application Project.

New Android Project

This will create a very simple Android Template Application. Click the “Start” button on the Visual Studio tool bar and Oxygene will build your project and deploy it to the emulator where you should be able to see it running.

New Android Project Running In Emulator

Setting Up An Actual Device

AVD’s are great for testing your application on devices you don’t own. If you do however own a device, you can test your application right on the device itself. In many ways this is preferable to using an AVD, as you get to see exactly how it will run and perform.

Enable USB debugging on your device

Before you can debug an Android application on your device, you need to enable it for USB debugging.
On Android 4.0 and newer, you need to go into Developer Options and turn it on.

NOTE: On Android 4.2 and newer, Developer options are hidden by default. To make them available, go to Settings > About phone or Settings > About Tablet and tap Build Number seven times.

Once turned on (if necessary) you can find Developer options in Settings > Developer options.

Android 4.4 Developer Options

If your device is running Android 3.2 or older, you can find the Developer options under Settings > Applications > Development.

Install USB Drivers For the Device

In order to connect to an Android device to test your applications, you need to install the appropriate USB driver. This page on the Android Developers website provides links to the web sites for several original equipment manufacturers (OEMs), where you can download the appropriate USB driver for your device. However, this list is not exhaustive for all available Android-powered devices. The page also gives information on how to install the driver once you have it.

Running Your App On The Device

Once the USB driver is installed for your device, make sure the device is connected to your machine. From Oxygene you can then choose to debug your application on your device by selecting your device from the Crossbox area of the Visual Studio tool bar.

Select Android Device

The first time you run your application from within Oxygene on your device, a dialog will appear asking for permission.

You Are Ready To Go

That’s it. You are now set up and ready to begin developing Android applications using Oxygene.

Good Luck!

New forum preview

October 14, 2013 in Uncategorized

In the last year, we’ve been looking into a better forum to replace Connect to overcome the issue it’s having with search and notifications and finally found one we liked: The new forum is Discourse and it will have all the previous posts from Connect. What we’d like to hear is your opinion of this forum and if everything works for you.

What this forum offers:

  • Better search results (for example: If you go into a category, it filters the search by that category)
  • Optional weekly mails about interesting topics
  • Proper notifications of replies

…and quite a few other features. Note that the current content is temporary and will be overwritten if/when we decide to move to this new forum. The forum can be found at talk.remobjects.com. At this moment all the posts up to July are visible. When we do the move to this new forum, all the connect posts will be copied over fresh, posts made to talk.remobjects.com now will stay. Our goal is to move to this forum as soon as we’re 100% sure there are no issues with it and all connect features are covered.

Profile photo of marc

by marc

Introducing the RemObjects “Beta” app for iOS and Android

June 26, 2013 in Android, Build System, Data Abstract, Elements, iOS, Uncategorized

We’re constantly trying to optimize the workflow for publishing and announcing beta releases. Oxygene has been on a weekly beta cycle for a long while now and we’re trying to get RO/DA onto a more regular (maybe bi-weekly-ish) cycle as well (i’ll be writing more about our upcoming plans for RO/DA over the next year or so, soon), and we want to make the process of publishing new beta builds easy for us, and the process of being notified about new beta builds easy for you.

As part of this, two changes have been made recently.

Firstly, if you have installed any beta build of a product post our May 2013 releases, our Everwood Update Check will now notify you not only of new release versions, but also of new beta builds being available – making it very likely you’ll be find out about new builds within 24 hours of actively using a beta product.

But we wanted to do more, and so we’ve started developing an app to keep the hard-core beta users amongst you even closer in the loop: Welcome to the “Beta” app.

“Beta” is a small app, available for iOS and Android on the respective app stores. The iOS version has been available for a couple of weeks now (i got it approved shortly before WWDC), and the Android version is live as of now. What does “Beta” do? Two things, really.

The most important thing, it will receive and show to you Push Notifications when new beta (or release) builds for your products are available. Are you anxiously awaiting the next Oxygene beta drop each friday afternoon? Your iPhone or your Android will now let you know!

So “Beta” will be useful even if you never ever run the app again, after the first time.

But you can also go into “Beta” at any time, to see the list of current beta and release products available to you, including a shiny “NEW” badge on builds shipped within the past two days. Over time, we might expand beta to show more info (such as to let you know whether a new build is covered by your current subscription or not, look at change logs, and more).

What does “Beta” look like? Here’s the iOS version:

(including a sneak peak at what it will look like on iOS 7), and here’s the Android version:

So where to get the app? You can get “Beta” on the iOS App Store and the Google Play store, respectively. In addition, we’ve also made full source for the app available on GitHub; of course it is written in 100% Oxygene, the client apps and the Push server.



Profile photo of marc

by marc

Hear me talk about WWDC and Oxygene for Cocoa on iDeveloper Live

June 20, 2013 in Uncategorized

I had the honor and privilege to be invited onto the iDeveloper Live podcast on Tuesday, mainly to talk about Oxygene, but Scotty and i also reminisced about WWDC, which took place the week prior, and we spend the first 15 or so minutes talking about iOS 7, OS X Mavericks and – most importantly, of course – the new Mac Pro that we’re both very excited about, before we dived into the core topic: Oxygene.

If you missed listening to the stream live on Tuesday, the episode is up now, so you can download it, stream it in your browser, or of course subscribe to the entire podcast in iTunes.

I love the iDeveloper Live podcast, and its’s been great to be on it again. Make sure to also check out the other episodes, as well as the podcast sponsor, Invasive Code.

Profile photo of Alex

by Alex

Data Abstract Sample for Oxygene for Cocoa

June 17, 2013 in Uncategorized

Hi guys,

Recently I’ve spotted a question about Nougat samples in the support thread. Unfortunately, we didn’t offer any sample applications at that time, so I’ve tried to quickly compose one.

We’ve already proposed some New Project templates for Data Abstract for Cocoa though:

Nougat Templates

Using these templates, and after going through several steps in the wizard, we can get an almost complete data-aware application (we just need to review and adjust the code in several places marked with a #warning directive).

So I’ve started with this New Project wizard and created a client for the PCTrade sample domain exposed by Relatvitiy server.

In this sample, I want to show several things:

  • Working with Relativity server.
  • Downloading data at the client side in an asynchronous way.
  • Using Cocoa NotificationCenter.
  • Master-Detail navigation in the data.
  • Using Calculated fields for the DADataTable.
  • Conditional formatting of the table view cells.
  • The application should be universal and support both iPhone and iPad.

At the same time, I’ve tried to keep things as simple as possible to make it easy to understand common ideas.

So let’s start:

Working with Relativity domains

Almost all implementation required for connecting to the Relativity server, including autentication at the Relativity side, is done by the template and new project wizard. Most important places in the code are highlighted with the #warning directive. For example, in the DataAccess.pas file you can see the following place:

    {$WARNING  Define your server address and Relativity domain name, below.}
    const SERVER_URL  =                    'http://192.168.0.22:7099/bin';
    const SERVICE_NAME =                   'DataService';
    const RELATIVITY_DOMAIN  =             'PCTrade Sample';
    const DOMAIN_SCHEMA  =                 'PCTrade';

Here you can adjust the URL of your Relativity server (my server uses http://192.168.0.22:7099/bin).
These constants will also be used for configuring the RemoteDataAdapter instance.

Another place that requires our attention is in the AppDelegate.pas and holds the passwords to log in to the Relativity domain:

method AppDelegate.needLogin(var aLogin: String) password(var aPassword: String): Boolean;
begin
  // The DataAccess automatically takes care of storing login information in Settings and Key Chain
  // and retrieving it as necessary. This method is only called when no login is stored (i.e. on first
  // run) or if the retrieved login was rejected by the server.
  // Typically, you would implement this method to bring up the UI that asks the user for his credentials.
 
  // By default, new Relativity Server domains will use "Data"/"Relativity" as login, unless
  // the login provider setup has been changed by the administrator.
  aLogin := 'Data';
  aPassword := 'Relativity';
 
  result := true; // return YES if the user provided login details, or NO if the user canceled
end;

Of course, in the real application, you can implement a popup window here with to enter login and password, or even get credentials from the application preferences, but I’m trying to keep it simple here.

Downloading data

Again, like in the point above, almost all implementation for downloading data from the server was generated automatically by the new project wizard.

You may notice that all the tables we selected in one of the last wizard step, were created with the appropriate properties in DataAccess.pas and code has been generated to fill them.

method DataAccess.downloadData;
begin
  // ToDo: Add code to download data from server
  // You will need to define fields and, if necessary, properties for your tables.
 
  var tableNames := new NSMutableArray<String>;
  tableNames.addObject('Clients');
  tableNames.addObject('OrderDetails');
  tableNames.addObject('Orders');
 
  var tables := fRDA.getDataTables(tableNames);
 
  Clients := tables['Clients'];
  OrderDetails := tables['OrderDetails'];
  Orders := tables['Orders'];
end;

It is important to note here that the given downloadData method is called asynchronously (in a separate thread), so we get a responsive and non-frozen UI.

method DataAccess.loadInitialData;
begin
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), method begin
      ...
      downloadData();
      ...
      dispatch_async(dispatch_get_main_queue(), -> triggerDataReady);

Using notifications

Since we are downloading data in a separate thread, we need to notify our main UI thread with the results.
And here the Cocoa Notification Center comes in to help us.
In the code above you may have notice that after downloading the data, we perform a triggerDataReady call at the main thread. This method just posts a notification to the Notification Center that the job is done.

method DataAccess.triggerDataReady;
begin
  dataReady := true;
  NSNotificationCenter.defaultCenter.postNotificationName(NOTIFICATION_DATA_READY) object(self);
  NSLog('data is ready.');
 
  // ToDo: Add any processing you want to do once the data is fully ready
end;

Thus, if our controller needs to be informed about loading data results, we need to subscribe it to this notification. You can find the code in the ClientsViewController.pas file.

 
method ClientsViewController.viewDidLoad;
begin
  inherited viewDidLoad;
  // Do any additional setup after loading the view, typically from a nib
  ...
  NSNotificationCenter.defaultCenter.addObserver(self) 
                                     &selector(selector(dataReady:)) 
                                     name(DataAccess.NOTIFICATION_DATA_READY) 
                                     object(DataAccess.sharedInstance);
  ...
end;
 
method ClientsViewController.dataReady(notification: NSNotification);
begin
  tableView.reloadData();
end;

That means that when our ClientsViewController receives the DataReady notification, the dataReady: method must be invoked, which then refreshes the content of the table view.

Master-Detail navigation

This feature is part of the New Project template. By default, it generates already configured Master and Detail view controllers and the corresponding storyboards files with proper transitions between views inside.

Concrete implementation depends on device type.
For iPhone/iPod devices with their relatively small screens, when user selects a certain cell, the proper transition will be invoked and we can hook on it and set the info for the detail controller.

method ClientsViewController.prepareForSegue(segue: UIStoryboardSegue) sender(sender: id);
begin
  if segue.identifier.isEqualToString('showOrders') then begin
    var ip := tableView.indexPathForCell(sender);
    var tableRow := self.dataTable.rowAtIndex(ip.row);
    segue.destinationViewController.setDetailItem(tableRow);
  end;
end;

For the iPad device, the master and detail view are visible at the same time – no transition required. So we can just hook at the didSelectRow event and provide the details data for the detail controller as shown below:

method ClientsViewController.tableView(tableView: UITableView) didSelectRowAtIndexPath(indexPath: NSIndexPath);
begin
  if UIDevice.currentDevice.userInterfaceIdiom = UIUserInterfaceIdiom.UIUserInterfaceIdiomPad then begin
    var tableRow := self.dataTable.rowAtIndex(indexPath.row);
    OrdersViewController.detailItem := tableRow;
  end;
end;

About the details data: Since all necessary data is already present at the client-side, we are performing just a local data filtering using NSPredicates:

method DataAccess.OrdersByClient(client: String): NSArray;
begin
  var filterPredicate := NSPredicate.predicateWithFormat('Client == %@', client);
  result := self.Orders.rowsFilteredUsingPredicate(filterPredicate);
end;

Using Calculated fields for the DADataTable

As you might know, we can easily extend any existing DADataTable with our custom lookup and calculated fields which could help us get various related information. For this sample I need to know the amount of orders for each of our clients and also want to know the total for each client order (which can be calculated by summing the OrderDetails rows).

There is the special setupData method in the DataAccess class. It will be called while loading the initial data, so I can be sure that my tables will be extended in a proper way.

Declaring calculated fields is easy, we just need to specify the field name, its type and the target and selector for the method that will be used for calculation.

method DataAccess.setupData;
begin
  // Use this method to implement any setup that is needed on your data tables, such as
  // creating lookup or calculated fields, etc.
  self.Clients.addCalculatedFieldName('OrdersCnt') 
                            dataType(__enum_DADataType.datInteger) 
                              target(self) 
                           &selector(selector(calculateOrdersCntForClientRow:)); 
 
  self.Orders.addCalculatedFieldName('OrderSum') 
                             dataType(__enum_DADataType.datCurrency) 
                               target(self) 
                            &selector(selector(calculateSumForOrderRow:)); 
end;

As a rule, calculation methods take a row instance as the parameter and return an object (id) as the result of the calculation. So here is the sample of our calculation method:

method DataAccess.calculateSumForOrderRow(row: DADataTableRow): id;
begin
  // Get the Order ID value from the row 
  var orderID: Integer := row.valueForKey('OrderId').integerValue;
  // Prepare filter to obtain details on given order
  var condition: NSPredicate := NSPredicate.predicateWithFormat('Order == %d', orderID);
  // Get the order total
  var orderSum: Double := self.OrderDetails.rowsFilteredUsingPredicate(condition).valueForKeyPath('@sum.Total').doubleValue();
 
  // Wrap it into an id object and return
  exit NSNumber.numberWithDouble(orderSum);
end;

Conditional cell formatting

It has become common practice to give a slightly different design to each cell depending on the data it represents. For example, the developer can play with font, size, color, etc. All this makes the data more obvious and easy to perceive.

We will use a similar approach for our application. We already have the method tableView() cellForRowAtIndexPath(): UITableViewCell which composes the cell for any table row we want to show.

method ClientsViewController.tableView(tableView: UITableView)
                 cellForRowAtIndexPath(indexPath: NSIndexPath): UITableViewCell;
begin
  var CellIdentifier := "Cell";
  // Try to obtain cached cell
  result := tableView.dequeueReusableCellWithIdentifier(CellIdentifier);
 
  // This is required only if you are targetting iOS 5.1 or lower
  if not assigned(result) then
    // If there is no such cell cached, then just create a new one
    result := new UITableViewCell withStyle(UITableViewCellStyle.UITableViewCellStyleValue1) 
                                  reuseIdentifier(CellIdentifier);  
  
  // Note that we used UITableViewCellStyleValue1 as the UITableViewCellStyle
  // which makes the cell with the value aligned to the left side and the detail value aligned to the right side of the cell
  var tableRow := self.dataTable.rowAtIndex(indexPath.row);
  result.textLabel.text := tableRow['ClientName'];
 
  // Get the count of orders (as you remember, OrdersCnt is the calculated field)
  var ordersCnt: Integer := tableRow['OrdersCnt']:integerValue();
 
  // And depending on the orders count we can use different colors and different icons for the given cells
  case ordersCnt of
    0: begin 
        result.detailTextLabel.textColor :=  UIColor.blueColor();
        result.imageView.image := UIImage.imageNamed('1');
        result.detailTextLabel.text := 'No orders'; 
    end;
    1: begin
      result.detailTextLabel.textColor := UIColor.orangeColor();
      result.imageView.image := UIImage.imageNamed('2');
      result.detailTextLabel.text := NSString.stringWithFormat('%d order', ordersCnt);
    end;
    2: begin
      result.detailTextLabel.textColor := UIColor.magentaColor();
      result.imageView.image := UIImage.imageNamed('3');
      result.detailTextLabel.text := NSString.stringWithFormat('%d orders', ordersCnt);
    end;
    else begin
       result.detailTextLabel.textColor :=  UIColor.redColor();
       result.imageView.image := UIImage.imageNamed('4');
       result.detailTextLabel.text := NSString.stringWithFormat('%d orders', ordersCnt);
    end;
  end;
  
end;

As a result of our efforts above, we now have the following application:

Nougat DA for iOS application

And finally, as a small bonus, this is how it looks in iOS7 ;)

Nougat DA for iOS application iOS7

You can get sources of the sample download here

Thanks for your attention! ;)

DA SQL Browser is getting better

June 5, 2013 in Uncategorized

Today I want to tell you about a recent change in the DA SQL Browser.
As you might know, it is a tool that comes with our Data Abstract product and allows you to create SQL statements and query your DataAbstract-powered servers by using a DA SQL feature. You can consider it as an SQL development studio, but instead of a database, a server supports DA SQL.

On start, the DA SQL Browser will prompt you to connect to the server with the following dialog:
DA-SQL-Browser-Server-Connection
You can see that several fields are already filled with default values, which will work with a DA Sample Server.
Unfortunately, the login dialog of the DA SQL Browser is not that easy to use when connecting to Relativity Server (after all, the DA SQL Browser was created much earlier than the Relativity project). You have to provide somewhat cryptic “additional login parameters” like Domain=PCTrade Sample;Schema=PCTrade.

Considering this, a new option was introduced, so you can see a checkbox Relativity Server on the bottom of the form.
DA-SQL-Browser-Server-Connection-expanded
When you click it, it gives another drop-down lists to pick a Domain Name and a Schema Name. Note that you can still fill these names manually, but as long as the dialog’s Server URL to the Relativity Server is valid, these lists will have all the domains and schemas you need.

Now, you can connect to the Relativity Server and try some queries and (maybe later) include them in your client application. And I hope the DA SQL Browser will help you with your projects.
DA-SQL-Browser-with-Relativity

Profile photo of marc

by marc

Prism XE4, Where Art Thou?

April 17, 2013 in Elements, Oxygene, Uncategorized

Update: (May 26, 2013) We have an official FAQ for the migration of Prism licenses to Oxygene available now at remobjects.com/oxygene/prism. Also updated pricing references within the post to reflect current pricing.

Ok, so the cat is out of the bag, if a few days ahead of schedule: starting with the upcoming release of XE4, Embarcadero Prism will no longer be part of the RAD Studio SKU, and there will be no “XE4″ branded edition of Prism.

But worry not. As you all know, Prism has been nothing more than a re-branded version of our Oxygene for .NET product — and Oxygene will keep going on, stronger than ever.

In fact, Oxygene has long outgrown its Prism-branded edition, first when we introduced full native support for Java and Android to the language over 18 months ago, and of course with our upcoming support for truly native iOS and Mac apps, shipping next month.

So “Embarcadero Prism” as a product is going away, but the Oxygene language you have come to love and depend on will continue to shine and evolve, as it always has.

What exactly does all of this mean?

We believe that in the end, this change will be a net positive for Oxygene.

When we first started working with Embarcadero in 2008 to bring Oxygene 3.0 into RAD Studio, Embarcadero had a gap left in their lineup with the discontinuation of their ill-fated Delphi for .NET product. Both companies shared a vision of Delphi and Oxygene — then getting branded Delphi Prism — becoming two sides of the same coin: two languages evolving together and influencing each other to push Pascal forward both for CPU-native Windows development and for managed targets.

Over the years, it turned out that this was not happening, and as Embarcadero was shifting their focus to “(CPU-)native, native über alles” and onto FireMonkey, Prism (and with it Oxygene, as i’m going to start referring to it from now on exclusively) became the odd man out — the product that was there, as part of RAD Studio, but no-one liked to talk about, because it did not really fit the vision of the company.

This became clearer as Oxygene evolved.

We added support for Java and (more importably) Android, but Embarcadero had their own (very long term ;) vision of how they wanted to pursue the platform that conflicted with what Oxygene had to offer. As a result, Oxygene was forced into a split personality — with Oxygene for .NET remaining under the Prism umbrella, and Oxygene for Java becoming a separate product (for a while).

At the same time, Embarcadero became less and less interested in actually marketing and promoting the product, and it was being relegated to a “filler” to pad up RAD Studio as a worthwhile product suite.

Things got even more complicated when we started working on “Nougat”, our vision for really and properly bringing Object Pascal and Oxygene onto the (misleadingly named) Objective-C runtime that is the engine behind iOS and Mac. Once again, Embarcadero had different plans for the platform, and what is more, they — understandably — raised the concern that Oxygene for Cocoa would be too direct a competitor to their efforts on iOS (albeit once again our two companies were following two very different visions).

To wrap things up short and sweet, as of right now, Oxygene is finally standing on its own two feet again.

During the five years of partnership, RemObjects Software has always been the sole technical contributor to the core Oxygene product, and having Oxygene “back to ourselves” really just means one thing: that we can, more aggressively and consistently, continue to drive the product on all three target platforms, according to the vision we have for it. And trust me, we have some amazing things planned for 2013 and 2014, with “Nougat”, our Mac and iOS support, only being the tip of the iceberg.

What does this mean for existing customers?

Worry not. We have every eventuality covered.

First of all, if you already bought Oxygene directly from us or one of our reseller (i.e. without an Embarcadero serial number), none of this will affect you at all, you’re already set.

If you’re an Oxygene user from the Embarcadero side of the fence, now more than ever, make sure you register your XE2.x or XE3.x serial number with us. This way, we know about you and can take care of you moving forward.

If you have registered your XE3.1 serial, you can take advantage of our special renewal price for Prism customers and renew to a full Oxygene package licensed directly from RemObjects Software, for only $499. Remember, this not only renews you for future updates to Oxygene for .NET (the product you have now), but it also gives you the Java/Android and Mac/iOS targets, as well!

If you have active software assurance (SA) with Embarcadero that covers Oxygene, that will of course be honored. Up until August (i.e. one year from when XE3 shipped), you will continue to receive the latest updates to Oxygene for .NET from Embarcadero. This will (assuming your SA is still active at the time) include the upcoming major 6.0 release, next month.

Once your current SA expires, renewing it will not include renewed access to Oxygene, but you can use the link above at any time to renew to the full Oxygene package from us. (Note that the current renewal price of $349 is a special offer and will increase slightly once “Nougat” ships next month.)

It’s probably unlikely that you’re buying RAD Studio XE4 “fresh” without already being an existing RAD Studio user, but if you do, i’m afraid you will not receive “Prism XE4″ as part of it. You (and every other Delphi user) can use our special cross-grade offer to purchase a full Oxygene package from us, at $599 (this is also a special offer, and the price will increase slightly once we ship 6.0 next month).

In Summary

As the old saying goes, The King is dead, long live the King! Embarcadero Prism is no more, starting next week, but Oxygene is going stronger than ever.

We, and i personally, are incredibly excited about Oxygene, and about the things we have planned thru-out the rest of the year and beyond. We can’t wait to walk down the road ahead with you.

yours,
marc hoffman
Chief Architect & Oxygene Team Lead
RemObjects Software