You are browsing the archive for Platforms.

Profile photo of marc

by marc

WWDC 2015 and Elements

June 15, 2015 in "Silver", Fire, iOS, Mac, Nougat, watchOS, WWDC, Xcode

It’s been another exciting year at WWDC, even though i personally did not make it out to San Francisco this time. But staying home also has its upsides, as it means I had lots of time to dive into what’s actually been released.

As always there are many things new and coming in the Apple ecosystem that affect our Elements compiler, and with that Oxygene, C#, Silver and of course Fire. Let’s have a look.

New SDKs

Like every year, WWDC brings new editions of OS X and iOS, namely version 10.11 and 9.0. This time around, these new SDKs add not just new functionality (of which there is plentiful), but Apple also made some pretty drastic changes to the API headers, mostly in service of better inter-operation with Swift.

Because most of the headers use new Objective-C language features, such as annotations of nullability and (limited) generics, the new SDKs do not cleanly import with our current FXGen tool. After all, FXGen cannot know about new Objective-C syntaxes that just shipped.

But worry not. Myself and the team have been hard at work this week to update everything, so with the new Elements beta build we will post today (and the new official 8.1 update release coming next week), the new SDKs now import fine and are fully usable – including all the new frameworks and APIs. So get coding!

We’ll continue to work on the import so that for the next release (Elements 8.2, which goes into beta soon), we’ll be able to leverage a lot of the new information these SDKs headers now expose, which will allow us to represent Cocoa APIs even better in Silver, C# and Oxygene. For example, APIs will reflect the more accurate nullability information that’s now available, making them easier to deal with – especially from Silver.

watchOS

Now, in addition to new iOS and OS X SDKs, Apple also shipped a third, brand new platform SDK: watchOS. On the SDK level, watchOS is very similar to the existing SDKs for Mac and iPhone – it’s just a bunch if frameworks.

In fact as part of the new work on the importer, the watchOS 2.0 SDK is already importing fine, and our compiler is already happily building against it. But of course fully integrating Watch support is more involved – there are many parts of the toolchain and the IDEs that we need to review and expand. Working on this will be a high priority over there next couple of months as watchOS gores thru the betas, and we plan on shipping watchOS support in Elements 8.2 in the Fall (and of course make it available incrementally in the betas, prior to that).

Swift 2.0

The third and last big thing to mention is of course Swift. At WWDC, Apple introduced Swift 2.0, which brings many cool (and some awkward) improvements to the language. Like with version 1.0, there’s a lot tom like here, but also some things that have us scratching our heads in terms of syntax choices ;). But in general, we’re very happy with how Swift is evolving.

Of course we already started on bringing Silver, ur implementation of Swift for .NET, Java and Cocoa, up to speed with the latest language changes. Some parts were easy to do, while others require some more thought.

For example, Apple added ”Error Handling” to Swift, but it is very different from exception handling as it is needed on .NET and Java (and supported in Silver via a Language Extension). We have some cool ideas hewn to integrate the two in a way that’s convenient and intuitive, but we’re still fleshing out the details.

We’ll be working on adding Swift 2.0 support over the course of the next couple of months, as part of Elements 8.2 (and remember that Swift 2.0 itself is in beta right now as well, and bound to change more between now and the time Xcode 7 ships. In fact, in there WWDC sessions Apple was already talking about features not in the current beta release yet).

We’ll update a page on our documentation site with progress on Swift 2.0 support as things move forward.

 

Let us know what you think. And make sure to check out Elements, if you have not already!

Profile photo of marc

by marc

Announcing Elements 8.1, with Swift and Fire

April 30, 2015 in .NET, "Silver", Cocoa, Elements, Fire, Java

Elements 8.1

We are absolutely thrilled to announce the immediate availability of Elements 8.1, the next major version of our Elements compiler with Oxygene and RemObjects C#.

Don’t let the .1 version number trick you, Elements 8.1 is a significant and major update that brings a wide range of features and improvements, building on our 8.0 release late last year. From support for Visual Studio 2015 to IDE-integrated Help, from new language features in Oxygene to full support for C# 6.0 syntax, from Android GUI designer integration to iOS Extension templates, there’s bound to be something new and exciting for everybody.

But of course the most significant new feature in Elements 8.1 is Silver, our implementation of Apple’s Swift programming language.

With Silver, Swift joins the ranks of Oxygene and C# as a third Elements language, and is supported across all three platforms, and with all the bells and whistles you have come to expect from Elements. What’s more, we have decided to make Silver completely free to use for everyone — it will be included for free in your active Elements subscription, and new users who are interested only in Swift can use Silver without requiring an Elements license at all.

The second major new thing shipping with Elements 8.1 — and very close to my heart personally, because it represents the last years of my work – is Fire. Fire is our new native development environment for the Mac, written and designed from the ground up for Elements around our ideas of what a modern and lightweight IDE should look like in 2015. Fire is designed to be fast and nimble, yet powerful.

Fire is not quite ready for the “1.0” moniker yet, so the current version is still considered a preview – but it’s a production stable preview that you should be able to use for your day-to-day work (I personally have been working exclusively in Fire since the beginning of 2014 – that’s 16 months now). Even though still in preview, Fire is available as free public trial download now, and also supports the free Silver compiler – in addition to, of course, Oxygene and C#.

Get Elements 8.1 now

Elements 8.1 is available for download now – both for Windows with Visual Studio, and for Mac inside Fire. You can grab your copy at http://elementscompiler.com/download.

Yours,

marc hoffman
Chief Architect,
RemObjects Software

Profile photo of Anton

by Anton

Little Things that make a difference. Part II. DA LINQ String Operations

January 5, 2015 in .NET, Data Abstract

One thing that DA LINQ lacked until recently was support of the string data comparison operations. This means that there was no easy way to properly express SQL statement like:

SELECT
  Id,
  Name
FROM
  dbo.Customers
WHERE
  Name > 'Alpha'

using DA LINQ. Even worse – a lot of .NET languages don’t support < or > operators with sting operands. This means that, for example, C# cannot compile code like:

bool r = "A" > "B";

Of course there are a lot of ways to compare strings in .NET, but to use them, you first have to load the data into the client app using DA LINQ and then filter that data locally using Linq2Objects. Obviously, an approach like this is not always feasible, especially on big datasets or slow network connections.

So a different way to express string comparison operations was needed. Data Abstract was recently expanded with a set of extension methods allowing to express string comparison operations in DA LINQ queries like for example:

var data = from x in dataAdapter.GetTable() where x.Name.IsGreaterThan("Alpha") select x;

These extension methods provide enough information for the internal magic of DA LINQ to construct proper SQL statements.

The full list of supported string comparison operations is available on the corresponding docs page at http://docs.dataabstract.com/API/NET/StringExtensions_Class/.

Notice that while a set of .NET methods is used to express string comparison operations, the actual comparisons are still performed by the database. This has two implications:

  1. This feature will work only if sting comparison operations are supported at database level.
  2. String comparison results depend on database server collation settings.

Happy New Year!

Profile photo of Anton

by Anton

Little Things that make a difference. Part I. Application Base (addendum)

December 19, 2014 in .NET, Visual Studio

In this short article, the server application template created in the previous article will be turned into a real Visual Studio template. Greater minds have already described the process in the MSDN article at http://msdn.microsoft.com/en-us/library/xkh1wxd8.aspx.

Some preparation work is needed before the project can be turned into a real application template.

First, edit the AssemblyInfo.cs file, so it will look like this:

using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;

//
// General Information about the assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with the assembly.
//
[assembly: AssemblyTitle("$projectname$")]
[assembly: AssemblyDescription("$projectname$")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("$registeredorganization$")]
[assembly: AssemblyProduct("$projectname$")]
[assembly: AssemblyCopyright("Copyright (c) $registeredorganization$ $year$")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]


[assembly: ComVisible(false)]

//
// The version information for the assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all values, or you can default the Revision and Build Numbers
// by using the '*' as shown below:

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

[assembly: NeutralResourcesLanguageAttribute("")]

In the ServerApplication.cs file, change the Application ID, Application Name and Service Name properties to:

protected override string Identifier
{
    get
    {
        return "$guid1$";
    }
}

protected override string ServiceName
{
    get
    {
        return "$projectname$ Service";
    }
}

protected override string ApplicationName
{
    get
    {
        return "$projectname$";
    }
}

Open the MainService.cs in the designer and set the ServiceName property to “$projectname$ Service“.

Open the ProjectInstaller.cs in the designer and set the ServiceName property of the ServiceInstaller component to “$projectname$ Service“, as well.

Then replace the namespace ServerTemplate string with namespace $safeprojectname$ project-wide.

Save all changed files and issue the menu command File -> Export Template. Export the project as a project template. Set the template name and description and press the Finish button.

Restart Visual Studio. The template you just created will be available in the Visual Studio project templates.

P.S.: If you really don’t want to follow all those boring steps, here is the download link for the template project. Download, unzip and open it in Visual Studio, then export it as a project template.

Profile photo of Anton

by Anton

Little Things that make a difference. Part I. Application Base

December 18, 2014 in .NET, Visual Studio

This is the first of a set of short articles related to different Data Abstract or SDK features that I feel are important and interesting. Some of them will be just minor improvement notifications, while others will highlight something that can be called a feature but is still way too specialized to be highlighted in a big article. This first article will be about the common application base class that can be used for RemObjects SDK and Data Abstract server applications.

RemObjects SDK contains the ApplicationServer class which provides base application startup infrastructure including Windows Service management and single instance checks.

The ApplicationServer class was designed to provide a common codebase and simplify development of RemObjects SDK and Data Abstract-based server applications. It provides the following features:

  • 3 application run modes – GUI mode (WinForms or WPF), command-line interface or Windows Service.
  • Windows Service management (installation/deinstallation).
  • Optional Single Instance check.
  • Extensible startup arguments parser. The ApplicationServer class provides an overridable method to handle command-line arguments not handled by the default arguments parser. It is also possible to use your own implementation of the command line arguments parser.
  • Single exception intercept point (useful for logging etc.).

By default, ApplicationServer-based applications recognize the following command-line arguments (not case-sensitive):

Parameters
Description
-I, /I, –INSTALL Install as a Windows Service
-U, /U, –UNINSTALL Uninstall a Windows Service
-Q, /Q, –QUIET Suppress messages on service installation and uninstallation
-C, /C, –COMMANDLINE Run in CLI mode
-D, /D, –DEBUG Request extended debug info (i.e. full stack traces)
-H, /H, -?, /? Show command-line arguments help message

There is no need to write any code to handle these actions.

Data Abstract project templates rely on the ApplicationServer class, but the RemObjects SDK ones are still old-fashioned Windows Forms applications. The next part of this article describes how to create a base application that can later be used as a seed for new server apps development.

  1. Create a new RemObjects SDK project named, say, ServerTemplate.
  2. Delete the ServerTemplateClient from the solution.
  3. Delete the Getting Started.html file from the ServerTemplate project.
  4. The next major steps are to provide network connectivity infrastructure, Windows Service stuff and to tie them all together using the ApplicationServer class.
    First, update the licensing.licx file with the following content (so there won’t be any need to adjust the licenses file for each server project).

    RemObjects.SDK.Server.IpTcpServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.IpSuperHttpServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.IpHttpServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.NamedPipeServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.LocalServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.HttpSysServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.HttpSysSuperHttpServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.SuperTcpServerChannel, RemObjects.SDK.Server
    RemObjects.SDK.Server.EventSinkManager, RemObjects.SDK.Server
    RemObjects.SDK.Server.MemoryMessageQueueManager, RemObjects.SDK.Server
    RemObjects.SDK.Server.MemorySessionManager, RemObjects.SDK.Server
    RemObjects.SDK.Server.OlympiaMessageQueueManager, RemObjects.SDK.Server
    RemObjects.SDK.Server.OlympiaServerSessionManager, RemObjects.SDK.Server
    
  5. The next step is to create a component that will perform the networking operations. Unfortunately, it is not feasible to use the components already generated by the project template, as they are placed on a Windows Form. So add a new Component Class project item and set its name to Engine. Open the component and add the IpHttpServerChannel, BinMessage and MemorySessionManager components to the designer pane. Register the newly added BinMessage component in the IpHttpServerChannel.Dispatchers collection.

    Also, add the following methods and properties to the Engine.cs code:

    public void Start()
    {
        this.serverChannel.Activate();
    }
    
    public void Stop()
    {
        this.serverChannel.Deactivate();
    }
    
    public bool IsActive
    {
        get
        {
            return this.serverChannel.Active;
        }
    }
    
  6. Now create the Windows Service definition and infrastructure it needs. Add a new Windows Service item to the project and set its name to MainService. Open the code-behind file of the newly added service and set its code to:
    partial class MainService : ServiceBase
    {
        private Engine _engine;
    
        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
            this._engine = new Engine();
            this._engine.Start();
        }
    
        protected override void OnStop()
        {
            base.OnStop();
            this._engine.Stop();
            this._engine.Dispose();
            this._engine = null;
        }
    
        protected override void OnPause()
        {
            base.OnPause();
            this._engine.Stop();
        }
    
        protected override void OnContinue()
        {
            base.OnContinue();
            this._engine.Start();
        }
    }
    

    The code above is quite simple. It handles the service state change events and either creates and opens the server channel or closes it and disposes the corresponding components.

  7. Now open the service in design mode again and right-click the designer pane. In the context menu, choose the Add Installer item. This command will automatically add a service installer instance that encapsulates the WinAPI calls needed to install or uninstall a Windows Service.

    At this point, the ServerTemplate project has almost all code and components needed to work as a Windows Service.

  8. Delete the Main.cs form present in the ServerTemplate project and add a new Windows Form to the project named MainForm. Add the following code to its code-behind file:

    public partial class MainForm : Form
    {
        private Engine _engine;
    
        public MainForm()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();
    
            this.FormClosed += OnFormClosed;
            this.StartServer();
        }
    
        private void StartServer()
        {
            if (this.IsServerActive)
            {
                this.StopServer();
            }
            this._engine = new Engine();
            this._engine.Start();
        }
    
        private void StopServer()
        {
            if (this.IsServerActive)
            {
                this._engine.Dispose();
                this._engine = null;
            }
        }
    
        // Properties
        public bool IsServerActive
        {
            get
            {
                return ((this._engine != null) && this._engine.IsActive);
            }
        }
    
        private void OnFormClosed(object sender, FormClosedEventArgs e)
        {
            this.StopServer();
        }
    }
    
  9. The next step is to tie all these components together using the ApplicationServer class. Add the following class to the ServerTemplate project:
    using System;
    using System.ServiceProcess;
    using System.Windows.Forms;
    
    namespace ServerTemplate
    {
        sealed class ServerApplication : RemObjects.SDK.Server.ApplicationServer
        {
            private Engine _consoleEngine;
    
            protected override String Identifier
            {
                get
                {
                    return "2a42e444-5b2c-4f5c-b73a-dd1cab801c0a" ;
                }
            }
    
            protected override String ServiceName
            {
                get
                {
                    return "SimpleProject Service";
                }
            }
    
            protected override String ApplicationName
            {
                get
                {
                    return "SimpleProject";
                }
            }
    
            protected override void RunAsConsoleApplication()
            {
                this._consoleEngine = new Engine();
                this._consoleEngine.Start();
            }
    
            protected override void ShutdownAsConsoleApplication()
            {
                this._consoleEngine.Stop();
                this._consoleEngine.Dispose();
            }
    
            protected override void RunAsWindowsService()
            {
                ServiceBase.Run(new MainService());
            }
    
            protected override void RunAsWindowsApplication()
            {
                Application.EnableVisualStyles();
                Application.Run(new MainForm());
            }
        }
    }
    
  10. And as the very last step change the application entry point code in the Program.cs file to:
    using System;
    
    namespace ServerTemplate
    {
        static class Program
        {
            [STAThread]
            static void Main(string[] args)
            {
                new ServerApplication().Run(args);
            }
        }
    }
    

And that’s it: The server application project template. Applications created using this template can be run as Windows Forms apps, Windows Services or Linux daemons and are able to install themselves as Windows Services.

If you really want a quick result but don’t want to go over all the steps, here is the download link for the project created during this article: ServerTemplate

So far the only way to use this project template is to copy it to a new place when a new SDK server app is needed. In the next article, this application will be turned into a real Visual Studio project template.

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 Anton

by Anton

AES encryption envelope and Xamarin PCL

July 31, 2014 in .NET

Recently I’ve been asked a question about how the AES encryption envelope can be used with a PCL build of Data Abstract, the issue being that PCL doesn’t expose the needed cryptography API. Although I don’t known the reason for this, I am still going to provide a solution.

Before we dive into the technical details, I have to say that relying on AES message encryption alone is not the best option. Once someone steals your password, they will be able to intercept, read and modify any client-server traffic. So keeping passwords safe and not storing them in non-encrypted form is an absolute must. But you should still consider SSL to protect your communication channels.

Let’s go back to AES for now.

For most of the platforms supported by RemObjects SDK “natively”, the AESEncryptionEnvelope can be instantiated in the application and then this instance can be added to the .Envelopes collection of the Message instance created in the PCL communication library (this is the magic of PCL, yes). Unfortunately, there are two quite important platforms that are supported only by the PCL build of RemObjects SDK. So a solution is needed.

Assume we have a very simple PCL library that calls a RemObjects SDK server and that the server has AESEncryptionEnvelope enabled, so we have to enable it on the client side as well. The client is a Xamarin.iOS application (but the Xamarin.Android approach is exactly the same). Below, I’ll be talking about ‘native’ code, by which I mean code that directly references Xamarin libraries, opposed to code that references PCL.

So the solution is dead simple: In the ‘native’ code part, wrap Crypto API into a form that the PCL code part can understand and provide this wrapped instance to the RemObjects SDK message instance. Obviously, the best way to provide something is to wrap it into a form that RemObjects SDK understands. In our case, we’ll derive a class from the abstract class MessageEnvelope. For further reference I’ll provide the code entirely:

using System;
using System.ComponentModel;
using System.IO;
using System.Text;
using RemObjects.SDK.Helpers;
using System.Security.Cryptography;

namespace RemObjects.SDK
{
     public class AesEncryptionEnvelope : MessageEnvelope
     {
          #region Default values
          private const String CATEGORY_ENCRYPTION = "Encryption";
          private const String IV = "@1B2c3D4e5F6g7H8";

          private const Int32 BUFFER_SIZE = 65536;//64k
          private const Int32 BLOCK_SIZE = 128 / 8;
          #endregion

          #region Private fields
          private Byte[] fEncodedPassword;
          #endregion

          public AesEncryptionEnvelope()
               : base()
          {
          }

          public AesEncryptionEnvelope(String password)
               : this()
          {
               this.Password = password;
          }

          #region Properties
          public String Password
          {
               get
               {
                    return this.fPassword;
               }
               set
               {
                    this.fPassword = value;
                    this.EncodePassword();
               }
          }
          private String fPassword;

          public override String DefaultEnvelopeMarker
          {
               get
               {
                    return "AES";
               }
          }
          #endregion

          protected override MemoryStream InternalWrap(Stream source, Byte[] header)
          {
               // Size of the original stream
               Int64 lStreamLength = source.Length - source.Position;
               Byte[] lStreamSizeBuffer = BinHelpers.Int32ToBuffer((Int32)lStreamLength);

               // Create bytes array containing
               // [... original header ...][stream size]
               // This is cheaper than creating MemoryStream and then converting it to Byte[]
               Byte[] lHeader = new Byte[header.Length + 4];
               Array.Copy(header, lHeader, header.Length);
               Array.Copy(lStreamSizeBuffer, 0, lHeader, header.Length, 4);

               return this.InternalEncrypt(source, lHeader);
          }

          protected override MemoryStream InternalUnwrap(Stream source)
          {
               // Read size of the original stream
               Byte[] lBuffer = new Byte[BinHelpers.SIZE_INT32];
               Int32 lBytesRead = source.Read(lBuffer, 0, BinHelpers.SIZE_INT32);

               if (lBytesRead != BinHelpers.SIZE_INT32)
                    BinHelpers.UnexpectedEndOfStream();

               Int32 lStreamSize = BinHelpers.Int32FromBuffer(lBuffer);

               MemoryStream lDecryptedData = new MemoryStream();
               this.InternalDecrypt(source, lDecryptedData);

               if (lDecryptedData.Length < lStreamSize)
                    throw new Exception("Decryption error. Invalid length of the stream.");

               lDecryptedData.SetLength(lStreamSize);

               return lDecryptedData;
          }

          private void EncodePassword()
          {
               if (String.IsNullOrEmpty(this.Password))
               {
                    this.fEncodedPassword = null;
                    return;
               }

               this.fEncodedPassword = new Byte[32];

               Byte[] lPasswordBytes = Encoding.UTF8.GetBytes(this.Password);
               Array.Copy(new SHA1CryptoServiceProvider().ComputeHash(lPasswordBytes), this.fEncodedPassword, 20);
               Array.Copy(new MD5CryptoServiceProvider().ComputeHash(lPasswordBytes), 0, this.fEncodedPassword, 20, 12);
          }

          private CryptoStream GetCryptoStream(Stream baseStream, CryptoStreamMode mode)
          {
               if (this.fEncodedPassword == null)
                    throw new Exception("No password configured for AesEncryptionEnvelope.");

               RijndaelManaged lSymmetricKey = new RijndaelManaged();
               lSymmetricKey.Mode = CipherMode.CBC;
               lSymmetricKey.Padding = PaddingMode.None; // Do padding manually
               lSymmetricKey.Key = this.fEncodedPassword;
               lSymmetricKey.IV = Encoding.UTF8.GetBytes(IV);

               ICryptoTransform lTransform = (mode == CryptoStreamMode.Write) ? lSymmetricKey.CreateEncryptor() : lSymmetricKey.CreateDecryptor();

               return new CryptoStream(baseStream, lTransform, mode);
          }

          private MemoryStream InternalEncrypt(Stream source, Byte[] header)
          {
               MemoryStream lEncryptedData = new MemoryStream(header.Length + (Int32)AesEncryptionEnvelope.GetEstimatedStreamLength(source));
               lEncryptedData.Write(header, 0, header.Length);

               using (CryptoStream cryptoStream = this.GetCryptoStream(lEncryptedData, CryptoStreamMode.Write))
               {
                    StreamHelpers.CopyStreamToStream(source, cryptoStream);

                    // Add tail
                    Int32 lTailLength = ((Int32)(source.Length - lEncryptedData.Length)) + header.Length;
                    if (lTailLength != 0)
                    {
                         lTailLength = AesEncryptionEnvelope.BLOCK_SIZE - lTailLength;
                         Byte[] lTail = new Byte[lTailLength];
                         cryptoStream.Write(lTail, 0, lTailLength);
                    }

                    cryptoStream.FlushFinalBlock();

                    // The original lEncryptedData stream will be enclosed together with the CryptoStream instance
                    // Note that the used constructor doesn't actually copy the data, so memory consumption/performance
                    // is not an issue here
                    MemoryStream lResult = new MemoryStream(lEncryptedData.GetBuffer());

                    // Otherwise the tail contained in the buffer will break the AES decryption on the other side
                    lResult.SetLength(lEncryptedData.Length);

                    return lResult;
               }
          }

          private void InternalDecrypt(Stream source, Stream destination)
          {
               using (CryptoStream cryptoStream = this.GetCryptoStream(source, CryptoStreamMode.Read))
               {
                    StreamHelpers.SetStreamCapacity(destination, source, AesEncryptionEnvelope.GetEstimatedStreamLength(source));
                    StreamHelpers.CopyStreamToStream(cryptoStream, destination);
               }
          }

          private static Int32 GetEstimatedStreamLength(Stream source)
          {
               Int32 lSourceLength = 0;
               try
               {
                    lSourceLength = (Int32)(source.Length - source.Position);
               }
               catch (NotSupportedException)
               {
                    return -1; // Unknown
               }

               Int32 lResult = (lSourceLength / 16) * 16;
               if (lResult < lSourceLength)
                    lResult += 16;

               return lResult;
          }
     }
}

(You'll have to reference the RemObjects SDK assemblies to get this code compiled.)

Then provide an instance of this AesEncryptionEnvelope class to the code part where the communication components are instantiated and add it there to the Envelopes collection:

message.Envelopes.Add(envelopeInstance, true);

And that's it. AES encryption is enabled.

I also want to mention that while theoretically it is possible to implement AES encryption/decryption completely in managed PCL code, there are reasons NOT to do this. Re-implementing part of the base class library leads to code bloating. What's more important is that cryptography APIs implemented by Xamarin platforms might utilize low-level platform methods for better performance and security – something that a PCL managed code-only implementation won't be able to provide by definition.

PS.: The above-mentioned approach can be extended. More powerful (and resources-consuming) cryptography algorithms can be used instead of AES, like asymmetric encryption. Custom envelopes based on them can be used in RemObjects SDK-powered applications – all you need to do is to properly override the abstract methods of the MessageEnvelope class.

Profile photo of Anton

by Anton

PCLs, async/await server calls, and more…

June 26, 2014 in .NET, Data Abstract

The new Data Abstract 8 is out. So I’d like to highlight some of its features and the changes they imply.

Xamarin support changes

To start with, the Xamarin iOS and Android platforms are now supported via Data Abstract for the Portable Class Library. This means that there is no more separate Data Abstract for MonoAndroid or MonoTouch builds.

On the bright side, this means that both target platforms now share the same set of features and, due to the PCL support, development of code shared between iOS and Android targets becomes a little easier. There are, however, some caveats you should be aware of:

  • Only DA LINQ data access is supported, DataSet support on the iOS side is not available anymore, so a data access code revamp is needed.
  • Only the simple HTTP client channel is available in Data Abstract for PCL. While this might look restricting, it is still the best choice for apps targeting mobile devices operating with a potentially unstable connection. In such conditions, SuperHTTP has no considerable advantage over the simple HTTP client channel.
  • Only asynchronous server calls are possible. While this is a must in the mobile world due to unpredictable network delays, it can be a real headache when the Begin/End asynchronous calls pattern is used, especially when several remote calls are chained in the same method. Luckily, starting this release, RemObjects SDK for .NET now provides support for async/await remote calls.

async/await remote calls

Old async code with callback methods and BeginOperation/EndOperation calls was hard to develop and maintain. Starting with the Summer 2014 release, RemObjects SDK now allows to call remote servers using code like:

var result = await service.SumAsync(1, 2);

Of course, the target platform also has to support await calls, so this feature is not supported for .NET 3.5 clients. For all other target platforms,_Intf code will contain method declarations like:

public interface ISampleService_Async : RemObjects.SDK.IROService_Async {
    System.IAsyncResult BeginSum(double a, double b, System.AsyncCallback @__Callback, object @__UserData);
    double EndSum(System.IAsyncResult @__AsyncResult);
    System.Threading.Tasks.Task SumAsync(double a, double b);
}

Note the last method declaration. It is the asynchronous server call proxy that can be called using the async/await pattern.

Unfortunately, it is not possible to expand the DataAdapter class with …Async methods due to the necessity to support .NET 3.5. Instead, a set of extension methods was introduced that provide nearly the same experience.

These extension methods are defined in the assembly RemObjects.DataAbstract.Async.dll. For platforms that support Extension SDK packages (f.e. Windows Phone) this assembly is included in the Data Abstract packages. On other platforms (f.e. desktop .NET) this assembly has to be referenced explicitly.

Note that to call an extension method, you need to add the namespace this method is declared in to the using (C#)/Imports (VB.NET) or uses (Oxygene) clause.

The following extension methods are provided:

  • IBaseLoginService_Async interface, methods are declared in the RemObjects.DataAbstract namespace.

    • Boolean LoginExAsync(String)
    • LogoutAsync()
  • DataAdapter (including LocalDataAdapter and RemoteDataAdapter), methods are declared in the RemObjects.DataAbstract namespace. All methods are awaitable versions of corresponding synchronous DataAdapter methods.

    • FillAsync(DataSet, Boolean)
    • FillAsync(DataSet, Boolean, Boolean)
    • FillAsync(DataSet, String[], Boolean)
    • FillAsync(DataSet, String[], WhereExpression[], Boolean)
    • FillAsync(DataSet, String[],TableRequestInfo[], Boolean)
    • FillAsync(DataTable, WhereExpression, Boolean)
    • FillAsync(DataTable,TableRequestInfo, Boolean)
    • FillWithDASqlAsync(DataTable, String, DataParameter[])
    • UpdateAsync(DataSet)
    • UpdateAsync(DataSet, String[])
    • UpdateAsync(Delta[], Boolean)
  • LinqDataAdapter (including LocalLinqDataAdapter and RemoteLinqDataAdapter), methods are declared in the RemObjects.DataAbstract.Linq namespace.

    • LoadListAsync<T>(IQueryable<T>) – asynchronously loads data into List<T>
    • LoadBindableListAsync<T>(IQueryable<T>) – asynchronously loads data into BindingList
    • ApplyChangesAsync()

    Asynchronous data loading using one of these methods will look like

    var list = await fDataAdapter.LoadListAsync(
            from x in fDataAdapter.GetTable<Clients>() select x);
    

Windows Phone Applications support

This application type has a somewhat misleading name. Microsoft has renamed the good old Windows Phone apps based on Silverlight to Windows Phone Silverlight applications and introduced new WinRT based phone applications as Windows Phone. We register Data Abstract and RemObjects SDK as Extension SDKs for both these platforms. In case you want to reference Data Abstract assemblies directly, you need to reference assemblies from the WindowsPhone folder for Silverlight based applications and assemblies from the WinRT folder for Windows Phone Store applications. It is strongly recommended to use the ExtensionSDKs’ references instead of direct assembly references to avoid situations where wrong assemblies are referenced and the application just cannot be built.


That’s all for now. See you around and don’t forget to check the Breaking Changes page!

Profile photo of marc

by marc

Announcing Elements 7.1

April 30, 2014 in Cocoa, Elements, RemObjects C#

Welcome back.

Hot on the heals of the brand new first release of RemObjects C# last month, we have just shipped the new 7.1 update to both RemObjects C# and our Oxygene language.

Despite the very short timeframe, 7.1 deserves the increased version moniker, as it includes — next to a huge amount of fixes, tweaks and improvements — several major new features that we’re very excited about.

Generics for Cocoa

You’ve asked and we listened, so version 7.1 brings full support for generic types to the Cocoa platform — for both Mac and iOS.

While 7.0 already allowed generics to be used on mapped types and provided generic variations of NSDictionary and NSArray, the new version now extends this to support generics on all types – including custom types derived from standard Cocoa classes such as NSObject or more concrete types. The sky is the limit.

Of course this feature is available in both the RemObjects C# and Oxygene languages, and I think this is yet another big step towards language parity between the platforms.

Colon operator, meet C#.

We just could not live without it ourselves, so we went ahead and implemented support for the ?. operator that’s rumored to be officially coming in C# 6.0 to our RemObjects C# dialect, ahead of time. The ?. is, essentially, what the colon (:) operator has been in Oxygene for ages: a way to safely call members of objects, whether the reference is null or not.

So you can now, for example, write if (myArray?.count > 0) and not care if myArray is null or not.

As in Oxygene, the ?. operator will convert the result into a nullable type, and RemObjects C# benefits from the full nullable arithmetic and ternary boolean logic as Oxygene when working with these types.

This means that if you mix nullable types in more complex expressions, the entire expression will become nullable. For example, myArray.count *5 could be null, 0, 5 or 10, depending on whether myArray is null.

We find that the ?. operator (and Oxygene’s colon one) comes in especially handy on the Cocoa platform, where calling members on null objects is second nature for developers coming from Objective-C. I’ve been porting a huge chunk of code from Objective-C to C# these past few weeks, and it’s been a lifesaver.

iOS 7.1 Support in the Box

Timing was not on our side when Apple shipped iOS 7.1 shortly after we shipped Elements 7 last month, and so manual import of the iOS 7.1 SDK was needed for anyone wanting to use RemObjects C# or Oxygene with the new SDK and the new Xcode 5.1. This new update — fittingly enough, given the version number — now includes support for iOS 7.1 in the box to make this easier. And we’re working on infrastructure to make these overlap periods less painful going forward, in time for iOS 8 and the next OS X release.

And there’s more

Further language and compiler enhancements include:

  • We’ve introduced a new [Category] aspect to make it easier to implement extension classes (i.e. “categories”, in Cocoa parlance) in RemObjects C# without the need for a special syntax (Oxygene, of course, has dedicated extension class syntax for this, but it can also use the new aspect).
  • We’ve extended Cross-Platform Compatibility Mode so that it now ignores the difference in case for the first letter of class called members, and ignores the case of namespaces in cross-platform code. This makes it a lot easier to deal with shared code on .NET (which prefers PascalCase) and Java or Cocoa (which prefer camelCase, and require lowercase namespaces).
  • We’ve added additional Fix-Its and Auto-Fixes.
  • We’ve added support for methods on records/structs on the Cocoa and Java platforms — yet another checkmark against language compatibility across all three targets, as .NET has had this feature from day one.
  • We’ve created new templates and added support for the ASP.NET Razor view engine.

Finally, for everyone downloading Oxygene or RemObjects C# fresh, we have also converted the “with Visual Studio” installers from .ISO files to embedded .exe installers to make them even easier to use.

What are you waiting for?

The new release is available now, and as always it is a free update for everyone with an active subscription. You can find it for download either in your Licensed Downloads area, as well as on the public Trials page. It (optionally) includes the Visual Studio 2013 IDE.

If your Oxygene subscription has lapsed, there has never been better time to renew than now to get both the new release, and everything we have planned for the the rest of the year (and beyond). Such as cough Fire cough. As always, you can renew your Oxygene license for a mere $499 per user. And we also have a special “up-renewal” that lets you renew Oxygene and add RemObjects C#, for only $699.

If your RemObjects C# subscription has lapsed, then, well, you’re a time traveller, and regular rules do not apply to you ;).

Prism

Also, for the very last time a reminder that if you are a Prism user, abandoned by Embarcadero, chances are you might be entitled to extended Oxygene for .NET releases from us, and/or qualify for special renewal or cross-grade pricing for both Oxygene and/or RemObjects C#. Check our Prism FAQ for details, or contact us if you have questions.

7.1

I’m very excited about this release. In many ways, it is what the 7.0 release we shipped in March should have been like. It received a ton of attention, testing and bug-fixing internally, and it’s probably the most solid release we ever shipped (only to be topped by what we have coming for May ;)..

I hope you enjoy it, too. Let me know what you think!

Yours,
marc hoffman
Chief Architect

Profile photo of marc

by marc

Data Abstract, RemObjects SDK and Hydra “Spring 2014” Releases

March 31, 2014 in .NET, Cocoa, Data Abstract, Delphi, Hydra, Java

On Friday, we released the latest updates to our Data Abstract and RemObjects SDK products for all five platforms, as well as for Hydra. Like always, a whole bunch of fixes and improvements across the product lines are gathered together in this release.

For Data Abstract and RemObjects SDK, this is also our last planned release for the 7.0 product version, as we prepare for a major new product cycle — codenamed DA8 — starting with our summer release in May. As such, this update focuses mainly on bug fixes and smaller enhancements (of which there are many).

The new release also includes official support for use with our recently released RemObjects C#, including project templates and IDE improvements to let you build .NET, Cocoa and Java apps with RO/DA using our C# implementation, as well as building managed hosts and plugins for Hydra.

As always, the new update is free for all users with an active subscription, and available on the customer portal. Our free 30-day trial downloads have also been updated to the new version.

If your subscription has elapsed, then now is a great time to renew. Renewing will not only give you access to the new 7.0 update, but also access to the beta versions of DA8 that will become available over the course of April, as well as the first (and future) DA8 or RO8 releases throughout the year.

If your previous subscription ended a while ago, you will be happy to hear that we recently updated our online shop to automatically grant “amnesty renewals”. That means you can be assured that your renewed license will always cover the current product and at least six months of future updates from your renewal date.

If you have or are considering getting a Suite subscription, remember that the Suites for .NET, Cocoa and Java now also include RemObjects C# — so you get been more value at the same great price as before (and you can always up-renew from RO or DA to the Suite, of course).

But enough talk, i’m sure you’re anxious to try out the new bits. We’re happy to have this new set of updates out to you now, and we’re extremely excited about what we have coming for DA8 and RO8 this summer and beyond.

yours,
marc hoffman
Chief Architect