Archive for the ‘Xcode’ Category

# Everything is Relative

Today i want to talk a bit about “Relativity”, a new feature we’re shipping with Data Abstract this month (and which is actually available as “tech preview”in the current Winter 2009 releases).

“Relativity” is, simply put, a standalone server application that can be used to host Data Abstract schemas and serve data. In essence, it provides the complete Data Abstract middle tier, in a precompiled box and ready run. This offers several benefits, not the least of which are:

  1. No need to build your own. Relativity provides all the power and abstraction of a true Data Abstract middle tier server, without you actually having to create, build, and deploy your own executable. This allows you to concentrate on the client development. It also is really handy for prototyping, if you just want to have database server to talk to, without much work, even if you plan to eventually implementing your own custom server.
  2. Build on Data Abstract for .NET. .NET is platform with the most advanced version of DA – it supports our powerful DA SQL execution engine, and other features not available on all platforms. “Relativity” is being made available to all users of Data Abstract, so whether you’re a developer using .NET, Delphi, or Xcode, you can now write clients against Relativity that take full advantage of these features.

But let’s go and take a more detailed technical look at Relativity.

Relativity is a server application, so it does not provide any user interface. You can deploy a Relativity server in several ways, including:

  • Running it as a regular user application, on Windows.
  • Installing it as a Windows service.
  • Running it as a Unix daemon with the mono-service2 tool, on Mac and Linux.
  • Running it as a menubar item, on Mac.

Regardless of how you deploy and run it, Relativity will start making it’s Data Abstract services available on (by default) port 7099. But of course before it can start serving actual data, it will need to be configured with what data to serve. That is done thru the Relativity Server Admin tool, which is currently available for Windows (but versions for both Mac and iPhone are in the works).

When you first start it, the Admin tool will look something like this:

Screen shot 2010-02-03 at 2.24.03 PM.png

On the left hand side, you will see a tree view with all known instances of “Relativity” servers. This includes any servers (local or remote) that you connected to in the past, as well as any servers discovered on the local network using ROZeroConf.

Select any of the servers (here, “VEMMY” is the one instance running in my Windows VM), to connect and get more options.

Screen shot 2010-02-03 at 2.30.01 PM.png

The first two nodes allow you to configure how this “Relativity” server is accessed. This includes options such as what ports to listen on, what RemObjects SDK channels and messages to use, etc. Here you have the full choice of all the options provided by RO, you can choose the familiar HTTP, TCP, Super HTTP or other channels, BinMessage, SOAP Message, and so on.

Where it gets more interesting is the third node – Domains. This is where you configure the meat of the services Relativity is providing.

Each Domain corresponds to what typically would be a separate Data Abstract middle tier server. Domains are completely abstracted from one another and Relativity allows you to host as many separate domains as needed. With that, a single Relativity server can replace multiple DA servers, be it for related to completely independent applications or projects.

As you can see, i have three domains set up in my server, one for “BC7″, our new bug tracking system (using a PostgreSQL database running on our Xserve build server), one for “RemObjectsCom”, the database that drives our website (Microsoft SQL Server, running on the Windows server that hosts our website), and finally “OneSpace”, the database for a personal iPad project i am working on.

As we drill into a specific domain, you start seeing more things that will be familiar to you as a Data Abstract developer. Each domain can contain one or more Schemas – which correspond directly to .daSchema files or TDASchema components as you know them. You can manage schemas right there in the Admin tool, or directly launch Schema Modeler to edit the schema in question:

Screen shot 2010-02-03 at 2.39.38 PM.png

The domain also maintains a list of Connections to back-end databases available to it’s schemas. Once again, this directly corresponds to the .daConnections file or TDAConnectionManager component. Since Relativity is based on DA/.NET, these connections are based on the available DA/.NET drivers – regardless of whether your regular development platform is .NET, Delphi or Cocoa.

Another interesting part is the Login node. Relativity provides several options for handling authentication from client applications for data access (something you would normally need to manually implement, in a standalone DA server): in addition to relying on a static list of allowed username/password combinations, you can also choose to use a data table or command defined in one of the domain’s schemas to verify users (as i do in the example shown below) or query an external LDAP server for login.

The LDAP option is very handy if you are running a variety of services – some using Relativity, and some not – that you want to share user data among. We recently switched to LDAP for all our employee resources, and it has made administration so much easier.

The LDAP support in Relativity is based on a new 100% managed LDAP client implementation we’ve added to Internet Pack for this upcoming release. Carlo will blog more about this, soon.

Screen shot 2010-02-03 at 3.05.53 PM.png

The Login Provider architecture is extensible, so you can implement your own providers, for example if you need to do user authentication with a different method.

Client Access

Once you have Relativity set up to serve your data, your client application(s) can access it like any other Data Abstract server.

The only slight difference is that, since a Relativity server can host more than one domain, you need to tell the server which domain to access, by simply passing an additional Domain parameter as your login string, as in

User=foo;Password=bar;Domain=DomainName

You will also want to select which Schema to query. in regular DA applications, each schema usually has its own DataService, so keeping in line with that, Relativity allows you to append a schema name to the ServiceName property of your Remote Service. Instead of using DataService, simply use DataService.DomainName. (Alternatively, you can also pass a Schema to LoginEx).

In Closing…

So, this has been a brief introduction to Relativity – i hope you found it useful.

We think of Relativity as a strategic piece of Data Abstract, and it will play an increasing part in what we do for DA. We have lots of things planned for the future that will make Relativity even more powerful, such as our upcoming JavaScript Business Rules Scripting based on Carlo’s RemObjects Script for .NET.

You can try out the tech preview of Relativity now, and the official release will be part of what we ship at the end of this month. I’m looking forward to your thoughts and feedback!

marc

by marc hoffman, February 3rd, 2010

# Visualizing Data with Core-Plot

Core Plot is an open source graphing framework for Cocoa developers that makes it really easy to add graphs to your applications for the Mac and iPhone. Over the past half year, i’ve had the chance to use Core Plot in several of the internal applications i have been working on and have been very impressed with it, so i wanted to talk a little bit about how to use the library, in general, and how to make generate charts based on data in a Data Abstract for OS X application, in particular.

The example shown here is from a small iPhone application i wrote to keep track of the status of our Continuous Integration servers. The application shows the success (or errors) of any builds done on the machine, as well as – and this is the part where Core Plot comes in – graphs the number of tests that run and fail, over time:

In the application in question, the chart is being displayed in a cell within a UITableView, so our example starts out by implementing a custom UITableViewCell class that will host the graph. But the same general principles apply to show a chart anywhere else (and, replacing UIView with NSView, for using charts in a desktop app).

Core Plot uses a Core Animation as underlying technology, and as such draws itself in a specialized view class CPLayerHostingView. So we start out by crating this view, and adding it as sub-view:

- (id)initWithStyle:(UITableViewCellStyle)style 
{
  self = [super initWithStyle:style reuseIdentifier:@"MyChartCell"];
  if (self)
  {
    CGRect frame = self.contentView.bounds;
    CPLayerHostingView *chartView = [[CPLayerHostingView alloc] initWithFrame: frame];
    [self addSubview:chartView];
    //...

Once the CPLayerHostingView is created, we can add a graphs to it, and configure them. There are several graph types supported, but we want a regular line graph with X/Y coordinates, so we’ll choose a CPXYGraph class. We’ll add the graph to the view, and set a padding, to give us some room between the edges of the table cell:

  // create an CPXYGraph and host it inside the view
  CPTheme *theme = [CPTheme themeNamed:kCPPlainWhiteTheme];
  graph = (CPXYGraph *)[theme newGraph];	
  chartView.hostedLayer = graph;
 
  graph.paddingLeft = 10.0;
  graph.paddingTop = 10.0;
  graph.paddingRight = 10.0;
  graph.paddingBottom = 10.0;

The next step is to set up a plot space. A plot space defines the coordinate system for one or more charts in a graph, essentially mapping logical values to the area in the graph. For example, your chart might show values ranging from, say, 0 to 1000. The plot space defines the scale of those values in relation to the graph. It also defines the visual range of values that can be seen on screen.

To match our X/Y graph, we’ll create a CPXYPlotSpace, and set it to a range of 0-100 for both axis:

  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(100)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(100)];

Finally, we’ll set up to axis, for the X and Y coordinates. Axis provide labels and tick-marks for the viewer, to give context to the values being shown.

The X/Y graph already provides a set of axis in for of a – you guessed it – CPXYAxisSet class. There are several properties on the axis’ that are worth looking at at tweaking to to suite out needs:

  • majorIntervalLength defines the number of units between “big” ticks on the axis. In this case it’s set to show one very 10 units. (if it were not for the exclusionRanges, discussed below, a numeric label would show for each major tick, as well).
  • minorTicksPerInterval specified how many small ticks will be shown between each major one. in this case, a value of 2 indicated that small would show for 5, 15, 25, etc. (a value of 9 would show ticks for every single unit).
  • Finally, exclusionRanges allows to define areas where no axis labels will be drawn. In my app, i don’t want to see any labels, so i set a range to exclude the entire visible graph
  CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
 
  CPXYAxis *x = axisSet.xAxis;
  x.majorIntervalLength = length:CPDecimalFromFloat(10);
  x.constantCoordinateValue = length:CPDecimalFromFloat(2);
  x.minorTicksPerInterval = 2;
  x.borderWidth = 0;
  x.labelExclusionRanges = [NSArray arrayWithObjects:
                              [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-100) 
                                                          length:CPDecimalFromFloat(300)], 
							  nil];;
 
  CPXYAxis *y = axisSet.yAxis;
  y.majorIntervalLength = length:CPDecimalFromFloat(10);
  y.minorTicksPerInterval = 1;
  y.constantCoordinateValue = length:CPDecimalFromFloat(2);
  y.labelExclusionRanges = [NSArray arrayWithObjects:
                              [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(-100) 
                                                          length:CPDecimalFromFloat(300)], 
							  nil];

Our graph is now fully set up – except for one important part: we still need to define one or more charts to display actual values. My application needs to show two graphs on top of each other – one showing the total number of tests that ran, and another showing the number of failures.

Core Plot supports a variety of chart (or, plot) types, such as bar and pie chart, but for this scenario, we want a simple line graph, which is done via a CPScatterPlot. (A scatter plot actually allows to draw a plot with points scattered all over the place, not just as string y = f(x) values, but we will use it in the more simplistic case).

We’ll create a new CPScatterPlot instance, configure some properties such as its lineWidth and lineColor, and most importantly, set the dataSource to the object that will provide the plot with its data – in this case, self. To round things off, we also tell the plot to fill the area underneath it with a gradient, going from almost-transparent green to nothing. This gives the plot some depth, without hiding the other plots.

  CPScatterPlot *dataSourceLinePlot = [[[CPScatterPlot alloc] init] autorelease];
  dataSourceLinePlot.identifier = @"AllTests";
  dataSourceLinePlot.dataLineStyle.lineWidth = 3.f;
  dataSourceLinePlot.dataLineStyle.lineColor = [CPColor greenColor];
  dataSourceLinePlot.dataSource = self;
  [graph addPlot:dataSourceLinePlot];
 
  // Put an area gradient under the plot above
  CPColor *areaColor = [CPColor colorWithComponentRed:0.3 
                                                green:1.0
                                                 blue:0.3
                                                alpha:0.3];
  CPGradient *areaGradient = [CPGradient gradientWithBeginningColor:areaColor 
                                                        endingColor:[CPColor clearColor]];
  areaGradient.angle = -90.0f;
  CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient];
  dataSourceLinePlot.areaFill = areaGradientFill;
  dataSourceLinePlot.areaBaseValue = CPDecimalFromString(@"1.75");

We repeat the above to add a second plot, except this time we use red for the line color and gradient, and set the identifier to @"FailedTests".

This was quite a bit setup, but our graph is now ready plot, and will ask its data source (our cell) for data by sending it messages from the CPPlotDataSource protocol. This protoco will be familiar to any Cocoa developer who worked with, for example, a UITableView or NSTableView, or any other control using a data source.

To the protocol, two methods need to be implemented. The first is numberOfRecordsForPlot: which will, simply enough, return the number of items (in case of a scatter plot, points, the chart will contain. The second can be one of three methods that return the actual data. We’ll implement numberForPlot:field:recordIndex:.

The data to display is retrieved via Data Abstract, using a simple DA SQL request on a table that contains all test runs:

	NSString *sql = [NSString stringWithFormat:@"SELECT TOP 50 ID, _TotalTestCount, \
                                     _FailedTestCount, FROM TestRuns ORDER BY ID DESC"];
	testRuns = [[rda getDataTableWithSQL:sql] retain];

The _TotalTestCount and _FailedTestCount fields are server-calculated based on a relation table and contain the total number of run and failed tests for each test run. We can Key Path operators to get the maximum value, and adjust our plot space accordingly, so that the entire graph fits into the chart:

  int count = [[testRuns rows] count];
  int maxTests = [[[testRuns rows] valueForKeyPath:@"@max._TotalTestCount"] intValue];
 
  CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
  plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(count)];
  plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0)
                                                 length:CPDecimalFromFloat(maxTests)];

This is of course a bit redundant with the values we set earlier, but in real life application, the data access will usually happen in a different place than the initial setup (and data might get changed or refreshed during the course of the application), so i find it important to set up the graph properly to begin with, but then adjust the range to the real data.

With the data retrieved and the plot space adjusted, we can now implement the two data source methods.

numberOfRecordsForPlot: will simply return the number of rows in our table. numberForPlot:field:recordIndex will be called twice per data point, once for the X value (since we’re drawing a “non-scattered” plot, we’ll simply return the indexes) and one for the Y value, which we’ll retrieve from our data table. The different identifiers we assigned to the two plots will serve to distinguish which field to use for the Y value.

-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot 
{
  return [rows count];
}
 
-(NSNumber *)numberForPlot:(CPPlot *)plot 
                     field:(NSUInteger)fieldEnum 
               recordIndex:(NSUInteger)index 
{
  switch (fieldEnum)
  {
    case CPScatterPlotFieldX: 
    {
        // inverse numbers, so first (latest) test run is on the right.
        int x = [rows count]-recordIndex; 
        return [NSDecimalNumber numberWithInt:x];
    }
    case CPScatterPlotFieldY:
    {
      if ([plot.identifier isEqual:@"AllTests"])
      {
        float v = [[[rows objectAtIndex:index] valueForKey:@"_TotalTestCount"] floatValue];
        return [NSNumber numberWithFloat:v];
      }
      else
      {
        float v = [[[rows objectAtIndex:index] valueForKey:@"_FailedTestCount"] floatValue];
        return [NSNumber numberWithFloat:v];
      }
    }
  }
  return nil;
}

And that’s it! You can find more info on Core Plot on their Google code page; i also recommend joining their mailing list for latest news and support.

by marc hoffman, January 26th, 2010

# Using NSPredicateEditor with DADataTable

Today I want to talk about NSPredicateEditor and how to use it with a DADataTable.

What is NSPredicateEditor…

Cocoa’s NSPredicateEditor class provides an excellent way to compose predicates at runtime. The main benefit is that the user needs to know nothing about predicates and their format, but with help of NSPredicateEditor can easily build quite complex conditions they need. Using NSPredicateEditor also allows to avoid any kind of typing errors, because in most of cases all the user needs is to do is just to select appropriate fields and values from popup buttons.

Here is the screenshot of Bugs 7 showing NSPredicateEditor that represents following condition: (Live == 1 AND AreaID == 4 AND OwnerID == 5) OR ID == 37222

NSPredicateEditor uses a list of NSPredicateEditorRowTemplate objects, where each row template describes certain elementary comparison predicate object.  Combining different row templates allows the NSPredicateEditor to represent compound predicates with unlimited complexity.

Usually, a row template holds three elements: left and right expressions and a condition between them. In our case, the left expression represents the column from our table and the right expression represents the value pattern for that column. Obviously, it is good to have template with most suitable editor for each column data type. DataAbstract for OS X provides proper templates for each fields that can be used in the table. In addition to standard  NSPredicateEditorRowTemplate DA brings several custom row templates that simplify building predicates for the tables.

The most interesting here is the DALookupFieldPredicateEditorRowTemplate class. This class allows to create row template for a lookup field, where the user can chose certain lookup value from list of allowed values, proposed by a popup button. It allows user to deal with meaningful values instead of just IDs. This is well shown in the figure above.

I should also mention DAFallbackPredicateEditorRowTemplate. This class describes special template for any predicate that is not supported by a given set of templates. For example if your editor tries to render a NSPredicate that comes into your application from outside and cannot understand a certain part of the compound predicate, then it will render it as “unsupported predicate” with help of DAFallbackPredicateEditorRowTemplate. This assures that the sub-predicate, while not editable in the NSPredicateEditor, will not get lost.

…and How Can You Use it?

Let’s see how to configure NSPredicateEditor instance for composing predicates for a certain custom DADataTable.

When you need to configure the editor for exposing a sub-set of columns only, you need to create array of row templates obtained from each table field you want to see in editor:

NSMutableArray *rowTemplates = [NSMutableArray arrayWithCapacity:[[da bugs] fieldCount]];
for (NSString *f in allowedFields)
{
  DAFieldDefinition *fd = [[da bugs] fieldByName:f];
  [rowTemplates addObjectsFromArray:[fd predicateEditorRowTemplates]];
}

Then you should supplement that array with additional row template for building compound predicates

NSPredicateEditorRowTemplate *compoundTemplate =
  [[[NSPredicateEditorRowTemplate alloc] initWithCompoundTypes:
    [NSArray arrayWithObjects:
      [NSNumber numberWithInt: NSAndPredicateType],
      [NSNumber numberWithInt: NSOrPredicateType],
      [NSNumber numberWithInt: NSNotPredicateType],
      nil]] autorelease];
[rowTemplates addObject:compoundTemplate];

and (optionally) add an instance of DAFallbackPredicateEditorRowTemplate for rendering unsupported predicates.

[rowTemplates addObject:[DAFallbackPredicateEditorRowTemplate rowTemplate]];

Finally, you should assign that templates array to your NSPredicateEditor instance

[editor setRowTemplates:rowTemplates];

If you want to expose all visible fields in the editor, then you can just use the convenient defaultPredicateEditorRowTemplates] method on the table, and whole configuration will be reduced to single line of code, as followings:

[editor setRowTemplates:[[da bugs] defaultPredicateEditorRowTemplates]];

That’s all. Your predicate editor is properly configured and you can use it for building any kind of predicates for given table.

You can use that editor to let the user define NSPredicates both for local filtering data in table like:

NSPredicate *p = [editor predicate];
rows = [[[myTable rows] filteredArrayUsingPredicate:p] retain];
[tableView reloadData];

or for creating Dynamic Where for server-side filtering data.

NSPredicate *p = [editor predicate];
DADynamicWhereClause *clause = [DADynamicWhereClause dynamicWhereClauseWithPredicate:p];
request = [rda beginGetDataTable:@"MyTable"
                          select:[self fieldsToSelect]
                           where:clause
                           start:NO];
[request setDelegate:self];
[request start];

I recomend to review our DAFilters sample that ships with DA/OSX, to see NSPredicateEditor and the techniques shown here in action.

by Alexander, January 18th, 2010

# Is that a Wiki in your Xcode?

We’re getting close to shipping our first release of Data Abstract for OS X as well as the 1.1 update for RemObjects SDK for OS X at the end of this month, and as part of crossing all the final Is and dotting all the remaining Ts, Carlo and i have been working on leveraging the tools in our new documentation tool chain to integrate the RemObjects Wiki (or, the relevant part of it) as Xcode documentation:

What you are seeing here is our wiki as standard Xcode doc set. You can browse and search it just as you would the standard Apple docs; you can navigate to it by Cmd+Option-Double-clicking identifiers in your code – in other words, you get the full documentation experience.

The version shown here works directly on the live wiki – meaning as soon as changes and updates are made to the pages online, you will see them reflected in the wiki as well. In the long term (not for this release, yet), we’ll also be providing an offline version, that contains a snapshot of the entire wiki, for offline use (i.e, when you’re working on the proverbial plane).

The Docset will also update via RSS feed, so content (in the offline version) and structure changes (such as the addition of new pages to the indexes, etc) will automatically update within Xcode, on a regular basis.

Stay tuned for more info on RO/OSX and DA/OSX, as we near release.

by marc hoffman, October 12th, 2009

# iPhone & Desktop Pairing with RemObjects SDK

One common scenario when developing iPhone apps is that you have a desktop application of some sorts that you want your iPhone to pair with – be it to sync data, remote control one with the other, or establish any other kind of communication.

In this scenario, the desktop app would be the “server”, in RemObjects SDK terminology, and the iPhone would be the client.

For the next release of RemObjects SDK for OS X, coming next month, we’ve created a nice sample that illustrates how to easily achieve this, and i figured i would post a small screencast of the sample in action, below.

What you see is a desktop app written in Delphi (although .NET will do just fine, as well), which for sample purposes has a pretty minimal UI, but in real life would be your full-fledged desktop UI app. When the iPhone client is a launched, it automatically detects any instance of your desktop app running on the local network and shows them in a list.

(The UI for this would be up to the application designer, obviously; for simplicity we simply show them all in a UITableView. In real life, if only one server was found you’d probably want to forgo the list altogether and just ask the user if he wants to connect).

Once the user picks a server, communication is initiated, by the iPhone calling a service method and passing it a unique GUID it generated. Since this is the first time these two are talking to each other, the server rejects the phone, but displays a random 4-digit code in it’s UI (this code is not known to the phone, at this stage). The phone asks the user to enter the code and, once done, sends it to the server to confirm the pairing. Once successful, the server stores the client’s GUID for future reference – and any future calls (even after the phone app has been restarted) will work right away.

Of course instead of showing an UIAlertView, your application would instead commence doing it’s real work.

Here’s the app in action:

by marc hoffman, September 18th, 2009

# An Update on Data Abstract for OS X

I realize it’s been a while since i talked about Data Abstract for OS X, so i figured today would be a good time to post a small teaser for what’s coming up in the next beta drop – most likely before the end of the week.

The previous beta, which we shipped in early June, provided read-only access to Data Abstract servers created using .NET and Delphi. Since then we’ve been busy both refining that support but also, more importantly, adding the ability to make changes, persist deltas and and apply updated back to the server.

Below, you’ll see a screenshot of a small sample application that downloads a table from our unified PCTrade sample database, allows to make changes, and post them back. in the background, you see the sample server (running in a Virtual Machine on Windows) accepting and handling those update requests.

The app uses the briefcase model, so it can work offline, with changes staying local until the user presses the “Update” button to send them back to the server; of course DA will also all you to sending changes to the server implicitly, to provide a more seamless “online” experience for the user.

As you might notice, the sample also leverages the new ROZeroConf support we shipped in May, to find the server on the local network without manual configuration (in this case, the server machine is called VEMMY, as can be seen in the popup button in the client’s toolbar – if more than one server were running on the network, the user could pick which one to use, defaulting to the one found first).

by marc hoffman, July 15th, 2009

# WWDC09 Roundup

So, WWDC09, Apple’s World Wide Developer Conference, is over, and i’m sitting in my room at the excellent Hotel Monaco getting ready to leave San Francisco.

For every conference i go to, i plan to blog more extensively about it, but of course that never happens, because there’s just too much good stuff going on throughout the week to find the time to sit down and write about it; WWDC has been no different.

I know most people following WWDC from afar only see the keynote on monday, but of course that is only the start of a full week of info straight from the firehose, and – while fun – pales in comparisson to the real meat of the conference.

This year, there has been lots of exciting news from the developer tools front. Xcode, the development IDE for both Mac and iPhone, is getting vastly expanded, with things such as deep integration of the Clang Static Analyzer (which admittedly i had been playing with for a month now, so it was not brand new for me, this week) and a new and vastly better Clang-LLVM based compiler to replace GCC (which still is the default, though). And that’s just the tip of the eisberg. And the rest of the tool suite, such as Instruments, is seeing significant improvements as well.

Due to the work i do at RemObjects, i always find myself in some sort of a “meta-developer” position at conferences like these. While most attendees see, say, new improvements in Instruments and think “that’s great, how can that help me write apps?”, i think “great, how can we leverage this to help our customers write their apps?”.

And i think there’s great potential here for deeper integration of RemObjects SDK and Data Abstract with tools such as Instruments, to make your life easier (and the same goes for GCD).

In addition to the tool chain, there’s also lots of good stuff happening in the OS and libraries, to benefit developers. Of course this is all largely under NDA, so i cannot say too much, but just take Grand Central Dispatch, for instance.

While GCD was already announced (not in the public keynote, but to developers) at last year’s WWDC, this week went into much more detail, and it’s amazing to see just at what level of both the OS and its applications, but also the developer APIs, GCD is being employed. Having a great technology as GCD made available is one thing (and the Parallel Framework on .NET offers something comparable), but seeing how virtually every of the OS’s APIs has been revised to make use of it, and seeing – first hand – the sort of performance improvements Apple has been able to get out of the technology by consistently applying it to all of their code as well, is mind blowing.

With this, and the great enhancements to the entire tool chain, i feel once again ensured that this is a great platform (or actually, two great platforms) to invest in.

And to think the entire tool chain, from Xcode to all the professional tools it comes with, comes free with the system (remember that, the text time someone wields the Apple Tax myth).

In any case, i should start to pack and catch my flight. It’s been a great week of learning and meeting great people, and i, for one, already can’t wait for WWDC 2010…

yours
marc hoffman
Chief Architect

ps: a couple of great food recommendations in San Francisco:

  • OSHA Thai Restaurant on 2nd, between Howard and Mission. Awesome food.
  • John’s Grill on Ellis, between Stockton and Powell. Home of the Maltese Falcon and great steaks and seafood
by marc hoffman, June 13th, 2009

# Introducing “RemObjects Builder”

This month is probably the busiest we’ve had in a long time. Last week, we RTMed a new release of Delphi Prism with many major new features, and also shipped the first beta of Data Abstract for OS X to our testers and pre-order customers. And we’re preparing for what probably will be the most major update to our Data Abstract and RemObjects SDK suite of products for Delphi and .NET in the last year or two, later this month.

So what better time is there to start a new project, right?

What happened was that last week i was sitting at my MacBook and preparing the beta drop for DA/OSX, continuously running my bash-based build script in terminal, finding the next build error (this was the first time i was automating the DA build and getting it all put together) and realizing i really missed FinalBuilder, the excellent tool we use to run the automated builds for our windows products. I shot a few messages out via twitter, and it seems that everyone else did, too!

I figured, a tool was needed to run builds in a more visual way, to allow me to better see what was happening, what was currently building, and at which step things went south if they did. Xcode’s (and by extensions, GCC’s) command line build output is way to verbose to follow along with it in terminal.

So i put a couple hours aside and started “RemObjects Builder”, the tool you see below, which is basically a runner for bash based scripts that lets you see progress and results nicely.

Mind you, the idea here was not to create a full-blown FinalBuilder clone – that’s far too much work, not to mention overkill at least for what i need. I’m perfectly fine with writing and editing build scripts in a text editor (and Builder runs plain shell script files, so the same file can be run in Builder, or in Terminal), i’m mainly interested in the more visual run process.

But who knows what the project takes off to…

I’ve decided to turn this into an open source project hosted at code.remobjects.com, in order to give back to the community, and also to get some more people involved in the project.

For now, the project is still marked as private; there’s still some (many) rough edges, and i don’t want any potential users or contributors turned off by those, but if you’re interested in participating in the project, just sign up on code.remobjects.com and send me your username – i’ll activate the project for you. Hopefully, in a couple weeks we can turn it public so it is accessible by everybody.

Let me know what you think!

 

ps: no, do not ask what TwinPeaks.framework is ;)
by marc hoffman, May 11th, 2009

# Teaser: PCTrade sample client for DA/OSX

One of the new features for Data Abstract we’ll be shipping in the May releases is a completely revamped sample infrastructure. I’ll be talking more about this in a future post later this week, but basically, we’ve created one big sample server application, based around a fictional “PC Trade” database that we ship for SQLite, MSSQL and Firebird, that all new client applications talk to.

The idea being that without major setup, you can “just run” the server, and then play around with the client applications.

What i did in the last couple hours (literally) today is create a client application for the iPhone for this. With literally a handful of lines of DA code, “PCTrade for iPhone” can browse available products, client data, and review orders. All data fetching is done asynchronously in the background, making sure the UI always stays responsive.

In a nutshell, the code below does all the magic to – in this example – fetch Products, via DA SQL. The rest of the app is standard Cocoa Touch plumbing.


- (void)viewDidLoad
{
  //...
  DAAsyncRequest *a = [[rda beginGetDataForSQL:@"SELECT * FROM Products" start:NO];
  [a setDelegate:self];
  [a start];
}
 
- (void)remoteDataAdapter:(DARemoteDataAdapter *)adapter didReceiveData:(NSData *)data forAsyncRequest:(DAAsyncRequest *)request
{
  DABin2DataStreamer *bin2 = [DABin2DataStreamer dataStreamerWithData:data];
  [table release];
  table = [[bin2 getDataTable:@"sql"] retain];
  [[self tableView] reloadData];
}

We’re getting pretty close to releasing a first Data Abstract for OS X beta to pre-order customers and testers, so stay tuned for more information on that, over the next few weeks. Also, as mentioned before, lookout for a more detailed post on the new PCTrade suite of sample apps, later this week.

by marc hoffman, April 26th, 2009

# ARTICLE: Writing a RemObjects SDK for .NET Server and Mac Client – Start to Finish

i just finished writing a new walkhru article on creating a RemObjects SDK for .NET server and matching RemObjects SDK for OSX client. Next go giving a complete overview over that, the article also gives a sneak peak at the ZeroConf support that is coming in RO/.NET (and RO/Delphi, as well) this May, which should be of interest to non-OS X developers, as well!

The article can be found on the wiki.

Enjoy; feedback appreciated!

by marc hoffman, April 21st, 2009