<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>RemObjects Blogs</title>
	<atom:link href="http://blogs.remobjects.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blogs.remobjects.com</link>
	<description>Remobjects Software Blogs</description>
	<lastBuildDate>Mon, 17 Jun 2013 17:27:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<item>
		<title>iOS 7 and OS X Mavericks</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/06/17/p6059</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/06/17/p6059#comments</comments>
		<pubDate>Mon, 17 Jun 2013 17:27:33 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[ROFX]]></category>
		<category><![CDATA[WWDC]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=6059</guid>
		<description><![CDATA[As you have probably heard by now, last week Apple announced iOS 7 and OS X Mavericks, new major versions of both its flag-ship operating systems. I had the privilege of being on site in San Francisco and attending WWDC in person, but the keynote with the core announcements is available for public viewing by [...]]]></description>
				<content:encoded><![CDATA[<p>As you have probably heard by now, last week Apple announced <strong>iOS 7</strong> and <strong>OS X Mavericks</strong>, new major versions of both its flag-ship operating systems. I had the privilege of being on site in San Francisco and attending WWDC in person, but the <a href="http://www.apple.com/apple-events/june-2013/">keynote</a> with the core announcements is <a href="http://www.apple.com/apple-events/june-2013/">available for public viewing</a> by anyone, and the remaining ~100 sessions of the conference are also available <a href="https://developer.apple.com/wwdc/videos/">for free to all registered developers</a> (major kudos to Apple for that, and more importantly, for making these videos available so <em>fast</em>, in most cases on the same day as the actual presentations!).</p>
<p><strong>iOS 7</strong> is a major new release and &ndash; most observers agree &ndash; a game changer. It&#8217;s a whole new UI paradigm for the OS, and will be a very exciting release for both users and developers; there are a whole bunch of new technologies that will let you create even better iOS apps, and will make the whole iOS experience even better for the user — in the core OS or with your apps.</p>
<p>Due to the massive UI overhaul, most iOS apps will need a serious rethinking for iOS 7 to stay relevant &ndash; which means extra work for developers, but also extra opportunities. From what i can tell (and am allowed to tell), switching an application over to the core iOS 7 &#8220;look&#8221; will be simple, but really making an app feel at home on iOS7 will require a lot of thought — no way around it.</p>
<p>I have already started moving two of our (internal) apps to iOS 7 while on site in San Francisco, simply because after (foolhardily) upgrading my main phone to the new OS, i could no longer stand looking at the old UI ;). One app is &#8220;done&#8221; and was relatively straight-forward &ndash; <em>mainly</em> a matter of rebuilding with the iOS 7 SDK, and making a few adjustments here and there to better embrace the new style; the other will be more work.</p>
<p><strong>OS X Mavericks</strong> (if you don&#8217;t like the name, you are not alone. Virtually everybody i talked to or heard talk about it found it &#8220;weird&#8221;) is a smaller upgrade, by comparison, but also a significant release with a ton of exciting technologies for developers &ndash; two that were highlighted in the <a href="http://www.apple.com/apple-events/june-2013/">keynote</a> include the new Maps API and cool new energy-saving APIs and technologies. (And if you&#8217;re not excited by being able to make your apps more power-efficient, then you have no business developing Mac apps! ;).)</p>
<p>Of course the big question you&#8217;re all asking is how <strong>Oxygene for Cocoa</strong> is working with the new iOS 7 and OS X Mavericks. The good (and slightly unexciting, because expected) news is: it works just fine. We&#8217;ve long had an <a href="http://wiki.oxygenelanguage.com/en/Importing_a_New_or_Beta_SDK_for_Use_with_Oxygene_for_Cocoa">article on the Wiki</a> that discusses the (simple) steps for hooking up Oxygene with new beta SDKs, and Oxygene is working fine with iOS 7 and with Mavericks (although i do recommend grabbing the latest beta drop of Oxygene, as we already made some tweaks and improvements there).</p>
<p>All the new APIs (IIRC Apple mentioned a number of 1500 new APIs being available) will work with Oxygene out of the box &ndash; no need to wait for anyone to create any wrappers or headers for you, and re-building your Oxygene apps with the iOS 7 SDK will give you the new iOS 7 look right away (but not save you from re-examining how to <em>really</em> embrace iOS 7 best with your app, of course).</p>
<p>There are also a few new non-API features that we&#8217;ll be embracing with Oxygene as well, but unfortunately those are (afaict) all under NDA, so i cannot talk about them yet. But suffice to say over the next few months we will of course be doing a lot of testing with Oxygene and the new APIs and SDKs to keep Oxygene up to date with the SDKs and the <a href="https://developer.apple.com/technologies/tools/whats-new.html">Xcode 5</a> tool chain.</p>
<p>Of course we&#8217;ll also be testing <strong>Data Abstract</strong> and <strong>RemObjects SDK for Cocoa</strong> with the new SDKs, and (where applicable) expanding them with support for new APIs. In my testing so far, they work great (both the apps i mentioned above are DA-based, and run fine on iOS 7, for example).</p>
<h2>Support</h2>
<p>Talking about new iOS and OS X SDKs is always a tightrope walk, as there&#8217;s a lot of information that&#8217;s under NDA (but available to all registered Apple developers &ndash; so <em>do</em> make sure you check out the beta builds and all the videos from WWDC). But Oxygene, as well as RO/DA for Cocoa, are already working great with the new operating systems, and we&#8217;ll be working hard to expand those parts that do need explicit support and work to fully embrace the new OSs.</p>
<p>If you have any specific questions regarding support for or issues with the new SDKs, there&#8217;s two places to get help: for one, we&#8217;ll be monitoring and participating in Apple&#8217;s <a href="https://devforums.apple.com">beta forums</a>, so you can post questions about Oxygene there (maybe add &#8220;(Oxygene)&#8221; to the subject so we can find them easier). And you can also always directly email <a href="mailto:support@remobjects.com">support</a>.</p>
<p>We cannot discuss the iOS 7 or OS X Mavericks Beta SDKs on <a href="http://connect.remobjects.com">Connect</a>; you could be violating your NDA by posting details there, and we&#8217;d be doing the same by answering. So be careful.</p>
<h2>Summary</h2>
<p>I&#8217;m very excited about both iOS 7 and Mavericks (and i assume i&#8217;ll eventually get over the name, too), and so should you. I&#8217;m looking forward to seeing what you&#8217;ll build on the new OSs with Oxygene and Data Abstract.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/06/17/p6059/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Abstract Sample for Oxygene for Cocoa</title>
		<link>http://blogs.remobjects.com/blogs/alexk/2013/06/17/p6028</link>
		<comments>http://blogs.remobjects.com/blogs/alexk/2013/06/17/p6028#comments</comments>
		<pubDate>Mon, 17 Jun 2013 16:02:06 +0000</pubDate>
		<dc:creator>Alexander</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=6028</guid>
		<description><![CDATA[Hi guys, Recently I&#8217;ve spotted a question about Nougat samples in the support thread. Unfortunately, we didn&#8217;t offer any sample applications at that time, so I&#8217;ve tried to quickly compose one. We&#8217;ve already proposed some New Project templates for Data Abstract for Cocoa though: Using these templates, and after going through several steps in the [...]]]></description>
				<content:encoded><![CDATA[<p>Hi guys,</p>
<p>Recently I&#8217;ve spotted a question about <a href="http://wiki.oxygenelanguage.com/en/Nougat" title="Nougat" target="_blank">Nougat</a> samples in the support thread. Unfortunately, we didn&#8217;t offer any sample applications at that time, so I&#8217;ve tried to quickly compose one.</p>
<p>We&#8217;ve already proposed some <em>New Project</em> templates for <strong>Data Abstract for Cocoa</strong> though:</p>
<p><a href="http://blogs.remobjects.com/blogs/alexk/2013/06/17/p6028/nougat-templates-2" rel="attachment wp-att-6050"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/06/Nougat-Templates-1024x852.png" alt="Nougat Templates" width="591" height="491" class="aligncenter size-large wp-image-6050" /></a></p>
<p>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 <em>#warning</em> directive).</p>
<p>So I&#8217;ve started with this <em>New Project wizard</em> and created a client for the <em>PCTrade sample domain</em> exposed by <a href="http://wiki.remobjects.com/wiki/Relativity_Server" title="Relativity" target="_blank">Relatvitiy server</a>.</p>
<p>In this sample, I want to show several things:</p>
<ul>
<li>Working with <a href="http://wiki.remobjects.com/wiki/Relativity_Server" title="Relativity" target="_blank">Relativity server</a>.</li>
<li>Downloading data at the client side in an asynchronous way.</li>
<li>Using Cocoa NotificationCenter.</li>
<li>Master-Detail navigation in the data.</li>
<li>Using <a href="http://wiki.remobjects.com/wiki/DACalculatedFieldDefinition_Class" title="Calculated Fields" target="_blank">Calculated fields</a> for the DADataTable.</li>
<li>Conditional formatting of the table view cells.</li>
<li>The application should be universal and support both iPhone and iPad.</li>
</ul>
<p>At the same time, I&#8217;ve tried to keep things as simple as possible to make it easy to understand common ideas.</p>
<p>So let&#8217;s start:</p>
<h2>Working with Relativity domains</h2>
<p>Almost all implementation required for connecting to the <a href="http://wiki.remobjects.com/wiki/Relativity_Server" title="Relativity" target="_blank">Relativity server</a>, 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 <em>#warning</em> directive. For example, in the <em>DataAccess.pas </em>file you can see the following place:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;">    <span style="color: #008000; font-style: italic;">{$WARNING  Define your server address and Relativity domain name, below.}</span>
    <span style="color: #000000; font-weight: bold;">const</span> SERVER_URL  <span style="color: #000066;">=</span>                    <span style="color: #ff0000;">'http://192.168.0.22:7099/bin'</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">const</span> SERVICE_NAME <span style="color: #000066;">=</span>                   <span style="color: #ff0000;">'DataService'</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">const</span> RELATIVITY_DOMAIN  <span style="color: #000066;">=</span>             <span style="color: #ff0000;">'PCTrade Sample'</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">const</span> DOMAIN_SCHEMA  <span style="color: #000066;">=</span>                 <span style="color: #ff0000;">'PCTrade'</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Here you can adjust the URL of your <a href="http://wiki.remobjects.com/wiki/Relativity_Server" title="Relativity" target="_blank">Relativity server</a> (my server uses http://192.168.0.22:7099/bin).<br />
These constants will also be used for configuring the <a href="http://wiki.remobjects.com/wiki/DARemoteDataAdapter_Class" title="DARemoteDataAdapter" target="_blank">RemoteDataAdapter</a> instance. </p>
<p>Another place that requires our attention is in the <em>AppDelegate.pas</em> and holds the passwords to log in to the Relativity domain:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> AppDelegate<span style="color: #000066;">.</span><span style="color: #000000;">needLogin</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> aLogin<span style="color: #000066;">:</span> String<span style="color: #000066;">&#41;</span> password<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> aPassword<span style="color: #000066;">:</span> String<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> Boolean<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #808080; font-style: italic;">// The DataAccess automatically takes care of storing login information in Settings and Key Chain</span>
  <span style="color: #808080; font-style: italic;">// and retrieving it as necessary. This method is only called when no login is stored (i.e. on first</span>
  <span style="color: #808080; font-style: italic;">// run) or if the retrieved login was rejected by the server.</span>
  <span style="color: #808080; font-style: italic;">// Typically, you would implement this method to bring up the UI that asks the user for his credentials.</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">// By default, new Relativity Server domains will use &quot;Data&quot;/&quot;Relativity&quot; as login, unless</span>
  <span style="color: #808080; font-style: italic;">// the login provider setup has been changed by the administrator.</span>
  aLogin <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'Data'</span><span style="color: #000066;">;</span>
  aPassword <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'Relativity'</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">result</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #000066;">;</span> <span style="color: #808080; font-style: italic;">// return YES if the user provided login details, or NO if the user canceled</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>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&#8217;m trying to keep it simple here.</p>
<h2>Downloading data</h2>
<p>Again, like in the point above, almost all implementation for downloading data from the server was generated automatically by the <em>new project wizard</em>. </p>
<p>You may notice that all the tables we selected in one of the last wizard step, were created with the appropriate properties in <em>DataAccess.pas</em> and code has been generated to fill them.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">downloadData</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #808080; font-style: italic;">// ToDo: Add code to download data from server</span>
  <span style="color: #808080; font-style: italic;">// You will need to define fields and, if necessary, properties for your tables.</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">var</span> tableNames <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">new</span> NSMutableArray&lt;String&gt;<span style="color: #000066;">;</span>
  tableNames<span style="color: #000066;">.</span><span style="color: #000000;">addObject</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Clients'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  tableNames<span style="color: #000066;">.</span><span style="color: #000000;">addObject</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'OrderDetails'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  tableNames<span style="color: #000066;">.</span><span style="color: #000000;">addObject</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Orders'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">var</span> tables <span style="color: #000066;">:</span><span style="color: #000066;">=</span> fRDA<span style="color: #000066;">.</span><span style="color: #000000;">getDataTables</span><span style="color: #000066;">&#40;</span>tableNames<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  Clients <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tables<span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Clients'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
  OrderDetails <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tables<span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'OrderDetails'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
  Orders <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tables<span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Orders'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

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

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">loadInitialData</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  dispatch_async<span style="color: #000066;">&#40;</span>dispatch_get_global_queue<span style="color: #000066;">&#40;</span>DISPATCH_QUEUE_PRIORITY_DEFAULT<span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">method</span> <span style="color: #000000; font-weight: bold;">begin</span>
      <span style="color: #000066;">...</span>
      <span style="color: #000000;">downloadData</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000066;">...</span>
      <span style="color: #000000;">dispatch_async</span><span style="color: #000066;">&#40;</span>dispatch_get_main_queue<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #000066;">-</span>&gt; triggerDataReady<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

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

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">triggerDataReady</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  dataReady <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #000066;">;</span>
  NSNotificationCenter<span style="color: #000066;">.</span><span style="color: #000000;">defaultCenter</span><span style="color: #000066;">.</span><span style="color: #000000;">postNotificationName</span><span style="color: #000066;">&#40;</span>NOTIFICATION_DATA_READY<span style="color: #000066;">&#41;</span> object<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  NSLog<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'data is ready.'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">// ToDo: Add any processing you want to do once the data is fully ready</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>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 <em>ClientsViewController.pas</em> file.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">method</span> ClientsViewController<span style="color: #000066;">.</span><span style="color: #000000;">viewDidLoad</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">inherited</span> viewDidLoad<span style="color: #000066;">;</span>
  <span style="color: #808080; font-style: italic;">// Do any additional setup after loading the view, typically from a nib</span>
  <span style="color: #000066;">...</span>
  <span style="color: #000000;">NSNotificationCenter</span><span style="color: #000066;">.</span><span style="color: #000000;">defaultCenter</span><span style="color: #000066;">.</span><span style="color: #000000;">addObserver</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">&#41;</span> 
                                     &amp;selector<span style="color: #000066;">&#40;</span>selector<span style="color: #000066;">&#40;</span>dataReady<span style="color: #000066;">:</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span> 
                                     name<span style="color: #000066;">&#40;</span>DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">NOTIFICATION_DATA_READY</span><span style="color: #000066;">&#41;</span> 
                                     object<span style="color: #000066;">&#40;</span>DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">sharedInstance</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">...</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">method</span> ClientsViewController<span style="color: #000066;">.</span><span style="color: #000000;">dataReady</span><span style="color: #000066;">&#40;</span>notification<span style="color: #000066;">:</span> NSNotification<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  tableView<span style="color: #000066;">.</span><span style="color: #000000;">reloadData</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>That means that when our <em>ClientsViewController</em> receives the <em>DataReady</em> notification, the <em>dataReady:</em> method must be invoked, which then refreshes the content of the table view.</p>
<h2>Master-Detail navigation</h2>
<p>This feature is part of the <em>New Project template</em>. By default, it generates already configured <em>Master</em> and <em>Detail</em> view controllers and the corresponding <em>storyboards</em> files with proper transitions between views inside.</p>
<p>Concrete implementation depends on device type.<br />
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.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> ClientsViewController<span style="color: #000066;">.</span><span style="color: #000000;">prepareForSegue</span><span style="color: #000066;">&#40;</span>segue<span style="color: #000066;">:</span> UIStoryboardSegue<span style="color: #000066;">&#41;</span> sender<span style="color: #000066;">&#40;</span>sender<span style="color: #000066;">:</span> id<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> segue<span style="color: #000066;">.</span><span style="color: #000000;">identifier</span><span style="color: #000066;">.</span><span style="color: #000000;">isEqualToString</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'showOrders'</span><span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000000; font-weight: bold;">var</span> ip <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tableView<span style="color: #000066;">.</span><span style="color: #000000;">indexPathForCell</span><span style="color: #000066;">&#40;</span>sender<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> tableRow <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">dataTable</span><span style="color: #000066;">.</span><span style="color: #000000;">rowAtIndex</span><span style="color: #000066;">&#40;</span>ip<span style="color: #000066;">.</span><span style="color: #000000;">row</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    segue<span style="color: #000066;">.</span><span style="color: #000000;">destinationViewController</span><span style="color: #000066;">.</span><span style="color: #000000;">setDetailItem</span><span style="color: #000066;">&#40;</span>tableRow<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>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 <em>didSelectRow</em> event and provide the details data for the detail controller as shown below:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> ClientsViewController<span style="color: #000066;">.</span><span style="color: #000000;">tableView</span><span style="color: #000066;">&#40;</span>tableView<span style="color: #000066;">:</span> UITableView<span style="color: #000066;">&#41;</span> didSelectRowAtIndexPath<span style="color: #000066;">&#40;</span>indexPath<span style="color: #000066;">:</span> NSIndexPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> UIDevice<span style="color: #000066;">.</span><span style="color: #000000;">currentDevice</span><span style="color: #000066;">.</span><span style="color: #000000;">userInterfaceIdiom</span> <span style="color: #000066;">=</span> UIUserInterfaceIdiom<span style="color: #000066;">.</span><span style="color: #000000;">UIUserInterfaceIdiomPad</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000000; font-weight: bold;">var</span> tableRow <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">dataTable</span><span style="color: #000066;">.</span><span style="color: #000000;">rowAtIndex</span><span style="color: #000066;">&#40;</span>indexPath<span style="color: #000066;">.</span><span style="color: #000000;">row</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    OrdersViewController<span style="color: #000066;">.</span><span style="color: #000000;">detailItem</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tableRow<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

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

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">OrdersByClient</span><span style="color: #000066;">&#40;</span>client<span style="color: #000066;">:</span> String<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> NSArray<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">var</span> filterPredicate <span style="color: #000066;">:</span><span style="color: #000066;">=</span> NSPredicate<span style="color: #000066;">.</span><span style="color: #000000;">predicateWithFormat</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Client == %@'</span><span style="color: #000066;">,</span> client<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">result</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">Orders</span><span style="color: #000066;">.</span><span style="color: #000000;">rowsFilteredUsingPredicate</span><span style="color: #000066;">&#40;</span>filterPredicate<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<h2>Using Calculated fields for the DADataTable</h2>
<p>As you might know, we can easily extend any existing <a href="http://wiki.remobjects.com/wiki/DADataTable_Class" title="DADataTable" target="_blank">DADataTable</a> 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).</p>
<p>There is the special <em>setupData</em> method in the <em>DataAccess</em> 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.</p>
<p>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.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">setupData</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #808080; font-style: italic;">// Use this method to implement any setup that is needed on your data tables, such as</span>
  <span style="color: #808080; font-style: italic;">// creating lookup or calculated fields, etc.</span>
  <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">Clients</span><span style="color: #000066;">.</span><span style="color: #000000;">addCalculatedFieldName</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'OrdersCnt'</span><span style="color: #000066;">&#41;</span> 
                            dataType<span style="color: #000066;">&#40;</span>__enum_DADataType<span style="color: #000066;">.</span><span style="color: #000000;">datInteger</span><span style="color: #000066;">&#41;</span> 
                              target<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">&#41;</span> 
                           &amp;selector<span style="color: #000066;">&#40;</span>selector<span style="color: #000066;">&#40;</span>calculateOrdersCntForClientRow<span style="color: #000066;">:</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> 
&nbsp;
  <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">Orders</span><span style="color: #000066;">.</span><span style="color: #000000;">addCalculatedFieldName</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'OrderSum'</span><span style="color: #000066;">&#41;</span> 
                             dataType<span style="color: #000066;">&#40;</span>__enum_DADataType<span style="color: #000066;">.</span><span style="color: #000000;">datCurrency</span><span style="color: #000066;">&#41;</span> 
                               target<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">&#41;</span> 
                            &amp;selector<span style="color: #000066;">&#40;</span>selector<span style="color: #000066;">&#40;</span>calculateSumForOrderRow<span style="color: #000066;">:</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> 
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>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:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> DataAccess<span style="color: #000066;">.</span><span style="color: #000000;">calculateSumForOrderRow</span><span style="color: #000066;">&#40;</span>row<span style="color: #000066;">:</span> DADataTableRow<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> id<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #808080; font-style: italic;">// Get the Order ID value from the row </span>
  <span style="color: #000000; font-weight: bold;">var</span> orderID<span style="color: #000066;">:</span> Integer <span style="color: #000066;">:</span><span style="color: #000066;">=</span> row<span style="color: #000066;">.</span><span style="color: #000000;">valueForKey</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'OrderId'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #000000;">integerValue</span><span style="color: #000066;">;</span>
  <span style="color: #808080; font-style: italic;">// Prepare filter to obtain details on given order</span>
  <span style="color: #000000; font-weight: bold;">var</span> condition<span style="color: #000066;">:</span> NSPredicate <span style="color: #000066;">:</span><span style="color: #000066;">=</span> NSPredicate<span style="color: #000066;">.</span><span style="color: #000000;">predicateWithFormat</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Order == %d'</span><span style="color: #000066;">,</span> orderID<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #808080; font-style: italic;">// Get the order total</span>
  <span style="color: #000000; font-weight: bold;">var</span> orderSum<span style="color: #000066;">:</span> Double <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">OrderDetails</span><span style="color: #000066;">.</span><span style="color: #000000;">rowsFilteredUsingPredicate</span><span style="color: #000066;">&#40;</span>condition<span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #000000;">valueForKeyPath</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'@sum.Total'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #000000;">doubleValue</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">// Wrap it into an id object and return</span>
  <span style="color: #000000; font-weight: bold;">exit</span> NSNumber<span style="color: #000066;">.</span><span style="color: #000000;">numberWithDouble</span><span style="color: #000066;">&#40;</span>orderSum<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<h2>Conditional cell formatting</h2>
<p>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. </p>
<p>We will use a similar approach for our application. We already have the method <i>tableView() cellForRowAtIndexPath(): UITableViewCell</i> which composes the cell for any table row we want to show.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> ClientsViewController<span style="color: #000066;">.</span><span style="color: #000000;">tableView</span><span style="color: #000066;">&#40;</span>tableView<span style="color: #000066;">:</span> UITableView<span style="color: #000066;">&#41;</span>
                 cellForRowAtIndexPath<span style="color: #000066;">&#40;</span>indexPath<span style="color: #000066;">:</span> NSIndexPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> UITableViewCell<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">var</span> CellIdentifier <span style="color: #000066;">:</span><span style="color: #000066;">=</span> &quot;Cell&quot;<span style="color: #000066;">;</span>
  <span style="color: #808080; font-style: italic;">// Try to obtain cached cell</span>
  <span style="color: #000000; font-weight: bold;">result</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tableView<span style="color: #000066;">.</span><span style="color: #000000;">dequeueReusableCellWithIdentifier</span><span style="color: #000066;">&#40;</span>CellIdentifier<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">// This is required only if you are targetting iOS 5.1 or lower</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #000000; font-weight: bold;">not</span> <span style="color: #000066;">assigned</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #808080; font-style: italic;">// If there is no such cell cached, then just create a new one</span>
    <span style="color: #000000; font-weight: bold;">result</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">new</span> UITableViewCell withStyle<span style="color: #000066;">&#40;</span>UITableViewCellStyle<span style="color: #000066;">.</span><span style="color: #000000;">UITableViewCellStyleValue1</span><span style="color: #000066;">&#41;</span> 
                                  reuseIdentifier<span style="color: #000066;">&#40;</span>CellIdentifier<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>  
  
  <span style="color: #808080; font-style: italic;">// Note that we used UITableViewCellStyleValue1 as the UITableViewCellStyle</span>
  <span style="color: #808080; font-style: italic;">// which makes the cell with the value aligned to the left side and the detail value aligned to the right side of the cell</span>
  <span style="color: #000000; font-weight: bold;">var</span> tableRow <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">.</span><span style="color: #000000;">dataTable</span><span style="color: #000066;">.</span><span style="color: #000000;">rowAtIndex</span><span style="color: #000066;">&#40;</span>indexPath<span style="color: #000066;">.</span><span style="color: #000000;">row</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">textLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">text</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tableRow<span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'ClientName'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">// Get the count of orders (as you remember, OrdersCnt is the calculated field)</span>
  <span style="color: #000000; font-weight: bold;">var</span> ordersCnt<span style="color: #000066;">:</span> Integer <span style="color: #000066;">:</span><span style="color: #000066;">=</span> tableRow<span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'OrdersCnt'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">:</span>integerValue<span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">// And depending on the orders count we can use different colors and different icons for the given cells</span>
  <span style="color: #000000; font-weight: bold;">case</span> ordersCnt <span style="color: #000000; font-weight: bold;">of</span>
    <span style="color: #0000ff;">0</span><span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">begin</span> 
        <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">textColor</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span>  UIColor<span style="color: #000066;">.</span><span style="color: #000000;">blueColor</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">imageView</span><span style="color: #000066;">.</span><span style="color: #000000;">image</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> UIImage<span style="color: #000066;">.</span><span style="color: #000000;">imageNamed</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'1'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">text</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'No orders'</span><span style="color: #000066;">;</span> 
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #0000ff;">1</span><span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">begin</span>
      <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">textColor</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> UIColor<span style="color: #000066;">.</span><span style="color: #000000;">orangeColor</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">imageView</span><span style="color: #000066;">.</span><span style="color: #000000;">image</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> UIImage<span style="color: #000066;">.</span><span style="color: #000000;">imageNamed</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'2'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">text</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> NSString<span style="color: #000066;">.</span><span style="color: #000000;">stringWithFormat</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'%d order'</span><span style="color: #000066;">,</span> ordersCnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #0000ff;">2</span><span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">begin</span>
      <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">textColor</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> UIColor<span style="color: #000066;">.</span><span style="color: #000000;">magentaColor</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">imageView</span><span style="color: #000066;">.</span><span style="color: #000000;">image</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> UIImage<span style="color: #000066;">.</span><span style="color: #000000;">imageNamed</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'3'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">text</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> NSString<span style="color: #000066;">.</span><span style="color: #000000;">stringWithFormat</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'%d orders'</span><span style="color: #000066;">,</span> ordersCnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
       <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">textColor</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span>  UIColor<span style="color: #000066;">.</span><span style="color: #000000;">redColor</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
       <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">imageView</span><span style="color: #000066;">.</span><span style="color: #000000;">image</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> UIImage<span style="color: #000066;">.</span><span style="color: #000000;">imageNamed</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'4'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
       <span style="color: #000000; font-weight: bold;">result</span><span style="color: #000066;">.</span><span style="color: #000000;">detailTextLabel</span><span style="color: #000066;">.</span><span style="color: #000000;">text</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> NSString<span style="color: #000066;">.</span><span style="color: #000000;">stringWithFormat</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'%d orders'</span><span style="color: #000066;">,</span> ordersCnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>As a result of our efforts above, we now have the following application:</p>
<p><a href="http://blogs.remobjects.com/blogs/alexk/2013/06/17/p6028/nougat-da-for-ios-application" rel="attachment wp-att-6045"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/06/Nougat-DA-for-iOS-application-1024x939.png" alt="Nougat DA for iOS application" width="591" height="541" class="aligncenter size-large wp-image-6045" /></a></p>
<p>And finally, as a small bonus, this is how it looks in iOS7 ;)</p>
<p><a href="http://blogs.remobjects.com/blogs/alexk/2013/06/17/p6028/nougat-da-for-ios-application-ios7" rel="attachment wp-att-6044"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/06/Nougat-DA-for-iOS-application-iOS7.png" alt="Nougat DA for iOS application iOS7" width="784" height="688" class="aligncenter size-full wp-image-6044" /></a></p>
<p>You can get sources of the sample <a href="https://cloud.remobjects.com/public.php?service=files&#038;t=ac2a724206033ecfdef5be58c8db645f" title="Sample Sources" target="_blank">download here</a> </p>
<p>Thanks for your attention! ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/alexk/2013/06/17/p6028/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8220;After which no more maintenance releases are planned&#8221;. Not.</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/06/07/p6003</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/06/07/p6003#comments</comments>
		<pubDate>Fri, 07 Jun 2013 09:24:12 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[non-tech]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=6003</guid>
		<description><![CDATA[Our good friends and trusted long-time partners at Embarcadero have recently sent out announcements to make sure that all of our shared Prism/Oxygene customers are fully aware of their future path for continuing using the Oxygene language, coverage of Oxygene updates for the full period of Software Assurance this customers have paid for, and are [...]]]></description>
				<content:encoded><![CDATA[<p>Our good friends and trusted long-time partners at Embarcadero have recently sent out announcements to make sure that all of our shared Prism/Oxygene customers are fully aware of their future path for continuing using the Oxygene language, coverage of Oxygene updates for the full period of Software Assurance this customers have paid for, and are assured that their technological investment in Prism/Oxygene are savely going forward.</p>
<p>I thought it might make sense to post this message here, to make sure noone misses it.</p>
<blockquote><p>
  Dear Embarcadero Customer,</p>
<p>  Embarcadero Technologies is pleased to announce the release of Embarcadero Prism XE3.2.</p>
<p>  Embarcadero Prism is no longer an included product within RAD Studio as of the XE4 release. Maintenance updates will continue to be provided through August 2013, after which no more maintenance releases are planned.</p>
<p>  We wish you success in using this latest Embarcadero Technologies product.</p>
<p>  Regards,</p>
<p>  Embarcadero Product Management
</p></blockquote>
<p>We want to thank our friends and partners at Embarcadero once again for getting the word out on this, and for letting our shared customers know <a href="http://www.remobjects.com/oxygene/prism">where to obtain Oxygene going forward, especially beyond August</a>. It goes without saying that we (RemObjects Software) will honor all active SA contracts, on our dime, beyond August. Please contact us if you have any questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/06/07/p6003/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Data Abstract for Cocoa: New methods for adding rows</title>
		<link>http://blogs.remobjects.com/blogs/alexk/2013/06/05/p5699</link>
		<comments>http://blogs.remobjects.com/blogs/alexk/2013/06/05/p5699#comments</comments>
		<pubDate>Wed, 05 Jun 2013 13:34:17 +0000</pubDate>
		<dc:creator>Alexander</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5699</guid>
		<description><![CDATA[In the last release we have introduced two new methods in the DADataTable which allows adding new row with data in one go The first one is public -addNewRowWithDataFromDictionary:inEditMode: It returns new row with values from specified dictionary which contains key-value pairs with field name as the key and value &#8211; as value for given [...]]]></description>
				<content:encoded><![CDATA[<p>In the last release we have introduced two new methods in the <em>DADataTable</em> which allows adding new row with data in one go</p>
<p>The first one is public <strong>-addNewRowWithDataFromDictionary:inEditMode:</strong></p>
<p>It returns new row with values from specified dictionary which contains key-value pairs with field name as the key and value &#8211; as value for given field.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> @<span style="color: #002200;">&#123;</span>
  <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;WorkerBirthDate&quot;</span> <span style="color: #002200;">:</span> date,
  <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;WorkerLastName&quot;</span>  <span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Doe&quot;</span>,
  <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;WorkerPosition&quot;</span>  <span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Boss&quot;</span>,
  <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;WorkerFirstName&quot;</span> <span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;John&quot;</span>
<span style="color: #002200;">&#125;</span>;
&nbsp;
DADataTableRow <span style="color: #002200;">*</span>row <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>table addNewRowWithDataFromDictionary<span style="color: #002200;">:</span>data inEditMode<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>Since it takes a dictionary, and we know to what field given value belongs, then there is no matter in what order you will put the data &#8211; it can differs from order of fields in the table. </p>
<p>This method also perform some basic validation. If you will specify value for field which does not belongs to the table then it throws an exception saying that given field does not exists in the table.</p>
<p>I also need to say few words about adding rows for tables with <em>autoincrement</em> fields. As you might know, when you insert new row to the table with autoincrement key, Data Abstract, at the client side, will provide temporary key value. It is an negative integer value in order not to interfere with existing positive values. </p>
<p><strong>-addNewRowWithDataFromDictionary:inEditMode:</strong> method does not allow you to specify custom value for such autoincrement key. Though it does not firbid to change temporary key value before sending an updateData request.</p>
<p>To avoid ambiguity, if you include value for autoinc field to the dictionary then adding new row will throw an exception saying that you cannot specify custom value for autoincrement field.</p>
<p>So general recomendation here will be &#8211; If your table has an autoincrement key field then just omit passing its value. It will be generated automatically. </p>
<p>And finally you don&#8217;t need to pass values for ALL fields. You can specify only ones you need. It also can be handy for setting defaults.</p>
<p>The second method <strong>-addNewRowWithDataFromArray:inEditMode:</strong> is less safe. It just takes an array of values for new row. Thus, orders of values here plays the very important role. There is no special validation and checkings of the passed arrays. So you must be sure what you are passing there.</p>
<p>For these reasons, we make this method as internal. You can use it when import proper header file like shown in code snippet below.</p>
<p>The benefit in using this method is in its simplicity and conciseness.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;DataAbstract/Internal.h&gt;</span>
...
<span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> @<span style="color: #002200;">&#91;</span>
   <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNull</span> null<span style="color: #002200;">&#93;</span>,
   <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Bond&quot;</span>,
   <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;James&quot;</span>,
   date,
   <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNull</span> null<span style="color: #002200;">&#93;</span>,
   <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Spy&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
DADataTableRow <span style="color: #002200;">*</span>row <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>table addNewRowWithDataFromArray<span style="color: #002200;">:</span>data inEditMode<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>As I&#8217;ve said, order of values here is important so when I want to skip value for certain field then I need to pass a null object there.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/alexk/2013/06/05/p5699/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DA SQL Browser is getting better</title>
		<link>http://blogs.remobjects.com/blogs/antonv/2013/06/05/p5796</link>
		<comments>http://blogs.remobjects.com/blogs/antonv/2013/06/05/p5796#comments</comments>
		<pubDate>Wed, 05 Jun 2013 08:00:15 +0000</pubDate>
		<dc:creator>Anton Vasilenko</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5796</guid>
		<description><![CDATA[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 [...]]]></description>
				<content:encoded><![CDATA[<p>Today I want to tell you about a recent change in the <strong>DA SQL Browser</strong>.<br />
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 <a href="http://wiki.remobjects.com/wiki/DA_SQL">DA SQL</a>.</p>
<p>On start, the DA SQL Browser will prompt you to connect to the server with the following dialog:<br />
<a href="http://blogs.remobjects.com/blogs/antonv/2013/06/05/p5796/da-sql-browser-server-connection" rel="attachment wp-att-5802"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/04/DA-SQL-Browser-Server-Connection.png" alt="DA-SQL-Browser-Server-Connection" width="462" height="388" class="aligncenter size-full wp-image-5802" /></a><br />
You can see that several fields are already filled with default values, which will work with a <a href="http://wiki.remobjects.com/wiki/PCTrade_Sample_Server_-_WPF">DA Sample Server</a>.<br />
Unfortunately, the login dialog of the DA SQL Browser is not that easy to use when connecting to <a href="http://wiki.remobjects.com/wiki/Relativity_Server">Relativity Server</a> (after all, the DA SQL Browser was created much earlier than the Relativity project). You have to provide somewhat cryptic &#8220;additional login parameters&#8221; like <tt>Domain=PCTrade Sample;Schema=PCTrade</tt>.</p>
<p>Considering this, a new option was introduced, so you can see a checkbox <em>Relativity Server</em> on the bottom of the form.<br />
<a href="http://blogs.remobjects.com/blogs/antonv/2013/06/05/p5796/da-sql-browser-server-connection-expanded" rel="attachment wp-att-5803"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/04/DA-SQL-Browser-Server-Connection-expanded.png" alt="DA-SQL-Browser-Server-Connection-expanded" width="462" height="452" class="aligncenter size-full wp-image-5803" /></a><br />
When you click it, it gives another drop-down lists to pick a <em>Domain Name</em> and a <em>Schema Name</em>. Note that you can still fill these names manually, but as long as the dialog&#8217;s <em>Server URL</em> to the Relativity Server is valid, these lists will have all the domains and schemas you need.</p>
<p>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.<br />
<a href="http://blogs.remobjects.com/wp-content/uploads/2013/04/DA-SQL-Browser-with-Relativity-1024x633.png"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/04/DA-SQL-Browser-with-Relativity-1024x633.png" alt="DA-SQL-Browser-with-Relativity" width="591" height="365" class="aligncenter size-large wp-image-5800" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/antonv/2013/06/05/p5796/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oxygene 6 now includes Oxygene for Cocoa</title>
		<link>http://blogs.remobjects.com/blogs/brian-long/2013/05/31/p5988</link>
		<comments>http://blogs.remobjects.com/blogs/brian-long/2013/05/31/p5988#comments</comments>
		<pubDate>Thu, 30 May 2013 23:03:00 +0000</pubDate>
		<dc:creator>Brian Long</dc:creator>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?guid=92caeb3d588799f18527c6eb46774052</guid>
		<description><![CDATA[<p>Ah, it&#8217;s been released&#8230; The May 2013 release of <a href="http://www.remobjects.com/oxygene/" target="_blank">Oxygene</a>, released on 27th May 2013, brings us Oxygene 6.0, and Oxygene 6.0 brings us the official release of <a href="http://www.remobjects.com/oxygene/cocoa.aspx" target="_blank">Oxygene for Cocoa</a>.</p> <p>The Oxygene language now gives ways of coding for all the currently interesting platforms using the three available editions of Oxygene:</p> <ul><li>Oxygene for .NET (<a href="http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822" target="_blank">formerly also known as Delphi Prism</a>) &#8211; targets the .NET platform, allowing you to build Windows applications, Windows phone applications, Silverlight applications and so on, using the relevant .NET frameworks. Also targets the Mono platform, allowing applications to go to the many places where Mono goes, such as Mac and Linux and also Android and iPhone/iPad using <a href="http://xamarin.com/monoforandroid" target="_blank">Xamarin.Android</a> (aka Mono for Android) and <a href="http://xamarin.com/monotouch" target="_blank">Xamarin.iOS</a> (aka MonoTouch) using those frameworks.  </li><li>Oxygene for Java &#8211; targets the Java runtime, allowing you to build Java apps, Java servlets, Java applets and also, perhaps most interestingly, Android apps. Java apps will use your chosen Java frameworks and Android apps use the Android SDK framework.  </li><li>Oxygene for Cocoa &#8211; targets iOS and OS X allowing native ARM applications to be built for iPhone and iPad as well as 64-bit native OS X applications. Applications are built against the native OS X Cocoa and iOS CocoaTouch frameworks.</li></ul><p>Oxygene is hosted in Visual Studio 2012 (support for Visual Studio 2010 has now been phased out in Oxygene 6.0). If you don;t have a copy of Visual Studio 2012 the Oxygene installer can set up the Visual Studio 2012 shell first.</p> <p>For existing users of Oxygene for .NET and/or Oxygene for Java there are some <a href="http://www.remobjects.com/oxygene/whatsnew.aspx" target="_blank">new features</a> added to Oxygene 6.0, including a spate of new conditional defines to help distinguish which compiler built your code or which platform you are targeting:</p> <table border="0" cellspacing="2" cellpadding="2"><tbody><tr><td><u>Oxygene 6.0 edition</u></td> <td><u>Edition define</u></td> <td><u>Platform define</u></td> <td><u>GC/ARC define</u></td></tr><tr><td>.NET</td> <td><code>ECHOES</code></td> <td><code>DOTNET</code></td> <td><code>GC</code></td></tr><tr><td>Java</td> <td><code>COOPER</code></td> <td><code>JAVA</code></td> <td><code>GC</code></td></tr><tr><td>Cocoa</td> <td><code>NOUGAT</code></td> <td><code>COCOA</code></td> <td><code>ARC</code></td></tr></tbody></table><p>However the main thrust of the release is Oxygene for Cocoa, which works in conjunction (if you want) with Apple&#8217;s UI designer to support visual UI design via nib (.xib) files or <a href="http://www.remobjects.com/tv/oxygene.aspx?video=oxygene-24-storyboards" target="_blank">storyboard files</a>. It also understands and fully supports multi-part method names so that it fits in directly with the Objective-C naming system and can represent and refer to any existing methods. It support the iOS Simulator, supports debugging there and on-device and offers all the options needed to sign and provision your apps. It supports <a href="http://wiki.oxygenelanguage.com/en/Automatic_Reference_Counting" target="_blank">ARC</a> (automatic reference counting), understands <a href="http://blogs.remobjects.com/blogs/mh/2013/04/02/p5749" target="_blank">bridging</a> and uses an LLVM back-end to generate good ARM and 64-bit Intel code.</p> <p>It ships with all the standard frameworks imported and has a tool that allows you to <a href="http://wiki.oxygenelanguage.com/en/Importing_an_Objective-C_Library_for_Use_with_Oxygene_for_Cocoa" target="_blank">import any additional libraries</a> you need to work with. Because Oxygene always uses the frameworks that natively exist on the target platforms, there is not an awful lot to learn specific to Oxygene when building Mac or iOS apps. Anything you learn on the Internet about how to build aspects of Mac/iOS apps applies directly &#8211; it&#8217;s just a case of expressing the various local API calls in the Oxygene syntax, which is a very familiar Object Pascal based syntax.</p> <p>During pre-release development Oxygene for Cocoa was called Project &#8220;Nougat&#8221; and I worked with it a lot to keep tabs on how it progressed. I&#8217;ve built a whole bundle of test apps to keep on top of (mostly) iOS application development techniques by simply following various online Objective-C tutorials, and just entering the code in Pascal instead of in Objective-C.</p> <p>I&#8217;m delighted Oxygene for Cocoa is now released as I&#8217;ve been productive with the tool for quite a long time now. I&#8217;ve wanted to make blog posts about how I do thing with it, but given it&#8217;s just a syntax shift there hasn&#8217;t really been much of a need for it. I guess maybe I&#8217;ll do one at some point to show the basics of building up an iOS app in the Visual Studio IDE and getting it launching in iOS Simulator, but after that it&#8217;s just writing code in the same way any other iOS developer does; just in Pascal.</p> <p>On <a href="http://www.richplum.co.uk/meetings/20130617.pdf" target="_blank">June 17th</a> I&#8217;ll be demonstrating the product with a talk at a <a href="http://www.richplum.co.uk/" target="_blank">Developers Group</a> meeting in Maidenhead, UK.</p> <p>You can find more information about Oxygene for Cocoa at these links:</p> <ul><li><a href="http://blogs.remobjects.com/blogs/mh/2013/05/28/p5967" target="_blank">Oxygene 6.0 release announcement post</a>  </li><li><a href="http://www.itwriting.com/blog/7434-build-mac-and-ios-apps-in-visual-studio-oxygene-for-cocoa.html" target="_blank">Tim Anderson&#8217;s post on the release</a>  </li><li><a href="http://www.remobjects.com/oxygene/platforms/ios.aspx" target="_blank">Oxygene iOS platform links</a>  </li><li><a href="http://www.remobjects.com/oxygene/platforms/mac.aspx" target="_blank">Oxygene OS X platform links</a>  </li><li><a href="http://www.remobjects.com/radio.aspx?episode=13-oxygene-nougat-overview" target="_blank">Oxygene &#8220;Nougat&#8221; overview podcast</a>  </li><li><a href="http://wiki.oxygenelanguage.com/en/Bridging_(Cocoa)" target="_blank">Bridging</a>  </li><li><a href="http://blogs.remobjects.com/blogs/mh/2013/03/11/p5663" target="_blank">Creating a Turn-based Game for iOS: Tic-Tac-Toe</a>  </li><li><a href="http://blogs.remobjects.com/blogs/mh/2013/02/22/p5634" target="_blank">Custom iOS controls in Oxygene &#8220;Nougat&#8221;</a>  </li><li><a href="http://wiki.oxygenelanguage.com/en/Using_Instruments_to_Profile_Mac_and_iOS_Apps" target="_blank">Using Instruments Profile Mac and iOS Apps</a>  </li><li><a href="http://wiki.oxygenelanguage.com/en/Getting_Started_with_Oxygene_for_Cocoa" target="_blank">.xib and .storyboard files</a>  </li><li><a href="http://blogs.remobjects.com/blogs/mh/2012/09/12/p4738" target="_blank">What is &#8220;Nougat&#8221;? &#8211; Part 1</a> &#8211; introduction, emphasising and illustrating the native targeting aspects  </li><li><a href="http://blogs.remobjects.com/blogs/mh/2012/09/21/p4801" target="_blank">What is &#8220;Nougat&#8221;? &#8211; Part 2</a> &#8211; target platforms, ARC, boxing and references  </li><li><a href="http://blogs.remobjects.com/blogs/mh/2012/10/02/p4853" target="_blank">What is &#8220;Nougat&#8221;? &#8211; Part 3</a> &#8211; the IDE, building and running an app  </li><li><a href="http://blogs.remobjects.com/blogs/mh/2012/10/19/p4999" target="_blank">What is &#8220;Nougat&#8221;? &#8211; Part 4</a> &#8211; the build &#38; deploy process</li></ul><p>Buying Oxygene is reasonably pocket-friendly. If you&#8217;re <a href="http://www.remobjects.com/shoppingcart?add=1289" target="_blank">new to it then $699</a> gets you all three versions. Otherwise there is a <a href="http://www.remobjects.com/shoppingcart?add=1291" target="_blank">$499 renewal price</a> for existing Oxygene for Java or Prism customers, a <a href="http://www.remobjects.com/shoppingcart?add=1292" target="_blank">$599 cross-grade price</a> for any users of Embarcadero Delphi or of older Embarcadero Prism versions (XE2 and below) and also a <a href="http://www.remobjects.com/shoppingcart?add=1293" target="_blank">$99 academic price</a>.</p> <p>If you want to see how you get on with Oxygene 6.0 without committing you can always <a href="http://www.remobjects.com/oxygene/downloads" target="_blank">pull down a trial version</a> first.</p>]]></description>
				<content:encoded><![CDATA[<p>Ah, it’s been released… The May 2013 release of <a href="http://www.remobjects.com/oxygene/">Oxygene</a>, released on 27th May 2013, brings us Oxygene 6.0, and Oxygene 6.0 brings us the official release of <a href="http://www.remobjects.com/oxygene/cocoa.aspx">Oxygene for Cocoa</a>.</p>
<p>The Oxygene language now gives ways of coding for all the currently interesting platforms using the three available editions of Oxygene:</p>
<ul>
<li>Oxygene for .NET (<a href="http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822">formerly also known as Delphi Prism</a>) – targets the .NET platform, allowing you to build Windows applications, Windows phone applications, Silverlight applications and so on, using the relevant .NET frameworks. Also targets the Mono platform, allowing applications to go to the many places where Mono goes, such as Mac and Linux and also Android and iPhone/iPad using <a href="http://xamarin.com/monoforandroid">Xamarin.Android</a> (aka Mono for Android) and <a href="http://xamarin.com/monotouch">Xamarin.iOS</a> (aka MonoTouch) using those frameworks.
<li>Oxygene for Java – targets the Java runtime, allowing you to build Java apps, Java servlets, Java applets and also, perhaps most interestingly, Android apps. Java apps will use your chosen Java frameworks and Android apps use the Android SDK framework.
<li>Oxygene for Cocoa – targets iOS and OS X allowing native ARM applications to be built for iPhone and iPad as well as 64-bit native OS X applications. Applications are built against the native OS X Cocoa and iOS CocoaTouch frameworks.</li>
</ul>
<p>Oxygene is hosted in Visual Studio 2012 (support for Visual Studio 2010 has now been phased out in Oxygene 6.0). If you don;t have a copy of Visual Studio 2012 the Oxygene installer can set up the Visual Studio 2012 shell first.</p>
<p>For existing users of Oxygene for .NET and/or Oxygene for Java there are some <a href="http://www.remobjects.com/oxygene/whatsnew.aspx">new features</a> added to Oxygene 6.0, including a spate of new conditional defines to help distinguish which compiler built your code or which platform you are targeting:</p>
<table border="0" cellspacing="2" cellpadding="2">
<tbody>
<tr>
<td><u>Oxygene 6.0 edition</u></td>
<td><u>Edition define</u></td>
<td><u>Platform define</u></td>
<td><u>GC/ARC define</u></td>
</tr>
<tr>
<td>.NET</td>
<td><code>ECHOES</code></td>
<td><code>DOTNET</code></td>
<td><code>GC</code></td>
</tr>
<tr>
<td>Java</td>
<td><code>COOPER</code></td>
<td><code>JAVA</code></td>
<td><code>GC</code></td>
</tr>
<tr>
<td>Cocoa</td>
<td><code>NOUGAT</code></td>
<td><code>COCOA</code></td>
<td><code>ARC</code></td>
</tr>
</tbody>
</table>
<p>However the main thrust of the release is Oxygene for Cocoa, which works in conjunction (if you want) with Apple’s UI designer to support visual UI design via nib (.xib) files or <a href="http://www.remobjects.com/tv/oxygene.aspx?video=oxygene-24-storyboards">storyboard files</a>. It also understands and fully supports multi-part method names so that it fits in directly with the Objective-C naming system and can represent and refer to any existing methods. It support the iOS Simulator, supports debugging there and on-device and offers all the options needed to sign and provision your apps. It supports <a href="http://wiki.oxygenelanguage.com/en/Automatic_Reference_Counting">ARC</a> (automatic reference counting), understands <a href="http://blogs.remobjects.com/blogs/mh/2013/04/02/p5749">bridging</a> and uses an LLVM back-end to generate good ARM and 64-bit Intel code.</p>
<p>It ships with all the standard frameworks imported and has a tool that allows you to <a href="http://wiki.oxygenelanguage.com/en/Importing_an_Objective-C_Library_for_Use_with_Oxygene_for_Cocoa">import any additional libraries</a> you need to work with. Because Oxygene always uses the frameworks that natively exist on the target platforms, there is not an awful lot to learn specific to Oxygene when building Mac or iOS apps. Anything you learn on the Internet about how to build aspects of Mac/iOS apps applies directly – it’s just a case of expressing the various local API calls in the Oxygene syntax, which is a very familiar Object Pascal based syntax.</p>
<p>During pre-release development Oxygene for Cocoa was called Project “Nougat” and I worked with it a lot to keep tabs on how it progressed. I’ve built a whole bundle of test apps to keep on top of (mostly) iOS application development techniques by simply following various online Objective-C tutorials, and just entering the code in Pascal instead of in Objective-C.</p>
<p>I’m delighted Oxygene for Cocoa is now released as I’ve been productive with the tool for quite a long time now. I’ve wanted to make blog posts about how I do thing with it, but given it’s just a syntax shift there hasn’t really been much of a need for it. I guess maybe I’ll do one at some point to show the basics of building up an iOS app in the Visual Studio IDE and getting it launching in iOS Simulator, but after that it’s just writing code in the same way any other iOS developer does; just in Pascal.</p>
<p>On <a href="http://www.richplum.co.uk/meetings/20130617.pdf">June 17th</a> I’ll be demonstrating the product with a talk at a <a href="http://www.richplum.co.uk/">Developers Group</a> meeting in Maidenhead, UK.</p>
<p>You can find more information about Oxygene for Cocoa at these links:</p>
<ul>
<li><a href="http://blogs.remobjects.com/blogs/mh/2013/05/28/p5967">Oxygene 6.0 release announcement post</a>
<li><a href="http://www.itwriting.com/blog/7434-build-mac-and-ios-apps-in-visual-studio-oxygene-for-cocoa.html">Tim Anderson’s post on the release</a>
<li><a href="http://www.remobjects.com/oxygene/platforms/ios.aspx">Oxygene iOS platform links</a>
<li><a href="http://www.remobjects.com/oxygene/platforms/mac.aspx">Oxygene OS X platform links</a>
<li><a href="http://www.remobjects.com/radio.aspx?episode=13-oxygene-nougat-overview">Oxygene “Nougat” overview podcast</a>
<li><a href="http://wiki.oxygenelanguage.com/en/Bridging_(Cocoa)">Bridging</a>
<li><a href="http://blogs.remobjects.com/blogs/mh/2013/03/11/p5663">Creating a Turn-based Game for iOS: Tic-Tac-Toe</a>
<li><a href="http://blogs.remobjects.com/blogs/mh/2013/02/22/p5634">Custom iOS controls in Oxygene “Nougat”</a>
<li><a href="http://wiki.oxygenelanguage.com/en/Using_Instruments_to_Profile_Mac_and_iOS_Apps">Using Instruments Profile Mac and iOS Apps</a>
<li><a href="http://wiki.oxygenelanguage.com/en/Getting_Started_with_Oxygene_for_Cocoa">.xib and .storyboard files</a>
<li><a href="http://blogs.remobjects.com/blogs/mh/2012/09/12/p4738">What is “Nougat”? – Part 1</a> – introduction, emphasising and illustrating the native targeting aspects
<li><a href="http://blogs.remobjects.com/blogs/mh/2012/09/21/p4801">What is “Nougat”? – Part 2</a> – target platforms, ARC, boxing and references
<li><a href="http://blogs.remobjects.com/blogs/mh/2012/10/02/p4853">What is “Nougat”? – Part 3</a> – the IDE, building and running an app
<li><a href="http://blogs.remobjects.com/blogs/mh/2012/10/19/p4999">What is “Nougat”? – Part 4</a> – the build &amp; deploy process</li>
</ul>
<p>Buying Oxygene is reasonably pocket-friendly. If you’re <a href="http://www.remobjects.com/shoppingcart?add=1289">new to it then $699</a> gets you all three versions. Otherwise there is a <a href="http://www.remobjects.com/shoppingcart?add=1291">$499 renewal price</a> for existing Oxygene for Java or Prism customers, a <a href="http://www.remobjects.com/shoppingcart?add=1292">$599 cross-grade price</a> for any users of Embarcadero Delphi or of older Embarcadero Prism versions (XE2 and below) and also a <a href="http://www.remobjects.com/shoppingcart?add=1293">$99 academic price</a>.</p>
<p>If you want to see how you get on with Oxygene 6.0 without committing you can always <a href="http://www.remobjects.com/oxygene/downloads">pull down a trial version</a> first.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.blong.com/feeds/4638646515318664944/comments/default</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Announcing Oxygene 6 and the new Oxygene for Cocoa</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/05/28/p5967</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/05/28/p5967#comments</comments>
		<pubDate>Tue, 28 May 2013 16:21:06 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5967</guid>
		<description><![CDATA[Hello everyone. We are more than pleased to announce the release of Oxygene 6, the next major milestone of our Oxygene language. This new version includes a significant update to the existing &#8220;Oxygene for .NET&#8221; and &#8220;Oxygene for Java&#8221; editions, but &#8211; most excitingly &#8211; it also marks the first release version of our all-new [...]]]></description>
				<content:encoded><![CDATA[<p><center><img src="http://www.remobjects.com/images/emails/Oxygene-May13.png" /></center></p>
<p>Hello everyone.</p>
<p>We are more than pleased to announce the release of Oxygene 6, the next major milestone of our <a href="http://www.remobjects.com/oxygene">Oxygene</a> language. This new version includes a significant update to the existing &ldquo;Oxygene for .NET&rdquo; and &ldquo;Oxygene for Java&rdquo; editions, but &ndash; most excitingly &ndash; it also marks the first release version of our all-new <strong>Oxygene for Cocoa</strong>.</p>
<p><a href="http://www.remobjects.com/oxygene/cocoa">Oxygene for Cocoa</a> is a brand-new edition of our Oxygene language, and it targets native Mac and iOS development with the Cocoa frameworks, using the same great language you already know and love from .NET and Java. We are <em>very</em> excited about Oxygene for Cocoa, and we think it will be a game-changer for how you create apps for Mac and iOS.</p>
<p>Oxygene for Cocoa is a very unique product, in that it is the only language (next to Apple&#8217;s own Objective-C) to truly natively target the Cocoa platform and the Objective-C runtime. It gives you access to <em>all</em> the great frameworks and libraries provided by the platform, lets you use all the native UI controls, and generates executables that are lean, mean and blazingly fast &ndash; and compiled directly for Intel x64 (Mac) or ARMv7 and ARMv7s (iOS).</p>
<h2>Get Oxygene now</h2>
<p>Support for all three platforms is available in the new Oxygene 6 package, which is a free update for all active subscribers who bought Oxygene form us since last August. It is available for new users <a href="http://www.remobjects.com/shoppingcart?add=1289">at only $699</a> (again including all three platforms!), and individual platform support is also included in our Suite Subscriptions for .NET, Cocoa and Java, respectively.</p>
<p>Special renewal pricing is available for existing Oxygene for Java or Prism customers <a href="http://www.remobjects.com/shoppingcart?add=1291">$499</a>, as well as a special <a href="http://www.remobjects.com/shoppingcart?add=1292">$599</a> cross-grade offer for any users of Embarcadero Delphi or of older Embarcadero Prism versions (XE2 and below).</p>
<p>We&#8217;re also for the first time ever introducing a new academic pricing for students, teachers and non-profit researchers, <a href="http://www.remobjects.com/shoppingcart?add=1293">at an amazingly low $99</a>.</p>
<p>And of course, as always, theres a free fully-functional <a href="http://www.remobjects.com/oxygene/downloads">30-day trial version</a> available, as well.</p>
<h2>This is only the beginning</h2>
<p>But we&#8217;re just getting started with this release and have many further exciting things planned for this year and beyond, including two minor updates for June and July, a significant &ldquo;6.1&rdquo; release in Fall, as well as several related products and technologies that will extend the Oxygene ecosystem that we&#8217;re not <em>quite</em> ready to talk about yet.</p>
<p>In the meantime, we hope you will enjoy the first release of Oxygene 6.0 and Oxygene for Cocoa &ndash; and we&#8217;re looking forward to hearing what Apps you will be building with it!</p>
<p>You can learn more about Oxygene at <a href="http://www.remobjects.com/oxygene">remobjects.com/oxygene</a> and <a href="http://wiki.oxygenelanguage.com">wiki.oxygenelanguage.com</a>.</p>
<p>&nbsp;</p>
<p>Yours,</p>
<p>marc hoffman<br />Chief Architect,<br />RemObjects Software</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/05/28/p5967/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RemObjects SDK Beginners Guide</title>
		<link>http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853</link>
		<comments>http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853#comments</comments>
		<pubDate>Wed, 22 May 2013 14:17:32 +0000</pubDate>
		<dc:creator>Anton Kasyanov</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ROFX]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5853</guid>
		<description><![CDATA[Intro RemObjects SDK is an awesome framework. Not only because its development feeds me and my 10 cats ;) but also because it allows to efficiently create applications on literally a dozen different platforms (to name them: Win32 (a.k.a. Delphi apps), desktop .NET framework, Windows Phone, Silverlight, Mono, Android, Android via MonoAndroid, iOS, iOS via MonoTouch, native [...]]]></description>
				<content:encoded><![CDATA[<h2>Intro</h2>
<p>RemObjects SDK is an awesome framework. Not only because its development feeds me and my 10 cats ;) but also because it allows to efficiently create applications on literally a dozen different platforms (to name them: Win32 (a.k.a. Delphi apps), desktop .NET framework, Windows Phone, Silverlight, Mono, Android, Android via MonoAndroid, iOS, iOS via MonoTouch, native MacOS X apps, Java and JavaScript). Unfortunately, it takes a bit of time to get started with developing, you can&#8217;t just jump right in. I myself (and most of the software developers I know) usually want to try their new, just downloaded toy without reading a ton of documentation pages.</p>
<p>So this article will try to be a kind of &#8220;crash course&#8221;. It won&#8217;t go very deep (there are <a href="http://wiki.remobjects.com/" title="Wiki" target="_blank">Wiki</a> articles on just about anything, if you want to delve in deeper, and our support team will help you with any questions), it will just try to give you some &#8216;feeling&#8217; for the tech, a foothold to conquer the new framework.</p>
<p>This article covers the .NET version of the RemObjects SDK, however, the main approach will remain the same for all platforms (.NET, Xcode, Delphi, Java, JavaScript), so you won&#8217;t waste your time with this article, even if you don&#8217;t use .NET in your development work.</p>
<p>My colleagues will provide similar articles devoted to the other supported platforms later this month.</p>
<p>Note: This article covers the &#8216;Client Calls The Server&#8217; scenario and doesn&#8217;t touch the &#8216;Server Pings The Client&#8217; one. At this moment it is enough to know that the latter scenario is possible as well and its implementation won&#8217;t affect the former one.</p>
<h2>The Core</h2>
<p>The very heart of the RemObjects SDK is based on <strong>Channels</strong>, <strong>Messages</strong>, <strong>Envelopes</strong> and <strong>Services</strong>. Two more components used under the hood are <strong>Interfaces</strong> and <strong>Invokers</strong>. Don&#8217;t be afraid of these words, things are actually simpler than they look.</p>
<p>Let&#8217;s take a look at the &#8216;Client calls the server method&#8217; scenario:</p>
<pre>
var methodCallResult = sampleService.DoSomething();
</pre>
<p>Looks simple, doesn&#8217;t it?</p>
<p>Here&#8217;s what happens from the RemObjects SDK&#8217;s point of view:</p>
<p>The client code calls the Foo method of some object serverService. Here, <strong>sampleService</strong> is an instance of the auto-generated proxy class, so calling the <strong>sampleService.DoSomething()</strong> method actually means the following:</p>
<p>1. Sending out a request<br />
The <strong>Interface</strong> class serializes the request to the server using the configured <strong>Message</strong>. The <strong>Message</strong> is then wrapped by the attached <strong>Envelopes</strong>, if any are set up (f.e. data is encrypted somehow). Then the resulting data package is sent over the wire by the <strong>Client Channel</strong>.</p>
<p>2. Processing the request on the server side<br />
The <strong>Server Channel</strong> retrieves the data package and pushes it to the <strong>Message</strong> component. <strong>Message</strong> unwraps it using the attached <strong>Envelopes</strong>, if needed. The resulting data package is provided to the <strong>Invoker</strong>, which reads the requested service, method names and method parameters from it.</p>
<p>Then the <strong>Service</strong> method is invoked, which does the actual job.</p>
<p>After the service method has finished, its result (or any exceptions occurred) are serialized, wrapped, and sent back over the wire using the <strong>Server Channel</strong> (yes, the processing pipeline is similar to step 1).</p>
<p>3. Retrieving the response<br />
The <strong>Client Channel</strong> retrieves the data package, unwraps it and provides the serialized data package to the <strong>Interface</strong>&#8216;s method that initiated the remote service call. This method then deserializes the provided data package and provides the method result back to the user code.</p>
<p><a href="http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/remobjects-sdk-beginners-guide-overview" rel="attachment wp-att-5925"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/05/RemObjects-SDK-Beginners-Guide-Overview.png" alt="RemObjects SDK Overview" width="339" height="584" class="aligncenter size-full wp-image-5925" /></a></p>
<p>The magic is that the entire process is transparent for the user code on both ends of the wire and doesn&#8217;t require much attention from the developer. While the service method call pipeline might seem complicated (or even over-complicated), its performance overhead is negligible (especially for the binary serialization-based <strong>Message</strong>), making the actual network speed the main issue to care about, not the inner RemObjects SDK processes.</p>
<h2>Sample Server</h2>
<p>Let&#8217;s create a sample server and client app in a step-by-step guide and see how the <strong>Channels</strong>, <strong>Messages</strong>, <strong>Envelopes</strong>, <strong>Interfaces</strong>, <strong>Invokers</strong> and <strong>Services</strong> entities are implemented in a real RemObjects SDK-based application.</p>
<h3>Prerequisites</h3>
<p>For this tutorial you&#8217;ll need Visual Studio and either the RemObjects SDK for .NET or the Data Abstract for .NET frameworks installed. Also, a minimal knowledge of C# is required, but the same concepts would apply to Visual Basic for .NET, Oxygene or any other .NET language.</p>
<h3>Server Application</h3>
<p>As mentioned above, the server application should contain the <strong>Server Channel</strong>, <strong>Message</strong>, <strong>Envelope</strong> (if needed) and <strong>Invoker</strong>, as well as the <strong>Service</strong> itself.</p>
<p>1. Create a new Class Library project named BusinessLogic and add a single class to it:</p>
<pre>
using System;

namespace BusinessLogic
{
    public class StringProcessor
    {
        public Int32 Process (String value)
        {
            if (String.IsNullOrEmpty(value))
                return -1;

            return (value + @"Secret Salt").GetHashCode();
        }
    }
}
</pre>
<p>This project imitates an already existing implemetation of a real-world business logic method that should be exposed to remote client applications. While it is not necessary to put the business logic into a separate project, it was done here to emphasize that the business logic layer is fully separated from the to-be-implemented communication layer.</p>
<p>2. Add a new Windows Forms project to the solution and name it <strong>SampleServer</strong>. Of course, a real-world server application should be running as a Windows Service (and RemObjects SDK provides the needed application template), but for this &#8220;crash course&#8221; it will be easier to use the simple Windows Forms project.</p>
<p>3. Add the following references to the SampleServer project, as they provide the needed classes:</p>
<ul>
<li>RemObjects.InternetPack.dll</li>
<li>RemObjects.SDK.dll</li>
<li>RemObjects.SDK.Server.dll</li>
<li>RemObjects.SDK.ZLib.dll</li>
</ul>
<p>Also add a reference to the previously created BusinessLogic project, as we will expose its methods in the server.</p>
<p>4. Now we need to define the <strong>Server Surface Area</strong>, i.e. the service name, its methods, their parameters and return values, etc. This step is needed to allow the RemObjects SDK to generate strongly-typed <strong>Interface</strong> and <strong>Invoker</strong> classes.</p>
<p>Add a new &#8216;RemObjects SDK Service Definition&#8217; item to the project.</p>
<p><a href="http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/remobjects-sdk-beginners-guide-new-item" rel="attachment wp-att-5911"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/05/RemObjects-SDK-Beginners-Guide-New-Item.png" alt="Adding New Item" width="796" height="448" class="aligncenter size-full wp-image-5911" /></a></p>
<p>A new file named <strong>NewLibrary1.RODL</strong> will be added to the project and the Service Builder app will be started automatically. The RODL is an XML file containing the service definition written in the &#8216;RemObjects Definition Language&#8217; (or RODL), and the <strong>Service Builder</strong> provides the GUI to edit .RODL files without diving into the definition language syntax. Please note that the RemObjects SDK exposes the object model that allows to load, parse and generate .RODL files (and even to generate code based on these files), but this topic is outside the scope of this article.</p>
<p><a href="http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/remobjects-sdk-beginners-guide-service-builder" rel="attachment wp-att-5912"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/05/RemObjects-SDK-Beginners-Guide-Service-Builder.png" alt="Service Builder" width="746" height="548" class="aligncenter size-full wp-image-5912" /></a></p>
<p>As you can see, the file is almost empty. Select the single topic in the tree on the left side of the app&#8217;s window. The edit boxes that will appear will allow you to change the library name, set its namespace or even write its definition. Set the <strong>Library</strong> name to <strong>BusinessLogicLibrary</strong>.</p>
<p>A <strong>Library</strong> contains all the entities in the given RODL file. Consider it as a root of a service definition tree.</p>
<p>The next step is to define the <strong>Service</strong>. Press the &#8216;Service&#8217; button (or right-click the Library name in the tree and issue the &#8216;Service&#8217; context menu command) and rename the just added Service to <strong>BusinessLogicService</strong>. </p>
<p>Now we can define this service&#8217;s methods. Press the &#8216;Add Operation&#8217; button (the one with the green &#8220;+&#8221; glyph). A new method named &#8216;NewMethod&#8217; will be added. Double-click its definition and change the method&#8217;s name to <strong>Process</strong>.</p>
<p>The last step is to define this method&#8217;s parameters and set its return type. Press the &#8216;Add Parameter&#8217; button and change the parameter&#8217;s name to &#8216;value&#8217;. Change the parameter&#8217;s type to <strong>Utf8String</strong> (the &#8216;Data Type&#8217; editor allows to select a type name from a combo box, so there is no need to enter it manually).</p>
<p>Set the Result type to <strong>Integer</strong> (the type name can be selected from the combo box as well).</p>
<p>If everything was done right, the Service Builder window should now look like this:</p>
<p><a href="http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/remobjects-sdk-beginners-guide-service-definition" rel="attachment wp-att-5913"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/05/RemObjects-SDK-Beginners-Guide-Service-Definition.png" alt="Service Definition" width="760" height="608" class="aligncenter size-full wp-image-5913" /></a></p>
<p>Close the Service Builder.</p>
<p>Set the &#8216;Build Action&#8217; of the just added RODL file to &#8216;Embedded Resource&#8217;, so it will be embedded into the compiled application. You will find out why this is needed below.</p>
<p>5. As you can see, once you closed the Service Builder, three new code file were added to your project: <strong>BusinessLogicLibrary_Intf.cs</strong>, <strong>BusinessLogicLibrary_Invk.cs</strong> and <strong>BusinessLogicService_Impl.cs</strong>.<br />
<strong>BusinessLogicLibrary_Intf.cs</strong> contains the <strong>Interface</strong> classes, <strong>BusinessLogicLibrary_Invk.cs</strong> contains the set of <strong>Invoker</strong> classes and <strong>BusinessLogicService_Impl.cs</strong> is a blank <strong>Service</strong> implementation class.<br />
There is no need (and it is NOT recommended) to edit the code in the first two files.</p>
<p>In case you change the RODL file (for example add one more method to the service definition), the <strong>*_Intf</strong> and <strong>*_Invk</strong> files will be regenerated automatically to reflect the RODL changes. At the same time the _Impl file will stay untouched to prevent any code loss. Since the service implementation class contained in the <strong>_Impl</strong> file implements the service interface contained in the <strong>_Intf</strong> file, the service project won&#8217;t be able to build until the Service implementation class will match the Service definition.</p>
<p>For example: If you add a method to a service definition, the interface representing this service in the <strong>_Intf</strong> file will contain the new method definition as well. And because the <strong>Service</strong> implementation class has to implement this interface, the developer will have to add the corresponding method implementation to the service definition class.</p>
<p>6. Open the <strong>Service Implementation</strong> file (i.e. <strong>BusinessLogicService_Impl.cs</strong>) and find the <strong>Process</strong> method implementation. It is empty, so change it to</p>
<pre>
public virtual int Process(string value)
{
    return (new BusinessLogic.StringProcessor()).Process(value);
}
</pre>
<p>At this time, we have defined and implemented a <strong>Service</strong> (and it probably took more time for you to read the text above than to actually execute the steps in Visual Studio). Now we need to make the service available remotely.</p>
<p>7. Below, we will manually implement the network connectivity layer using the RemObjects SDK components. This is done to demonstrate the ins and outs of the framework as the RemObjects SDK provides the application templates and (starting from the May 2013 release) the pre-implemented NetworkServer class that allows to implement the connectivity layer in literally 3 lines of code.</p>
<p>Open the main form in designer mode (remember that our server app is intentionally primitive, so no properly layered architecture or &#8216;Run As Windows Service&#8217; support here):<br />
* Add the <strong>IpHttpServerChannel</strong> and <strong>BinMessage</strong> components to the main form (note that a <strong>licenses.licx</strong> file was automatically added to the server app project. Please do not delete this file).<br />
* Open the properties of the <strong>IpHttpServerChannel</strong> component and open the custom editor for the <strong>Dispatchers</strong> property.<br />
* Press the &#8216;Add&#8217; button and select the previously added <strong>BinMessage</strong> instance as a value for the Message property.</p>
<p><a href="http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/remobjects-sdk-beginners-guide-channel-properties" rel="attachment wp-att-5909"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/05/RemObjects-SDK-Beginners-Guide-Channel-Properties.png" alt="Channel Properties" width="553" height="373" class="aligncenter size-full wp-image-5909" /></a></p>
<p>* Press <strong>OK</strong> to close the dialog and save the property&#8217;s value.</p>
<p>That&#8217;s it. The server message processing pipeline (i.e. the <strong>Server Channel</strong> and <strong>Server Message</strong>) is set up.</p>
<p>8. Open the code-behind file of the main form and add this code line to the very end of the main form class constructor:</p>
<pre>
this.ipHttpServerChannel1.Open();
</pre>
<p>This code line will &#8216;open&#8217; the server channel so it will start to accept the incoming connections.</p>
<p>Now you can start the server app. Open a web browser and go to the page <a href="http://localhost:8099/rodl" title="http://localhost:8099/rodl" target="_blank">http://localhost:8099/rodl</a>. The server app will show the contents of the embedded RODL file at this address. Note that you can always set the the &#8217;Embedded Resource&#8217; property to None for the RODL file and the server will not advertise its methods.</p>
<h3>Client Application</h3>
<p>Even the most advanced server application is useless if there is no client application for it. So&#8230; let&#8217;s create one!</p>
<p>If you remember, a client application needs the following components implemented: <strong>Channel</strong>, <strong>Message</strong>, (possibly) <strong>Envelope</strong> and <strong>Interface</strong>. This may look scary again, but it will be much easier than it sounds.</p>
<p>1. Create a new <strong>Console Application</strong> (for simplicity reasons).</p>
<p>2. Add references to the assemblies</p>
<ul>
<li>RemObjects.InternetPack.dll</li>
<li>RemObjects.SDK.dll</li>
<li>RemObjects.SDK.ZLib.dll</li>
</ul>
<p>These assemblies provide the client connectivity classes (as you can see, there is no need to reference the <strong>RemObjects.SDK.Server.dll</strong> assembly).</p>
<p>3. Now issue the &#8216;Add&#8217; -> &#8216;Existing Item&#8217; command (available via the context menu for the client application project entry in the Solution Explorer).</p>
<p>4. Select the <strong>BusinessLogicLibrary_Intf.cs</strong> file (it can be found in the server&#8217;s project folder) and add it as a link.</p>
<p>Adding the <strong>_Intf</strong> file as a link has a little but important advantage over simply adding an existing file to the client app project: when the server RODL is changed, the <strong>_Intf</strong> file is automatically regenerated. If this file is added as a link, there will be no need to update the <strong>_Intf</strong> file copy contained in the client app project.</p>
<p>This step adds the <strong>Interface</strong> part of the client app.</p>
<p>4. Add the following code to the Program.cs:</p>
<pre>
using System;

namespace SampleConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Enter string: ");
            String value = Console.ReadLine();
            Console.WriteLine();
            Console.WriteLine("Processing...");

            // Communicating with the server
            SampleServer.IBusinessLogicService service = new SampleServer.BusinessLogicService_Proxy(@"http://localhost:8099/bin");

            Int32 hash = service.Process(value);

            Console.WriteLine();
            Console.WriteLine("String entered: {0}", value);
            Console.WriteLine("String hash: {0}", hash);
            Console.WriteLine("Press ENTER to continue...");
            Console.ReadLine();
        }
    }
}
</pre>
<p>The <strong>Console.WriteLine</strong> and <strong>Console.ReadLine</strong> calls here are pretty usual for any console application. Let&#8217;s take a closer look at these code lines:</p>
<pre>
// Communicating with the server
SampleServer.IBusinessLogicService service = new SampleServer.BusinessLogicService_Proxy(@"http://localhost:8099/bin");
Int32 hash = service.Process(value);
</pre>
<p>Here, a proxy for a server app service is created and then a service method is called (the <strong>Channel</strong> and <strong>Message</strong> components are automatically created behind the scenes to make this possible).</p>
<p>The <strong>IBusinessLogicService</strong> interface lists all methods exposed by the remote service, while the <strong>CoBusinessLogicService.Create</strong> static method creates a proxy class that implements this interface. This makes it possible to perform calls to a remote server transparently for the client app&#8217;s code.</p>
<p>5. There are probably some explanations needed regarding where the <strong>&#8220;http://localhost:8099/bin&#8221;</strong> URL came from. Let&#8217;s take a closer look on each part of the URL:</p>
<ul>
<li><strong>http</strong> – Protocol used by the server channel. In this sample, we use a simple HTTP channel. The RemObjects SDK supports several other communication protocols as well (f.e. TCP-based ones).</li>
<li><strong>localhost</strong> – Name or IP address of the server&#8217;s host.</li>
<li><strong>8099</strong> – Port the Server Channel is listening to. 8099 is the default port for the IpHttpServerChannel used in our server application.</li>
<li><strong>bin</strong> – So-called dispatcher name. This is the name of the Message on the server side that processes the incoming data package. <strong>bin</strong> is the default name for the <strong>BinMessage</strong>.</li>
</ul>
<p>6. Build and start both the server and client applications. Enter any string into the client application window and see the result returned by the server app:</p>
<p><a href="http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/remobjects-sdk-beginners-guide-client-application" rel="attachment wp-att-5910"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/05/RemObjects-SDK-Beginners-Guide-Client-Application.png" alt="Client Application" width="673" height="341" class="aligncenter size-full wp-image-5910" /></a></p>
<h2>Conclusion</h2>
<p>At this point you should have a basic understanding of how the RemObjecs SDK-based communications can be implemented. As an exercise, try to add one more method to the Service and call it.</p>
<p>This article doesn&#8217;t cover many (or even most) of the RemObjecs SDK features. <strong>Server Events</strong>, <strong>Envelopes</strong>, client authentication processing and SSL support were not covered for simplicity reasons. Search our Wiki for the questions you are interested in. If for some reason you can&#8217;t find the info you need, don&#8217;t hesitate to call on our support via <a href="http://connect.remobjects.com/" target="_blank">RemObjects Connect</a> or email to <a href="mailto:support@remobjects.com">support@remobjects.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/antonk/2013/05/22/p5853/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8230;then i might as well learn Java?</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/04/23/p5863</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/04/23/p5863#comments</comments>
		<pubDate>Tue, 23 Apr 2013 16:00:22 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5863</guid>
		<description><![CDATA[One of the most frequent comments i hear when people dismiss or decide against considering Oxygene as their development tool of choice goes along the lines of the title of this blog post: &#8220;With Oxygene i need to learn all the new platform APIs. If that&#8217;s the case, i might as well learn C# [or [...]]]></description>
				<content:encoded><![CDATA[<p>One of the most frequent comments i hear when people dismiss or decide against considering Oxygene as their development tool of choice goes along the lines of the title of this blog post:</p>
<blockquote><p>
  &#8220;With Oxygene i need to learn all the new platform APIs. If that&#8217;s the case, i might as well learn C# [or Java or Objective-C].&#8221;
</p></blockquote>
<p>That&#8217;s certainly true. When moving to and learning a new platform, there&#8217;s a vast number of things to learn — new classes, new APIs, new concepts, new ways of doing things. Learning a new language, especially if it&#8217;s one from the same broader family of languages you already know (i.e. Object Oriented languages) is only a small and insignificant part of that.</p>
<p><strong>But</strong>, i think it is missing the point of Oxygene, to think its whole reason d&#8217;être is to save you from learning a new language. Quite the contrary.</p>
<p>Oxygene is based on Object Pascal, and is, at its root, very close to the &#8220;Delphi&#8221; language (which basically represents the state-of-the-art of Object Pascal ca. 2003). The main reason for that is not that Delphi developers (which the creators of Oxygene were too, at the time) do not have to learn a new language. The reason for that is that Pascal — as much as it has gone out of fashion over the past 20 or so years — is a freaking amazing base point for a programming language. It&#8217;s clean, well structured, easy to learn, and — very importantly — easy to read.</p>
<p>Many developers underestimate this, but they spend <em>a lot</em> more time re-eading their (and other&#8217;s) code than they originally spent writing it — so having a language that makes code easy to parse and understand by the human brain is a very important and undervalued feature of a language. One that Oxygene shines at like no other.</p>
<p>So that&#8217;s the why Oxygene is what it is, but is that enough reason to choose it over C#, Java or even Objective-C? No, of course not.</p>
<p>The biggest selling point for Oxygene in my opinion is <em>not</em> that it&#8217;s Pascal based, and is <em>not</em> that is allows you to natively compile for today&#8217;s three major platforms (.NET, Java and Cocoa) with the same code base, and it most certainly <em>not</em> that it <strong>saves</strong> you from doing anything (be it learning a new language, or be it spending more money on a more expensive development tool).</p>
<p>The biggest selling point of Oxygene is — quite frankly — that it is an amazing modern language, with features that developers using the other mainstream languages don&#8217;t even begin to dream about.</p>
<p>Going into details on all the features that make Oxygene unique and powerful, the features that will change your <em>life</em> as a developer, would require several posts on its own. But the scope ranges from Class Contracts to language-integrated parallelism, from nullable types to the amazing Future types, from small but powerful things like the colon operator and double boolean comparisons to &#8220;for&#8221; loop expressions (not to be confused with regular &#8220;for&#8221; loops), and from duck typing to language-native tuples.</p>
<p>The list could keep going on.</p>
<p>So when you&#8217;re looking at Oxygene (and i know you are), don&#8217;t just look at it from the perspective that it will let you keep coding in Pascal without having to learn a new language. Sure, that&#8217;s a big factor too. If you&#8217;re a Delphi developer, you probably love Pascal (like we do), and have been using it for the past 10, 20 or even more years. And being Pascal certainly is <em>one</em> thing that makes Oxygene attractive to you.</p>
<p>But don&#8217;t stop there; you&#8217;re doing Oxygene <em>and</em> yourself an injustice, if you look at that as the main benefit.</p>
<p>Instead, think of using Oxygene as switching to the most powerful and modern object oriented language out there, today. That it&#8217;s Pascal-based is just the icing on an already very delicious cake.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/04/23/p5863/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Prism XE4, Where Art Thou?</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822#comments</comments>
		<pubDate>Wed, 17 Apr 2013 16:04:02 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5822</guid>
		<description><![CDATA[Update: (May 26, 2013) We have an official FAQ for the migration of Prism licenses to Oxygene available now at remobjects.com/oxygene/prism. 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 [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Update</strong>: (May 26, 2013) We have an official FAQ for the migration of Prism licenses to Oxygene available now at <a href="http://www.remobjects.com/oxygene/prism">remobjects.com/oxygene/prism</a>.</p>
<p>Ok, so the <a href="http://www.andreanolanusse.com/en/delphi-xe4-official-announcement-coming/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=delphi-xe4-official-announcement-coming">cat is out of the bag</a>, 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 &#8220;XE4&#8243; branded edition of Prism.</p>
<p>But worry not. As you all know, Prism has been nothing more than a re-branded version of our <a href="http://remobjects.com/oxygene">Oxygene</a> for .NET product &mdash; and Oxygene will keep going on, stronger than ever.</p>
<p>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.</p>
<p>So &#8220;Embarcadero Prism&#8221; 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.</p>
<h2>What exactly does all of this mean?</h2>
<p>We believe that in the end, this change will be a net positive for Oxygene.</p>
<p>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.</p>
<p>Over the years, it turned out that this was not happening, and as Embarcadero was shifting their focus to &#8220;<nobr>(CPU-)native</nobr>, native über alles&#8221; and onto FireMonkey, Prism (and with it Oxygene, as i&#8217;m going to start referring to it from now on exclusively) became the odd man out &mdash; 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.</p>
<p>This became clearer as Oxygene evolved.</p>
<p>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).</p>
<p>At the same time, Embarcadero became less and less interested in actually <em>marketing</em> and promoting the product, and it was being relegated to a &#8220;filler&#8221; to pad up RAD Studio as a worthwhile product suite.</p>
<p>Things got even more complicated when we started working on &#8220;Nougat&#8221;, 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 &mdash; understandably &mdash; 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).</p>
<p>To wrap things up short and sweet, as of right now, Oxygene is finally standing on its own two feet again.</p>
<p>During the five years of partnership, RemObjects Software has always been the sole technical contributor to the core Oxygene product, and having Oxygene &#8220;back to ourselves&#8221; 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 <em>we</em> have for it. And trust me, we have some amazing things planned for 2013 and 2014, with &#8220;Nougat&#8221;, our Mac and iOS support, only being the tip of the iceberg.</p>
<h2>What does this mean for existing customers?</h2>
<p>Worry not. We have every eventuality covered.</p>
<p>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&#8217;re already set.</p>
<p>If you&#8217;re an Oxygene user from the Embarcadero side of the fence, now more than ever, make sure you <strong><a href="http://remobjects.com/oxygene/registerserial">register your XE2.x or X3.x serial number with us</a></strong>. This way, we know about you and can take care of you moving forward.</p>
<p>Once you have registered your serial, you can take advantage of our <a href="http://www.remobjects.com/shoppingcart?add=1291">special renewal price</a> for Prism customers and renew to a full Oxygene package licensed directly from RemObjects Software, for only <a href="http://www.remobjects.com/shoppingcart?add=1291">$349</a>. 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!</p>
<p>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.</p>
<p>Once your current SA expires, renewing it will not include renewed access to Oxygene, but you can use the <a href="http://www.remobjects.com/shoppingcart?add=1291">link above</a> at any time to renew to the full Oxygene package from us. (Note that the current renewal price of <a href="http://www.remobjects.com/shoppingcart?add=1291">$349</a> is a special offer and will increase slightly once &#8220;Nougat&#8221; ships next month.)</p>
<p>It&#8217;s probably unlikely that you&#8217;re buying RAD Studio XE4 &#8220;fresh&#8221; without already being an existing RAD Studio user, but if you do, i&#8217;m afraid you will not receive &#8220;Prism XE4&#8243; as part of it. You (and every other Delphi user) can use our <a href="http://www.remobjects.com/shoppingcart?add=1292">special <em>cross-grade</em> offer</a> to purchase a full Oxygene package from us, at <a href="http://www.remobjects.com/shoppingcart?add=1292">$399</a> (this is also a special offer, and the price will increase slightly once we ship 6.0 next month).</p>
<h2>In Summary</h2>
<p>As the old saying goes, <strong>The King is dead, long live the King!</strong> Embarcadero Prism is no more, starting next week, but Oxygene is going stronger than ever.</p>
<p>We, and i personally, are <em>incredibly</em> excited about Oxygene, and about the things we have planned thru-out the rest of the year and beyond. We can&#8217;t wait to walk down the road ahead with you.</p>
<p>yours,<br />
marc hoffman<br />
Chief Architect &amp; Oxygene Team Lead<br />
RemObjects Software</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/04/17/p5822/feed</wfw:commentRss>
		<slash:comments>82</slash:comments>
		</item>
		<item>
		<title>Letting Oxygene and RemObjects SDK wake you up in time for WWDC</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/04/03/p5774</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/04/03/p5774#comments</comments>
		<pubDate>Wed, 03 Apr 2013 14:59:46 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[non-tech]]></category>
		<category><![CDATA[Nougat]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[WWDC]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5774</guid>
		<description><![CDATA[On Monday, it being a holiday and all, i found myself with a free half hour before dinner and so i decided i&#8217;d write a small little application with Oxygene that can both serve as an example for some cool technology interaction, and also does something useful for me: a Client/Server app that monitors the [...]]]></description>
				<content:encoded><![CDATA[<p>On Monday, it being a holiday and all, i found myself with a free half hour before dinner and so i decided i&#8217;d write a small little application with Oxygene that can both serve as an example for some cool technology interaction, and also does something useful for me: a Client/Server app that monitors the <a href="https://developer.apple.com/wwdc/">Apple WWDC webpage</a> for changes and notifies me via Push Notifications on my iPhone when the page changes.</p>
<p>The whole thing was literally done and <a href="https://github.com/dwarfland/WWDCNotify">up on GitHub</a> in about twenty minutes, start to finish (writing this blog post will probably take longer than writing the app ;), and i figured i&#8217;d give you a rundown of what it does, how it works and how i did it.</p>
<p>I started by going to developer.apple.com and setting up a new App ID with a Push Notification certificate. Any app using Push Notifications needs a unique, non-wildcard ID, so i could not just use one of my existing IDs and profiles.</p>
<p>After downloading the profile and the new Push Certificate, i exported it from Keychain Access as a .p12 file <em>without password protection</em> (to keep things simple).</p>
<p>(The .p12 file is the only piece missing from the WWDCNotify distro on GitHub. You must create your own to run the app, or else we&#8217;d get our streams crossed when more people run the app with the same certificate.)</p>
<p>Next, i created the server app. I wrote that in .NET, so i can use Mono to either run it locally on my Mac, or i move it to one of our Linux servers on EC2, if i wanted to.</p>
<p>I started with the RemObjects SDK for .NET new project wizard. The server is really simple, as it doesn&#8217;t define any of its new services, it just links in our open source <a href="https://github.com/remobjects/Push">Apple Push Provider</a> (source on GitHub), which provides two pieces of core functionality needed for Push notifications on the server:</p>
<ol>
<li>It provides the APSConnect class that encapsulates the protocol for submitting notifications to Apple&#8217;s servers.</li>
<li>It provides a ready-to-go RemObjects SDK Service that clients can call to register for notifications &mdash; along with all the infrastructure to manage the list of registered devices.</li>
</ol>
<p>Nothing but these few lines of code are needed to set up the Push service:</p>
<pre>var lCertificatePath := Path.ChangeExtension(typeOf(self).Assembly.Location, 'p12');
PushDeviceManager.DeviceStoreFile :=  Path.ChangeExtension(typeOf(self).Assembly.Location, 'devices');
PushDeviceManager.CertificateFile := lCertificatePath;
PushDeviceManager.APSConnect.ApsHost := 'gateway.sandbox.push.apple.com'; // for this app, we're staying in the sandbox
PushDeviceManager.RequireSession := false;</pre>
<p>I tell the PushDeviceManager.RequireSession the path to the .p12 file (which i included in the project and set to be copied next to the .exe), the file to store the registered devices in (again, it goes next to the .exe to keep things simple), the URL of the Apple Push Server, and finally i tell it to not bother with requiring clients to authenticate.</p>
<p>And with that, the server is done and ready to let clients register for push notifications&#8230;</p>
<p>Of course there are no notifications being <em>sent</em> yet. To handle that, i created a quick static class that uses a timer that fires every five minutes. When that happens, it downloads the content of the website and compares it to the previous version:</p>
<pre>var lNewWebsite: String;
using lClient: WebClient := new WebClient() do 
  lNewWebsite := lClient.DownloadString(URL);

if assigned(fLastWebsite) and (fLastWebsite &ne; lNewWebsite) then begin
  …</pre>
<p>If that is the case, it will send a notification with message and sound to all registered clients:</p>
<pre>for each d in PushDeviceManager.Devices.Values do
  PushDeviceManager.APSConnect.PushCombinedNotification(d.Token.ToArray, 'ALARM ALARM! The WWDC Website has changed', 0, 'default');</pre>
<p>It&#8217;s that simple.</p>
<p>Because i have a mild case of OCD, i also made the server send a regular notification without sound (every few hours), to assure me that the service is still running. And on startup, it will also send a notification that the server has been (re)started &mdash; again really just to set me at ease that everything is working, when launching or re-deploying the server.</p>
<p>Ok, if you think &#8220;well, that was easy&#8221;, wait till we get to the client. I added a second project to the solution, this time an iOS app based on the Simple App template — which does nothing but show an empty view. (For completeness sake, i went into Interface builder and made the empty view show the Default.png image, instead of just a white screen.)</p>
<p>To communicate with the server, i imported the interface file for our Push Server by going to the <em>RemObjects SDK|Import Service menu</em> and choosing the RODL file from the Push project above (i could also have pointed it to the URL of the running server instead).</p>
<p>Literally all the code that drives the app is in the AppDelegate class:</p>
<p>In <b>application:DidFinishLaunchingWithOptions:</b>, we add one line of code:</p>
<pre>application.registerForRemoteNotificationTypes(UIRemoteNotificationType.UIRemoteNotificationTypeAlert or
                                               UIRemoteNotificationType.UIRemoteNotificationTypeSound)</pre>
<p>to let the OS know we are interested in notifications, and want alerts and sounds.We then implement two callback functions that will be called either if registration for push was successful, or if it failed (which will happen when running it in the simulator, for example). <b>application:didRegisterForRemoteNotificationsWithDeviceToken:</b> and <b>application:didFailToRegisterForRemoteNotificationsWithError:</b>.</p>
<p>When registration fails, we simply show an alert view with the error message.</p>
<p>The success case is more interesting:</p>
<pre>method AppDelegate.application(application: UIKit.UIApplication) didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Foundation.NSData);
begin
  var p := new ApplePushProviderService_AsyncProxy withURL(new NSURL withString(URL));
  p.beginRegisterDevice(deviceToken, UIDevice.currentDevice.name) startWithBlock(method (aRequest: ROAsyncRequest) begin
      p.endRegisterDevice(aRequest);
      var lAlert := new UIAlertView withTitle('All set!') 
                         message('You are registered for Push Notifications!') 
                         &#038;delegate(nil) 
                         cancelButtonTitle('Okay!') 
                         otherButtonTitles(nil);
      lAlert.show();
    end);
end;</pre>
<p>Here we do an async call to the <em>RegisterDevice</em> function exposed by the server, passing the <em>deviceToken</em> we received (this is the token the server will hold on to and use to later send a message to our device). We pass a block that gets called back when the call was successful and &mdash; just for completeness &mdash; we show a message that everything went well when that happens.</p>
<p>And that&#8217;s it. I run the server with &#8220;mono WWDCNotify.exe&#8221;. Run the client app once to let it register, and then forget about it.</p>
<p><center><img src="http://blogs.remobjects.com/wp-content/uploads/2013/04/WWDCNotify.png" /></center></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/04/03/p5774/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cocoa/CoreFoundation Bridging Explained</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/04/02/p5749</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/04/02/p5749#comments</comments>
		<pubDate>Tue, 02 Apr 2013 15:17:56 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Nougat]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5749</guid>
		<description><![CDATA[&#8220;Bridging&#8221; is a new language feature introduced to Objective-C alongside ARC, that i believe is not very widely understood, at least not fully. Cocoa always had the ability to &#8220;toll-free bridge&#8221; between Cocoa objects, such as NSString and their underlying non-object-oriented CoreFoundation equivalents, like CFStringRef. Before ARC, you could just cast back and forth between [...]]]></description>
				<content:encoded><![CDATA[<p>&#8220;Bridging&#8221; is a new language feature introduced to Objective-C alongside ARC, that i believe is not very widely understood, at least not fully.</p>
<p>Cocoa always had the ability to &#8220;toll-free bridge&#8221; between Cocoa objects, such as NSString and their underlying non-object-oriented CoreFoundation equivalents, like CFStringRef. Before ARC, you could just cast back and forth between them as you pleased, but ARC made the rules a bit stricter, and Objective-C introduced new &#8220;bridge casts&#8221; to formally express these toll-free bridge casts in an ARC-safe manner. Oxygene also supports these casts, with the bridge&lt;T>() compiler magic function.</p>
<h2>Questions?</h2>
<p>So how do bridge casts work, when do you need them, and what is the difference between the three distinct types? That are questions that i think a lot of people are confused about. I&#8217;ll admit i myself wasn&#8217;t quite sure what the differences and implications of &#8220;bridge&#8221; vs. &#8220;transfer&#8221; vs. &#8220;retain&#8221; were, until Carlo and i sat down the other day to really formalize how we would properly expose them in Oxygene (and thus had to understand them really well ;)).</p>
<p>As most Objective-C developers who use ARC <em>will</em> know, the answer to the middle question is the easiest. When do you need a bridge cast? Simple: every time you want to go from a Cocoa object to a CoreFoundation entity or back. You know this, because the compiler will tell you by refusing to compile code that was perfectly fine in pre-ARC, such as:</p>
<pre>NSString *s = (NSString *)myCFString;</pre>
<p>Instead, you now need to write:</p>
<pre>NSString *s = (__bridge NSString *)myCFString;</pre>
<p>Or do you? The answer is, it depends. As i mentioned before, there are three different <em>types</em> of bridge casts, and it is important to pick the right one (lest you will end up in the land of chasing down memory leaks and weird crashes, once again).</p>
<p>I say there are three types, but you can really think of them as two groups of casts.</p>
<h3>&#8220;Regular&#8221; Bridge Cast</h3>
<p>First, there&#8217;s what i like to think of as the <strong>&#8220;regular&#8221; bridge cast</strong>. In Objective-C that&#8217;s expressed with the __bridge keyword; in Oxygene, it&#8217;s the default when calling bridge&lt;T> without a BridgeMode enum value (or with BridgeMode.Bridge, the default):</p>
<p><strong>Objective-C</strong></p>
<pre>UIColor *u = [UIColor redColor];
CGColorRef c = [u CGColor]
id o = (__bridge id)c;
[u set]; // or something else that keeps "u" around.</pre>
<p><strong>Oxygene</strong></p>
<pre>var u := UIColor.redColor;
var c := u.CGColor
var o := bridge&lt;id>(c);</pre>
<p>You can think of this as making the original item (a CGColor) available &#8220;on the other side&#8221; (as featureless &#8220;id&#8221;, in this case, as CGColorRef is not toll-free bridged to a Cocoa class), without affecting the original.</p>
<p><em>The original ownership of the CGColor remains with the UIColor object it was obtained from. The cast object is merely a second view onto the same item, in a different form.</em></p>
<p>The &#8220;regular&#8221; bridge cast works both ways &mdash; going from a Cocoa to a Core Foundation, or the other way around.</p>
<h3>Transfer/Retain Bridge Casts</h3>
<p>The second type of casts are the transfer/retain bridge casts casts. I lump them together because they form two sides of the same coin. Different than the regular bridge cast, they do not work in both directions; instead, the <strong>transfer bridge cast</strong> can be used when going from CoreFoundation to Cocoa, and the <strong>retain bridge cast</strong> when going the opposite way, from Cocoa to CoreFoundation.</p>
<p>In Objective-C that&#8217;s expressed with the __bridge__transfer and __bridge_retained keywords; in Oxygene by calling bridge&lt;T> with a BridgeMode.Transfer or BridgeMode.Retained value.</p>
<p>Why this distinction is necessary will become clear soon, but first let&#8217;s look at an example:</p>
<p><strong>Objective-C</strong></p>
<pre>CFStringRef c = CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding());
NSString *s = (__bridge_transfer NSString)c;
c = nil;</pre>
<p><strong>Oxygene</strong></p>
<pre>var c := CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding());
var s := bridge&lt;NSString>(c, BridgeMode.Transfer);
c := nil;</pre>
<p>As the name implies, the transfer cast <em>transfers</em> the item, and its ownership, to the other side. After the cast from the CFStringRef to an NSString, the NSString (stored in &#8220;s&#8221;) is the only true owner of the underlying string. The original CFStringRef is no longer relevant, and as you see, we do not (must no) free it.</p>
<p><em>Essentially, the transfer cast says, &#8220;give me a Cocoa object, and then let&#8217;s forget the CoreFoundation thing ever existed&#8221;</em>.</p>
<p>This is highly useful when writing more concise code. In the example above, we could have used a regular bridge cast, and simply called CFRelease(c) afterwards and everything would have been fine. But imagine the same example written as a single line of code:</p>
<p><strong>Objective-C</strong></p>
<pre>NSString *s = (__bridge_transfer NSString)CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding());</pre>
<p><strong>Oxygene</strong></p>
<pre>var s := bridge&lt;SString>(CFStringCreateWithCString(nil, 'hello', CFStringGetSystemEncoding()), BridgeMode.Transfer);</pre>
<p>Here we <em>have</em> no reference to the original CFStringRef object, so the transfer cast is essential.</p>
<p>Conversely, you can imagine that using the transfer cast on the CGColor example above would be disastrous. The Original CGColorRef is owned by the UIColor we received it from; we&#8217;d have no right to transfer it and invalidate it underneath the UIColor&#8217;s feet. Things will crash, eventually. (In fact, a bug report with just this problem that we received from a tester of Oxygene was what promoted me to write this post ;)).</p>
<p>At this point, you might already begin to understand why transfer bridge casts can only work one way in an ARC language and why on the flip side the <strong>retain bridge casts</strong> is needed:</p>
<p><strong>Objective-C</strong></p>
<pre>NSString *s = [NSString stringWithFormat:"hello, %@", name];
CFStringRef c = (__bridge_retained CFStringRef)s;
...
CFRelease(c);</pre>
<p><strong>Oxygene</strong></p>
<pre>var s := NSString.stringWithFormat('hello, %@', name);
var c := bridge&lt;CFStringRef>(s, BridgeMode.Retained);
...
CFRelease(c);</pre>
<p>When we used transfer bridge casts above, a true transfer happened; the CoreFoundation reference was no longer valid, and we did release it. Going the other way, we do not have this luxury: The original Cocoa object (a string in this case) is managed by ARC, and there is no way to <em>not</em> release it. If a true transfer bridge cast were allowed, ARC would go ahead and over-release an &#8220;invalid&#8221; object. And that cannot happen.</p>
<p>Instead, the retained bridge cast does the next best thing. It gives us back a CoreFoundation entity we fully own (and have to release), and it leaves the Cocoa object untouched.</p>
<p><em>You can think of the retain bridge cast as &#8220;just like the transfer, but leaving the source object for ARC to deal with&#8221;.</em></p>
<h2>When to Use What?</h2>
<p>The answer to this question will not always be clear-cut, but a good rule of thumb is to use the regular bridge cast &mdash; i.e. __bridge or bridge&lt;T>() w/o mode &mdash; when you do not own the original item and/or are merely &#8220;borrowing&#8221; it to be used on the other side. Use the transfer/retain bridge cast when you do own the original object and want to take ownership of it &#8220;on the other side&#8221;.</p>
<h2>So How Does this Work Under the Hood?</h2>
<p>To be honest, you probably don&#8217;t really want to know, or at least not think about it, because what the bridge casts do under the hood can be really confusing how you think of them on the higher level.</p>
<p>Let&#8217;s start with the <strong>transfer bridge cast</strong>. It essentially does &#8220;nothing&#8221;, just as the regular cast would have done before ARC; it converts the pointer type and that&#8217;s it, and it does not affect the retain count of the object at all.</p>
<p>Because of how ARC works under the hood, it assumes ownership (or a +1 retain count, if you will) of the Cocoa object pointer and this affectively acts as if the original CoreFoundation object had been released (i.e. gotten a -1 on its retain count). The actual retain count of the item has not changed, but ARC now has staked claim on it.</p>
<p>The <strong>regular bridge cast</strong> is essentially the same as the transfer, except it does an extra <em>retain</em> on the resulting object when going from Core Foundation to Cocoa. This way, ARC can deal with the object (and eventually release it again). But the underlying CoreFoundation reference is unaffected and keeps its own claim on the entity. When going from Cocoa to CoreFoundation, it does nothing — because ARC is not involved in handling the life cycle of CF objects, it can just pass the original object off as an unowned entity.</p>
<p>Finally, the <strong>retain cast</strong> works much like the regular bridge, but does an additional retain on the item, before the cast. This way, the original object reference remains retained, and the resulting CF entity is owned (i.e. needs to be freed) as well.</p>
<p>The thing to keep in mind is that there&#8217;s a single retain/reference count for each entity. It&#8217;s really just a sleight of hand on the compiler&#8217;s side how the bridge casts &#8220;move&#8221; the ownership around between the Cocoa and CoreFoundation references.</p>
<p>But as i said, you <em>probably</em> want to forget about these implementation details, and just think of these bridge casts in the logical terms described above ;).</p>
<h2>Summary</h2>
<p>I hope you found this article useful and that it helped to provide some insight into the different bridge cast types on the Cocoa platform. Let me know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/04/02/p5749/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Abstract for Java Samples on Google Play</title>
		<link>http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708</link>
		<comments>http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708#comments</comments>
		<pubDate>Tue, 02 Apr 2013 08:00:42 +0000</pubDate>
		<dc:creator>Anton Vasilenko</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ROFX]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5708</guid>
		<description><![CDATA[I’m happy to announce the availability of the DA SQL Sample – our first, but definitely not last, sample application that is available on Google Play. It is written in Java and powered by our Data Abstract for Java framework. Now it is even easier for you to give the possibilities of Data Abstract for [...]]]></description>
				<content:encoded><![CDATA[<p>I’m happy to announce the availability of the <strong>DA SQL Sample</strong> – our first, but definitely not last, sample application that is available on Google Play. It is written in Java and powered by our Data Abstract for Java framework.<br />
<center><a href="https://play.google.com/store/apps/details?id=com.remobjects.dataabstract.dasql"><img src="https://developer.android.com/images/brand/en_generic_rgb_wo_60.png" width="172" height="60" alt="DA SQL Sample on Google Play" class /></a></center></p>
<p>Now it is even easier for you to give the possibilities of Data Abstract for Java a try. Just install it on your device and try to fetch some data using SQL from our externally available PCTrade Sample Server. The sample is preconfigured to talk to http://remobjects.com:8099/bin, but you can change it on the Settings screen and direct the application to any locally accessible DA Sample Server. Make sure to also try the other available settings.<br />
<a href="http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708/da-sql-android-initial-view-skinned" rel="attachment wp-att-5715"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/03/da-sql-android-initial-view-skinned.png" alt="da-sql-android-initial-view-skinned" width="401" height="700" class="aligncenter size-full wp-image-5715" /></a><br />
Other details about the usage and the concepts covered can be found at the <a href="http://wiki.remobjects.com/wiki/DA_SQL_(Android)_Sample_(Java)">sample’s wiki page</a>.</p>
<p>More samples will be available in the near future. Meanwhile, please note that you can always download and install Data Abstract for Java and compile and run any sample manually. These samples can give you a good starting point in developing your own application with the Data Abstract for Java framework, be it for Android or any other Java-powered target platform.<br />
<a href="http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708/da-sql-android-tablet-skinned" rel="attachment wp-att-5719"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/03/da-sql-android-tablet-skinned-1024x689.png" alt="da-sql-android-tablet-skinned" width="591" height="397" class="aligncenter size-large wp-image-5719" /></a></p>
<p><strong>P.S.</strong> We have published two more Android samples lately.</p>
<p>
<strong>Filters Sample</strong> shows how to use Dynamic Where and Dynamic Select features for obtaining data from the Data Abstract servers.<br />
<a href="http://wiki.remobjects.com/wiki/Filters_(Android)_Sample_(Java)">wiki page</a>, <a href="https://play.google.com/store/apps/details?id=com.remobjects.dataabstract.filters">Play link</a>
</p>
<p>
<strong>Simple Sample</strong> shows basic Data Abstract functionality, including loading, changing and updating of data from and back to the Data Abstract servers.<br />
<a href="http://wiki.remobjects.com/wiki/Simple_(Android)_Sample_(Java)">wiki page</a>, <a href="https://play.google.com/store/apps/details?id=com.remobjects.dataabstract.simple">Play link</a>
</p>
<p><center><a href="http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708/simple-sample-clients-list-framed" rel="attachment wp-att-5771"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/04/simple-sample-clients-list-framed-171x300.png" alt="simple-sample-clients-list-framed" width="171" height="300" class="alignnone size-medium wp-image-5771" /></a><a href="http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708/framed_group-selected-framed-2" rel="attachment wp-att-5770"><img src="http://blogs.remobjects.com/wp-content/uploads/2013/04/framed_group-selected-framed-2-171x300.png" alt="framed_group-selected-framed-2" width="171" height="300" class="alignnone size-medium wp-image-5770" /></a></center></p>
<p style="clear: all">
Install, try them ant tell us what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/antonv/2013/04/02/p5708/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>&#8220;The Truth is in the Cloud&#8221; — Why iCloud Data is Failing You, and How Data Abstract can Help.</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/03/27/p5739</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/03/27/p5739#comments</comments>
		<pubDate>Wed, 27 Mar 2013 18:18:11 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[ROFX]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5739</guid>
		<description><![CDATA[The past few weeks, everybody has been complaining about iCloud. Or more precisely, they have been complaining about a small subfeature that is crucial to app developers: Core Data syncing via iCloud. Developers are concerned that data syncing via iCloud is difficult and unreliable, and that when things go wrong (and the invariably will), they [...]]]></description>
				<content:encoded><![CDATA[<p>The past few weeks, <a href="http://www.theverge.com/2013/3/26/4148628/why-doesnt-icloud-just-work">everybody</a> has been complaining about iCloud. Or more precisely, they have been complaining about a small subfeature that is crucial to app developers: Core Data syncing via iCloud. Developers are concerned that data syncing via iCloud is difficult and unreliable, and that when things go wrong (and the invariably will), they have little to no recourse to investigate or debug the issues.</p>
<p>Frankly, i&#8217;m not surprised about these issues, because from where i stand, Core Data in iCloud uses a fundamentally wrong approach that can only fail. Let&#8217;s see how that is so.</p>
<p>Do you remember when Steve Jobs took the stage at WWDC a couple of years back and introduced iCloud? It was going to be better than all of Apple&#8217;s previous cloud services, and to explain the reason why, Steve used one catch phrase: &#8220;The truth is in the cloud&#8221;. Developers rejoiced and gave a standing-o — and rightfully, because Steve was correct.</p>
<p>For a cloud service to work reliably, the &#8220;truth&#8221; — that is, the authoritative representation of what your data is — needs to be in one central place. The cloud.</p>
<p>And Steve was not lying to us. That claim he made is true for most of iCloud, and if we&#8217;re honest, iCloud is working pretty well for <em>most</em> of the services it provides. Cloud-based documents work great. Cloud-based settings (the Key-Value-Store) work great. All the non-developer features of iCloud (Calendar/Contacts, Backups, heck, even things like iTunes Match) work pretty well. The only thing that is causing developers (and by extension, users) headaches is &#8220;Core Data in iCloud&#8221;. Why is that?</p>
<p>It&#8217;s because Core Data in iCloud violates the core promise Steve made about why iCloud is better. Core Data&#8217;s truth is <strong>not</strong> in the cloud. Instead, Core Data merely uses iCloud as a dumb conduit to sync data back and forth between the different devices a user runs your app on — and leaves the onus for sorting out the sync to the individual devices.</p>
<p>And as we all know, &#8220;syncing is hard&#8221;. And worse, syncing is impossible, if the app doing the syncing has no control over the data flow (for example when the user disables iCloud for a while), and the developer has no way to debug what is going on.</p>
<p>If 15+ years of working with networked data and disconnected clients has taught me anything, it is that this is an unsalvagable situation. In order to have data in your apps and reliably reproduce and &#8220;sync&#8221; it between multiple devices, you need to take control of that data, and have a single truth source — ideally in the cloud.</p>
<p>It just so happens that here at RemObjects Software, we have spent the past 10 years thinking about these problems, and have developed a technology and libraries around it that solve them.</p>
<p>This blog post is less about selling you on Data Abstract (although i of course hope that you will have a look at it), and more about showing how taking control and hosting your own data will solve your problem in ways that Core Data in iCloud can not — and give your app additional capabilities, to boot. So i <em>will</em> look at this from the perspective of using Data Abstract, our product, but many of the ideas covered will be applicable just as well, should you decide to &#8220;roll your own&#8221; or use a different infrastructure.</p>
<h2>What is Data Abstract?</h2>
<p>Data Abstract is a combination of a client library that you link into your iOS or Mac application (it is also available for other  platforms), and server-side infrastructure in form of our free Relativity Server.</p>
<p>One of the &#8220;downsides&#8221; of giving up Core Data/iCloud is that you will need to look at hosting your own data. That seems like a daunting task, but is really not as difficult, or as costly as it might seem. And in fact, you will come to see it as an <em>upside</em> in the long run.</p>
<p>To get started, in most cases a tiny and cheap Amazon EC2 server instance will do the job — we&#8217;re talking monthly costs of around $20 or so. This will be enough to handle the initial load of most apps — and of course, if your app sells really well, the extra costs for upgrading the specs, or &#8220;scaling out&#8221; to more than one server will be peanuts to you, anyways ;).</p>
<p>Setting up the server is really simple. Most Linux servers you can rent or host, including EC2, already come with a database such as mySQL or PostgreSQL (we use the latter a lot, ourselves). All you need to do is install our <a href="http://www.remobjects.com/da/relativity">Relativity Server</a>, and you&#8217;re set. You can of course also use Azure, or other more traditional hosting solutions (and we are working on providing a ready-to-use EC2 image that will let you get set up with this even quicker, soon).</p>
<p>You can then design your database as you see fit, and Relativity Server lets you expose the data to your client applications — you decide what tables get exposed and who can access what, and you can write custom logic to control and influence data access and updates via JavaScript. The Relativity <a href="http://www.remobjects.com/da/serverexplorer/mac">Server Explorer</a> makes this easy and visual.</p>
<p>On the client side, <a href="http://www.remobjects.com/da">Data Abstract</a> is an easy-to-use static library that you can link into your application, and it will handle all the data access for you. The library is built on modern Cocoa principles, for example it uses GCD blocks to handle network access in the background, making it easy to keep your app responsive. Also, it is designed from the ground up for <em>offline data</em>, meaning you do not need to spend a lot of effort worrying about what happens when your user loses network connection — they can work with data while on a plane, and sync back up later when they get back online.</p>
<p>We have a lot of development topics around DA and Relativity server covered in our documentation Wiki, a good starting point is this page: <a href="http://wiki.remobjects.com/wiki/Developing_Database_Applications_for_Mac_and_iOS">Developing Database Applications for Mac and iOS</a>.</p>
<p>In addition to providing all that Core Data/iCloud promises (but reliably), hosting your own data also provides additional benefits that cannot be achieved (by design) with iCloud data, even if it were working perfectly otherwise:</p>
<ul>
<li>In addition to each user having their own private data, your app can share data between users, where applicable — be it between individual users, or publicly with all users.</li>
<li>You can build apps for other platforms, including Android, Windows, or Mac apps not sold in the Mac App Store, that share the same data. (Data Abstract has dedicated libraries for creating native apps for both Android and Windows, as well.)</li>
<li>You can build a web front-end for users to view their data, either via server technologies such as ASP.NET, or client technologies such as a pure JavaScript based browser client. (Again, Data Abstract provides libraries for both, and our library for JavaScript is even completely free.)</li>
<li>Most importantly, though, you as the app developer are in full control of the data. If one of your users calls you and says that something is wrong with their data, you&#8217;ll know exactly where to look.</li>
</ul>
<h2>Summary</h2>
<p>I hope you found this article interesting, and that is has given you a fresh take on the intricacies of adding data &#8220;syncing&#8221; to your app — on iOS and elsewhere.</p>
<p>The key point i hope you will take a way from this is that Core Data in iCloud, being essentially a client-to-client sync mechanism, just like MobileMe and others before it, is fundamentally flawed, so that the myriad of problems many developers are seeing are hardly surprising. And that the solution to that is taking control of your own data, and hosting it with a single &#8220;truth in the cloud&#8221;.</p>
<p>I&#8217;d be lying if i said i didn&#8217;t hope you would consider using Data Abstract as your solution for this problem. We&#8217;re a small team of developers dedicated to this problem, and i believe we have a great and unique solution to it that provides a lot of benefit and can save you a lot of time and resources. Data Abstract sells as developer license, with <em>no deployment costs or royalties</em>.</p>
<p>Let us know what you think!</p>
<p>Whatever solution you choose, we wish you best of luck with your data-driven apps, and are looking forward to what you&#8217;ll produce!</p>
<p>Yours,<br />
marc hoffman</p>
<p>Chief Architect,<br />
RemObjects Software</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/03/27/p5739/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Storyboards with Oxygene &#8220;Nougat&#8221;</title>
		<link>http://www.remobjects.com/tv/oxygene-24-storyboards</link>
		<comments>http://www.remobjects.com/tv/oxygene-24-storyboards#comments</comments>
		<pubDate>Tue, 26 Mar 2013 18:02:50 +0000</pubDate>
		<dc:creator>RemObjects TV</dc:creator>
				<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?guid=acbec1c3e58b8290dd5cefe01d8b5072</guid>
		<description><![CDATA[A brief introduction to building Oxygene "Nougat" applications for iOS using Storyboards and Interface Builder. Storyboards provide a better approach for interface design and controlling the user experience. Oxygene "Nougat" provides full support and i...]]></description>
				<content:encoded><![CDATA[<p>A brief introduction to building Oxygene &#8220;Nougat&#8221; applications for iOS using Storyboards and Interface Builder. Storyboards provide a better approach for interface design and controlling the user experience. Oxygene &#8220;Nougat&#8221; provides full support and integration for storyboards for iPhone and iPad development using Cocoa Touch.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/remobjects-tv/2013/03/26/p5737/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.podtrac.com/pts/redirect.mp4/tv.remobjects.com/oxygene/oxygene-24-storyboards.mp4" length="25793972" type="video/mp4" />
		</item>
		<item>
		<title>Top 10 Reasons to use Platform Native APIs</title>
		<link>http://blogs.remobjects.com/blogs/jim/2013/03/14/p5657</link>
		<comments>http://blogs.remobjects.com/blogs/jim/2013/03/14/p5657#comments</comments>
		<pubDate>Thu, 14 Mar 2013 16:38:26 +0000</pubDate>
		<dc:creator>Jim McKeeth</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Cooper]]></category>
		<category><![CDATA[non-tech]]></category>
		<category><![CDATA[Nougat]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5657</guid>
		<description><![CDATA[What are native platform APIs? They are the APIs provided by the platform vendor that define the platform. On Android this is the Android SDK. On iOS it is the Cocoa Touch Frameworks. On Windows and Windows Phone it is WinRT and the .NET Framework. There are undocumented APIs, and even calls that circumvent the [...]]]></description>
				<content:encoded><![CDATA[<p>What are native platform APIs? They are the APIs provided by the platform vendor that define the platform. On Android this is the Android SDK. On iOS it is the Cocoa Touch Frameworks. On Windows and Windows Phone it is WinRT and the .NET Framework. There are undocumented APIs, and even calls that circumvent the platform APIs, but they are not considered part of the platform API.</p>
<p>In addition to the native development tool provided by the platform vendor, there are 3rd party development tools providers (such as ourselves) with their own solutions. The 3rd party tools typically either focus on providing a better solution for the specific platform, or sacrifice native platform support with the objective of cross-platform simplicity. There is no reason to sacrifice platform support, as you will see in these top 10 reasons to program to platform native APIs.</p>
<p><strong>Platform Native APIs are Great</strong></p>
<p>Those who programmed MS-DOS applications or the early Windows API no doubt remember what a pain those APIs (or lack of) were to work with. Back then it was great to have a good abstraction to make the platform easier to work with. Today&#8217;s platform native APIs encompass all the productivity enhancements that are found in the the best abstractions. Typically, the productivity enhancements that come from additional abstractions are only in the form of familiarity and developer&#8217;s resistance to learning a new API and framework. You know things are getting carried away when there is a Java abstraction for developing Windows Phone 8 applications and a .NET abstraction for building Android applications.</p>
<p><strong>The Law of Leaky Abstractions</strong></p>
<p>&#8220;<a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">All non-trivial abstractions, to some degree, are leaky.</a>&#8221; If your tool forces you to use some non-trivial abstraction on top of a platform&#8217;s API, at some point it will leak &#8211; there will be something that the abstraction cannot do, or somewhere the abstraction behaves differently from platform to platform. If you are serious about developing for any platform, you need to understand the platform&#8217;s native API. The more non-trivial the abstraction, the less of the platform it can abstract successfully and the more likely you will need to move to the platform native API. If you are going to need to learn the platform API anyway, you might as well start there. No need to learn both the abstraction and the platform API &#8211; that is <em>twice</em> as much work.</p>
<p><strong>Native Documentation</strong></p>
<p>Documentation is a lot of work. Good documentation is even more work. On each platform, the platform vendor provides the documentation of the platform along with all the best practices and examples. For each additional level of abstraction that requires another level of documentation to consult. Chances are that the documentation will eventually refer you to the platform API documentation. Wouldn&#8217;t it be nice to just start at the ultimate authority and not have to wade through incomplete and outdated layers of documentation?</p>
<p><strong>No Bloatware</strong></p>
<p>If your abstraction adds additional graphic libraries or run-times, your application suffers with <em>bloat</em>. These abstractions replace the functionality already present in the platfrom and make your app bigger, slower to start-up and less responsive at runtime. Some of these add-ons are worthwhile, but if you need to double (or more) the size of your app just to write &#8220;hello world&#8221;, then you are probably using the wrong solution.</p>
<p><strong>Rapid Release Cycle</strong></p>
<p>When a platform vendor releases a new API you want to be able to take advantage of those features right away. It may surface new hardware features, or just introduce better ways of doing things. If you are forced to use an abstraction, you need to wait for the 3rd party to update their abstraction. This may be fairly quick, or you may have to wait for their release cycle, which, depending on where they are in development, could mean the release after the next. No matter how fast a vendor has been in the past at updating their abstraction library, a point will come where they are not updated when you need them.</p>
<p><strong>Support for Platform Deviations</strong></p>
<p>If a hardware vendor comes out with their own SDK extensions or variations on a platform, they will provide their support at the level of the platform API. If you are stuck behind an abstraction, you will not have access. The openness of Android is a great example with extensions like Google TV, Epsion Moverio, Ouya, and Google Glass. If you are interested in cutting edge platforms like these, you need a development tool that doesn&#8217;t lock you behind an abstraction.</p>
<p><strong>Native User Experience</strong></p>
<p>Each platform has a typical user experience. This comes from the native platform user interface widgets and the way they behave. It also comes from design guidelines provided in the platform documentation. If you are using an abstraction for your user interface, even one that tries to look and act like the native one, it will get in the way of this native user experience. When it comes to user experience, close isn&#8217;t close enough. Using the native platform user interface controls is the only way to give your users the experience they expect.</p>
<p><strong>Less Points of Failure</strong></p>
<p>Everything always works great in the demonstrations, but the more layers of interoperability and wrappers required to make your application run, the more points of failure. When you develop for the platform API directly, you are not handicapping yourself with black boxes or other points of failure for your app. The first time you find yourself debugging into that abstraction layer, you will really wonder if it was worthwhile to shackle yourself with it.</p>
<p><strong>Maximum Developer Flexibility</strong></p>
<p>Platform APIs are huge. In the process of creating a wrapper, choices are made to simplify or eliminate options. These simplifications and eliminations result in less flexibility for the developer. Tying a project to a subset of the features of the platform reduces what you can do with your project. Don&#8217;t tie your hands!</p>
<p><strong>3rd Party Support</strong></p>
<p>The majority of 3rd party components and books are going to support the platform&#8217;s API. The further you are from that, the less support you are going to have. Want to use a cool 3rd party custom control? Hope they port it to your favorite framework. And what are the odds of a book about the specific features of the platform you want to explore covering it via your specific pair of shackles?</p>
<p><strong>Summary</strong></p>
<p>Cross-platform abstractions are only going to get in your way and tie your hands. Any benefit in getting you up to speed faster will be lost in the long term when you hit the rough edges of the abstraction. That is the reason <a href="http://www.remobjects.com/oxygene/">Oxygene</a> is designed to use the platform native APIs directly. There is no forced or complex abstraction to get in your way of using the platform and making the best app possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/jim/2013/03/14/p5657/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Creating a Turn-Based Game for iOS: Nougat Tic-Tac-Toe</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/03/11/p5663</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/03/11/p5663#comments</comments>
		<pubDate>Mon, 11 Mar 2013 15:30:56 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[non-tech]]></category>
		<category><![CDATA[Nougat]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[WWDC]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5663</guid>
		<description><![CDATA[Over the past couple of weeks, i have been working on a new sample project for Oxygene &#8220;Nougat&#8221; on the side. After having gotten Browse500 into the App Store in January and showing how to reimplement a simple native UIKit control from Objective-C in Nougat last month, i wanted to create another example that illustrates [...]]]></description>
				<content:encoded><![CDATA[<p>Over the past couple of weeks, i have been working on a new sample project for Oxygene &#8220;Nougat&#8221; on the side. After having gotten <a href="http://blogs.remobjects.com/blogs/mh/2013/01/17/p5466">Browse500</a> into the App Store in January and showing how to <a href="http://blogs.remobjects.com/blogs/mh/2013/02/22/p5634">reimplement a simple native UIKit control</a> from Objective-C in Nougat last month, i wanted to create another example that illustrates the benefits of how Nougat interacts directly with the native APIs, and i picked a technology i knew nothing about at all to do so: Game Center.</p>
<p>I&#8217;m not a big gamer; i don&#8217;t find myself playing games much, and i have certainly never written one before, so this was a great opportunity to explore something new.</p>
<p>For those of you not familiar with it, Game Center is a technology Apple ships in iOS (and now also Mac OS X) that allows for games to interact across the network to create multi-player games, and to keep track of achievements. Game Center is not about graphics, or game UI, or anything of the sort (there&#8217;s other frameworks for that), it&#8217;s only for bringing players together.</p>
<p>I decided to create a simple turn-by-turn game, that is, a game where multiple players (in this case two) can interact, but only one player is active at a given time. Once a player has made their move, it&#8217;s the next player&#8217;s turn. To keep things simple, i picked a game that everybody knows and that is dead simple to implement, game playing wise: Tic Tac Toe. This way, having to explain the game itself won&#8217;t get in the way of the sample code.</p>
<p>To start with, i had to dig myself into the Game Center documentation and i watched a couple of videos on Turn-by-Turn gaming from WWDC 2011 (sessions i didn&#8217;t attend at the time). As it turns out, the API for interacting with Game Center for such a game is surprisingly easy and straightforward, and i was up and coding in no time.</p>
<p>Before we get started looking at the code, let&#8217;s look at the prerequisites:</p>
<ul>
<li>
<p>Here&#8217;s the amount of effort anyone from the Oxygene team had spent on thinking about or working on making GameKit (the framework for interacting with Game Center) available to Nougat, before i started this endeavor: <strong>0. Nada. Nil.</strong></p>
</li>
<li>
<p>Here&#8217;s the amount of legwork i had to do before i could work with the GameKit APIs, just like every other Cocoa developer would: <strong>i added a reference to GameKit to my project. Done.</strong></p>
</li>
</ul>
<p>That&#8217;s it. No begging someone to translate header files, or waiting for someone to create a crappy abstraction wrapper class. Add a reference, and use the APIs as Apple intended them &mdash; that&#8217;s the way development should be.</p>
<h2>The Code</h2>
<p>Let&#8217;s dive into the code.</p>
<p>First of all, the full code of Tic-Tac-Toe is included in the latest Nougat beta, and it&#8217;s also available in <a href="https://github.com/dwarfland/TicTacToe">my Github account</a> for anyone to explore.</p>
<p>There&#8217;s really three separate parts that are of interest as a sample project in this app:</p>
<ol>
<li>The GameKit integration</li>
<li>The game board, implemented as a custom UIControl</li>
<li>The computer player algorithm, generously provided by my good friend and long-time Oxygene user, <a href="http://jjphotos.co.uk">Jeremy Knowles</a>.</li>
</ol>
<p>Let&#8217;s look at GameKit first.</p>
<h2>Working with GameKit</h2>
<p>There&#8217;s four main classes or concepts that you will work with for GameKit.</p>
<p>The first is the local player, a singleton object that can be obtained via a call to <code>GKLocalPlayer.localPlayer</code>. This objects provides the game with information about the local player &mdash; most importantly their ID, and whether the local player is in fact registered and authenticated with Game Center or not. If the player is not set up for Game Center, Tic Tac Toe will simply disable the appropriate UI and just allow local vs. computer game play (although it would be possibly for a game to provide a signup UI, if so desired).</p>
<p>Next is the <code>GKTurnBasedMatchmakerViewController</code>, which provides access to the standard GameCenter UI. It gives the user access to any and all games they might already have going on, as well as the chance to start a new game. In Tic-Tac-Toe, i make this UI available via a button in the navigation bar, and all that&#8217;s needed to show the view is code like the following:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> request <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GKMatchRequest<span style="color: #000066;">;</span>
request<span style="color: #000066;">.</span><span style="color: #000000;">minPlayers</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">2</span><span style="color: #000066;">;</span>
request<span style="color: #000066;">.</span><span style="color: #000000;">maxPlayers</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">2</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span> mmvc <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GKTurnBasedMatchmakerViewController withMatchRequest<span style="color: #000066;">&#40;</span>request<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
mmvc<span style="color: #000066;">.</span><span style="color: #000000;">turnBasedMatchmakerDelegate</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #000066;">;</span>
mmvc<span style="color: #000066;">.</span><span style="color: #000000;">showExistingMatches</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #000066;">;</span>
presentViewController<span style="color: #000066;">&#40;</span>mmvc<span style="color: #000066;">&#41;</span> animated<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">true</span><span style="color: #000066;">&#41;</span> completion<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>This code brings up the Game Center UI, with the list of games (if any) or straight with the &#8220;Start New Game&#8221; (if not). Via the <code>GKMatchRequest</code>, we force the number of players to exactly two. (Game Center itself allows games for up to 16 players):</p>
<p><center><img src="http://blogs.remobjects.com/wp-content/uploads/2013/03/TicTacToe1.png" alt="Tic Tac Toe Game Center" /></center></p>
<p>The way Game Center works for starting new games is that it lets you either invite a known friend who also plays the game or &mdash; much more interestingly &mdash; auto-match you with another random player. One thing that&#8217;s cool is that after starting a game, <em>it will always be your turn</em> — you will either be thrown into another game that was started earlier by a different user, or you will get to start a fresh game, depending on what games are currently live and waiting for players. If you start a fresh game, you get to make your first move, and then and only then does Game Center go out and try to find someone for you to play with.</p>
<p>Going back to the code level, what we are looking out for is a callback on the <code>turnBasedMatchmakerDelegate</code> that we assigned above. Our root view controller class implements some 4 methods from the <code>IGKTurnBasedMatchmakerViewControllerDelegate</code> interface, and the match-maker view controller will call us back on these when interesting things happen. This is a very common pattern in Cocoa, and is how the platform handles &#8220;events&#8221;.</p>
<p>In particular, the callback we care about for starting a new game is:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> turnBasedMatchmakerViewController<span style="color: #000066;">&#40;</span>aViewController<span style="color: #000066;">:</span> GKTurnBasedMatchmakerViewController<span style="color: #000066;">&#41;</span> 
       didFindMatch<span style="color: #000066;">&#40;</span>aMatch<span style="color: #000066;">:</span> GKTurnBasedMatch<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>This method actually gets called any time the user picks a game in the Game Center UI &mdash; whether they are starting a new game, or selecting an existing game. This is neat, because it means we can leave all the game management to GameKit, and don&#8217;t need to keep track of ongoing games ourselves.</p>
<p>This callback receives the third important class, a <code>GKTurnBasedMatch</code>. &#8220;All&#8221; we need to do when this method is called is load the passed match as the active game. In the Tic-Tac-Toe app, we do this by calling our own <code>loadCurrentMatch()</code> method, which does all the heavy lifting.</p>
<p>Every match contains a binary blob in the <code>matchData</code> property that describes the current game state. The content of this binary blob is entirely up to our game, but we can use it to store up to 4KB of data, and this data will automatically be passed between all the participants as they take their turns. In turn, our Game will read the data, let the active player make their move, and then store the updated game state, as we will see in a few moments.</p>
<h3>Loading a Game</h3>
<p>Loading a game is done with two method calls, first, a a small helper function loads the binary data into an <code>NSDictionary</code>, and then we ask the board to load its game state from that dictionary (the idea being that in a future version, our game might store additional info in the dictionary that the board does not care about &mdash; that&#8217;s why i decoupled the data the <code>Board</code> class reads/writes from the actual binary format).</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span> lDictionary <span style="color: #000066;">:</span><span style="color: #000066;">=</span> dictionaryFromData<span style="color: #000066;">&#40;</span>fCurrentMatch<span style="color: #000066;">.</span><span style="color: #000000;">matchData</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
fBoard<span style="color: #000066;">.</span><span style="color: #000000;">loadFromNSDictionary</span><span style="color: #000066;">&#40;</span>lDictionary<span style="color: #000066;">,</span> …<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>The same happens in reverse when we later save the updated game state. Of course, when a new game is first started, there will be no data present (GameKit doesn&#8217;t know anything about how our game data is structured, after all), so our code will need to be prepared to find an empty <code>NSData</code> object in <code>matchData</code>.</p>
<p>The second part, in addition to loading the board data, is determining the active player (if any) and enabling the game play. Each <code>GKTurnBasedMatch</code> has a <code>currentParticipant</code> property of type <code>GKTurnBasedParticipant</code> which links to the current player (it also has a <code>participants</code> array that contains all (two) players). We can compare this participant&#8217;s <code>playerID</code> to that of the local player.</p>
<p>If they match, it&#8217;s the local player&#8217;s turn, so we display &#8220;your turn&#8221;, and enable the board. If they don&#8217;t match, it&#8217;s either the remote players&#8217; turn (if <code>currentParticipant</code> is assigned), or the game has finished. In either case, we show the proper status message, and leave the board disabled.</p>
<h3>Playing a Turn</h3>
<p>If it was the local player&#8217;s turn and we enabled the board, we&#8217;re done for now, and await the player to make a move. This all happens inside the <code>Board</code> class, which will call us back via the <code>board() playerDidSelectGridIndex()</code> method, once the player made their move.</p>
<p>What we need to do then is determine the game status (the player might have made a winning move, for example), re-encode the game status, and pass control back to game center.</p>
<p>There are three scenarios we need to cover:</p>
<ol>
<li>The player has won by managing to place 3 &#8220;X&#8221; markers in a row.</li>
<li>The board has been filled (and the game just tied).</li>
<li>Any other case — the game is still on.</li>
</ol>
<p>In the two game-over scenarios, we set the appropriate status (Won/Lost/Tied) on each of the game participants, and then call <code>endMatchInTurnWithMatchData() completionHandler()</code> to tell Game Center that the match has ended as part of the player taking his turn.</p>
<p>In the other case, we call <code>endTurnWithNextParticipant() matchData() completionHandler()</code> to let Game Center know that the local player is done, and game play can move to the next player.</p>
<p>In either case, we will pass the updated information on what our game board looks like now, via the <code>matchData</code> parameter.</p>
<p>It is worth noting that it&#8217;s up to our game to tell Game Center &#8220;who&#8217;s next&#8221;. In our case, that decision is trivial (it&#8217;s the player that&#8217;s not the local player), but Game Center allows for turns to be passed in arbitrary ways, depending on your game&#8217;s needs &mdash; it doesn&#8217;t always have to go around the (virtual) table.</p>
<p>Once we called either of the above fund methods, it&#8217;s no longer our turn, and all we can do is wait for the remote player to make a move.</p>
<h3>Handing Remote Turns</h3>
<p>Of course, eventually the remote player <em>will</em> make their move, and GameKit provides a second delegate interface for this case, <code>IGKTurnBasedEventHandlerDelegate</code>, which we have hooked up to the <code>GKTurnBasedEventHandler.sharedTurnBasedEventHandler</code> singleton.</p>
<p>What will happen once the remote player moved is that Game Center will show a notification banner to the user, saying something along the lines of &#8220;It&#8217;s Your Turn&#8221;, and play that annoying fanfare sound. When and only when the user taps that notification, will we receive a call to the</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="oxygene" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">method</span> handleTurnEventForMatch<span style="color: #000066;">&#40;</span>aMatch<span style="color: #000066;">:</span> GKTurnBasedMatch<span style="color: #000066;">&#41;</span> 
       didBecomeActive<span style="color: #000066;">&#40;</span>didBecomeActive<span style="color: #000066;">:</span> Boolean<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>method to let our application know that something happened. This is nice, because it saves us from worrying about showing any UI to the user to ask if they, say, want to switch from the game they are currently looking at to the one that has received a response. When we get the callback, we already know that the user has decided to view the game in question.</p>
<p>So all we really need to do is the same as we did in <code>… didFindMatch()</code> above: load the passed match and enable the board, if appropriate.</p>
<h3>House Keeping</h3>
<p>This basically takes care of all the Game Center interaction needed for our simple game. There&#8217;s a few more minor items that i won&#8217;t go into detail for this post; for example, there&#8217;s a callback you will want to handle to quit games if the user selects to delete them in the Game Center UI. There also are APIs for providing a custom UI for the list of games, instead of relying on the standard UI provided by Game Center (all Tic-Tac-Toe does with this is adjust the Game Center button to either read &#8220;Games&#8221; or &#8220;Start&#8221;, depending on whether there are any games ongoing or not).</p>
<p>In Tic-Tac-Toe, <strong>all</strong> the GameKit interaction is located in <em>RootViewController.pas</em>, which is only ~500 lines of code total, so it should give you a good overview and starting point for your own game.</p>
<h3>Caveats</h3>
<p>There are a couple of caveats you might want to be aware of when working with Game Center games; these had me stumped for a short while, so hopefully pointing them out here will help save you frustration:</p>
<ul>
<li>
<p>In order for Game Center to work, your app needs to be registered on <a href="itunesconnect.apple.com">iTunes Connect</a> with the appropriate app ID. Even for the simulator. This is counter-intuitive if you are used to App Store development, because normally you don&#8217;t have to go to iTunes Connect to register your app until you&#8217;re (almost) ready to go and submit it. For Game Center, you need to register it first. If you don&#8217;t, <code> GKTurnBasedMatchmakerViewController</code> will just come up looking all empty and dysfunctional.</p>
</li>
<li>
<p>As best as i can tell, you <em>must</em> specify &#8220;<code>gamekit</code>&#8221; in the <code>UIRequiredDeviceCapabilities</code> section of your Info.plist file for things to work properly.</p>
</li>
<li>
<p>Finally, and most importantly, notifications do not work in the Simulator. If you worked with Push Notifications before, this might not come as much of a surprise, but realize that callbacks such as <code>handleTurnEventForMatch() …</code> will never, ever be called on the Simulator &mdash; which seriously will impact how you test game interaction. (In essence, i found the only way to work around this was to manually invoke the <code> GKTurnBasedMatchmakerViewController</code> and re-select the active game to trigger the app to reload the game data and detect the changed game state.)</p>
</li>
</ul>
<h2>The Game Board</h2>
<p>The second piece of interest in the game is the <code>Board</code> class, which implements all the UI of the game as a really simply <code>UIControl</code> descendant.</p>
<p>The implementation is fairly straight-forward; the class maintains a 3&#215;3 array to keep track of which player has claimed a particular spot on the game board, and in which move (by keeping track of the move number, the game can show different versions of their &#8220;X&#8221; and &#8220;O&#8221; markers, making the board look more dynamic).</p>
<p>The <code>begin/continue/endTrackingWithTouch() withEvent()</code> methods are overridden to keep track of &mdash; you guessed it &mdash; the user&#8217;s finger, and they use animations to fade the user&#8217;s game piece in and out, and to move it to the next appropriate spot, as the finger moves. (You&#8217;ll notice that while the user can move their finger all over the board, the game piece will always &#8220;snap&#8221; to a fixed position in the closest matching grid spot with a smooth animation.)</p>
<p>All the game pieces (the grid, the &#8220;X&#8221; and &#8220;O&#8221; game pieces, etc.) are pre-created images, and the game pieces come in 5 versions (since 5 is the maximum number of moves any one player can make).</p>
<p>The entire <code>Board</code> class is really straightforward and there isn&#8217;t much worth covering here that won&#8217;t be clear from looking at the code. Worth pointing out is the <code>makeComputerMove</code> method, which invokes Jeremy&#8217;s mean <code>ComputerPlayer</code> class, which is used when not playing in Game Center mode.</p>
<p><center><img src="http://blogs.remobjects.com/wp-content/uploads/2013/03/TicTacToe2.png" alt="Tic Tac Toe Board" /></center></p>
<h2>Summary</h2>
<p>I think that&#8217;s it (and it&#8217;s probably enough ;). Make sure to check out the code on <a href="https://github.com/dwarfland/TicTacToe">GitHub</a>, and let me know what you think!</p>
<p>Oh, and: even though the code is written in Oxygene, as are the code snippets here, i hope the general description of how to work with GameKit will also be useful to &#8220;regular&#8221; Cocoa developers using Objective-C. Another nice thing about Oxygene working directly against the standard Cocoa APIs without any abstractions!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/03/11/p5663/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Where Does Business Logic Belong?</title>
		<link>http://blogs.remobjects.com/blogs/jim/2013/02/25/p5624</link>
		<comments>http://blogs.remobjects.com/blogs/jim/2013/02/25/p5624#comments</comments>
		<pubDate>Mon, 25 Feb 2013 11:40:02 +0000</pubDate>
		<dc:creator>Jim McKeeth</dc:creator>
				<category><![CDATA[ROFX]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5624</guid>
		<description><![CDATA[The question of where business logic belongs is as old as database application development. Early on, with primitive client server development, the business logic existed in the client and the database existed only to persist the data. The advantage of this approach is that it makes the client responsive for input validation, and simplifies the [...]]]></description>
				<content:encoded><![CDATA[<p>The question of where business logic belongs is as old as database application development. Early on, with primitive client server development, the business logic existed in the client and the database existed only to persist the data.</p>
<p style="text-align: center;"><img class="aligncenter" style="height: 200px;" alt="Client Server" src="http://blogs.remobjects.com/wp-content/uploads/2013/02/Client-Server-1024x503.png" /></p>
<p>The advantage of this approach is that it makes the client responsive for input validation, and simplifies the degree of coupling between the client and server. The disadvantage is that if a different client connects to the database, the business logic is no longer enforced. This compromises the integrity of the database. There are other disadvantages to client server development &#8211; to learn more, read the <a href="http://www.remobjects.com/da/why-multitier">white paper on &#8220;Why Multi-Tier&#8221;.</a></p>
<p>With the introduction of <a href="http://www.remobjects.com/da">Multi-Tier database application development</a>, the business logic moved to a Middle-Tier.</p>
<p style="text-align: center;"><img style="height: 200px;" alt="MultiTier" src="http://blogs.remobjects.com/wp-content/uploads/2013/02/MultiTier-1024x304.png" /></p>
<p>This has the immediate advantage of keeping the database secure no mater which client connects, while also simplifying client development. The disadvantage is that the client has to make a round trip to the server to validate user input &#8211; a major hit in the user experience department.</p>
<p>What I&#8217;ve seen some developers do is duplicate the input validation business logic from the middle-tier into the client. This speeds up input validation, but increases the complexity of client development, and requires that any business logic updates be made in two places &#8211; duplication of code is rarely the right answer.</p>
<p>Thankfully <a href="http://www.remobjects.com/da/">Data Abstract</a> has a solution for this thanks to the new <a href="http://www.remobjects.com/da/scripting">Business Rule Scripting support</a>. Not only does it allow you to easily define your server side business logic in JavaScript, but also, select scripts are shared from the server to the client for fast and convenient validation and the best possible user experience.</p>
<p style="text-align: center;"><img style="height: 200px;" alt="Data Abstract Business Rules Scripting" src="http://blogs.remobjects.com/wp-content/uploads/2013/02/Client-Scripting-1024x304.png" /></p>
<p>This has the advantage of running the validation logic twice &#8211; once on the client for fast response, and then again on the middle-tier to protect the database. This is the best of both worlds &#8211; you keep your database secure and your client application responsive with no duplication of effort or code to keep synchronized. Data Abstract takes care of all that for you.</p>
<p>Additionally, <a href="http://www.remobjects.com/da/schemas">Data Abstract&#8217;s schema technology</a> keeps the client completely decoupled from the database. This keeps the database easier to maintain, and allows your application to easily migrate to a new database when your project requires it.</p>
<p>Both schemas and business rules scripting are supported in all editions of Data Abstract: .NET, Java, Delphi, Xcode and JavaScript. Learn more about <a href="http://www.remobjects.com/tv/da-06-scripting">Business Rules Scripting</a> on RemObjects TV.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/jim/2013/02/25/p5624/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Custom iOS Controls in Oxygene &#8220;Nougat&#8221;</title>
		<link>http://blogs.remobjects.com/blogs/mh/2013/02/22/p5634</link>
		<comments>http://blogs.remobjects.com/blogs/mh/2013/02/22/p5634#comments</comments>
		<pubDate>Fri, 22 Feb 2013 16:45:50 +0000</pubDate>
		<dc:creator>marc</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Nougat]]></category>
		<category><![CDATA[Oxygene]]></category>
		<category><![CDATA[Prism]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?p=5634</guid>
		<description><![CDATA[A week or so back, Yari D&#8217;areglia had an excellent tutorial on his blog on How to build a custom control in iOS that gave a nice rundown of some of the tasks involved, including handling touches, drawing some non-trivial custom UI, and returning events to the application via the target/action pattern. While Oxygene &#8220;Nougat&#8221; [...]]]></description>
				<content:encoded><![CDATA[<p>A week or so back, Yari D&#8217;areglia had an excellent tutorial on his blog on <a href="http://www.thinkandbuild.it/how-to-build-a-custom-control-in-ios">How to build a custom control in iOS</a> that gave a nice rundown of some of the tasks involved, including handling touches, drawing some non-trivial custom UI, and returning events to the application via the target/action pattern.</p>
<p>While Oxygene &#8220;Nougat&#8221; can of course use any such controls directly and without having to convert or wrap them, i thought it would be fun to try and port the code over to Nougat and see what it looks like (and what kind, if any, challenges would be involved).</p>
<p>We don&#8217;t have <a href="wiki.oxygenelanguage.com/en/Oxidizer">Oxidizer</a> support for Objective-C <em>yet</em>, so i did this manually, but it was still a very straight-forward process, and below are a few notes:</p>
<ul>
<li>
<p>It turns out the new &#8220;Auto-Fix&#8221; for <code>=</code> vs. <code>:=</code> assignments that <a href="http://www.remobjects.com/oxygene/whatsnew">we are shipping</a> in the February release (which RTMs today) is a <strong>huge</strong> time saver. Just leave all the &#8220;<code>=</code>&#8221; in place, and the compiler will fix them for you when you hit build. This is new since i last converted code a few weeks back, and a much appreciated improvement.</p>
</li>
<li>
<p>There&#8217;s really only two &#8220;repetitive&#8221; tasks i found myself doing a lot to convert Obj-C to pascal: (a) changing Objective-C style &#8220;<code>[]</code>&#8221; method calls to use regular Oxygene &#8220;<code>.</code>&#8221; or &#8220;<code>:</code>&#8221; operators and (b) replacing type names with &#8220;var&#8221; in local variable declarations, such as <code>CGpoint centerPoint = …</code> to simply <code>var centerPoint…</code>.</p>
</li>
<li>
<p>There were a couple of C macros used in the original code, which  translated nicely into inline methods — a new feature in the Oxygene language for version 6.0.</p>
</li>
</ul>
<p>All in all, i spent maybe 30 minutes last night converting and then tweaking/cleaning the code, and then the control and surrounding sample app was working perfectly (i also found a couple of new compiler bugs — remember Nougat <em>is</em> still beta — which always makes Carlo happy. When i woke up this morning, they were already fixed ;).</p>
<p>&nbsp;</p>
<p>If you&#8217;re at all interested in creating your own controls for iOS (whether in Nougat or in Objective-C), i recommend to check out <a href="http://www.thinkandbuild.it/how-to-build-a-custom-control-in-ios">Yari D&#8217;areglia&#8217;s post</a>. His original code can be found on <a href="https://github.com/ariok/TB_CircularSlider">GitHub</a>, as can be <a href="https://github.com/dwarfland/TBCircularSlider-Oxygene">my ported version</a>.</p>
<p>&nbsp;</p>
<p><center><img src="https://raw.github.com/dwarfland/TBCircularSlider-Oxygene/master/README.png" alt="Screenshot" /></center></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/mh/2013/02/22/p5634/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oxygene &#8220;Nougat&#8221; Overview</title>
		<link>http://www.remobjects.com/radio/13-oxygene-nougat-overview</link>
		<comments>http://www.remobjects.com/radio/13-oxygene-nougat-overview#comments</comments>
		<pubDate>Thu, 14 Feb 2013 19:39:15 +0000</pubDate>
		<dc:creator>RemObjects Radio</dc:creator>
				<category><![CDATA[radio]]></category>

		<guid isPermaLink="false">http://blogs.remobjects.com/?guid=e8f42c329a7ceec9fd7ff40db34f13ee</guid>
		<description><![CDATA[Discussing with marc hoffman, Carlo Kok, Mike Orris &#38; Brian Lindahl the newest flavor of Oxygene "Nougat", bringing the Oxygene programming language to the Cocoa and Cocoa Touch frameworks for Mac and iOS development. See also the [<a href="http://www.remobjects.com/tv/oxygene-23-nougat">Introducing Nougat</a>] and [<a href="http://www.remobjects.com/tv/oxygene-20-oxygene-overview">Oxygene Overview</a>] videos.]]></description>
				<content:encoded><![CDATA[<p>Discussing with marc hoffman, Carlo Kok, Mike Orris &amp; Brian Lindahl the newest flavor of Oxygene &#8220;Nougat&#8221;, bringing the Oxygene programming language to the Cocoa and Cocoa Touch frameworks for Mac and iOS development. See also the [<a href="http://www.remobjects.com/tv/oxygene-23-nougat">Introducing Nougat</a>] and [<a href="http://www.remobjects.com/tv/oxygene-20-oxygene-overview">Oxygene Overview</a>] videos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.remobjects.com/blogs/remobjects-radio/2013/02/14/p5622/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.podtrac.com/pts/redirect.mp3/radio.remobjects.com/13-oxygene-nougat-overview.mp3" length="28757052" type="audio/mpeg" />
		</item>
	</channel>
</rss>
