Archive for October, 2008

The second part of the Cappuccino tutorial, Scrapbook Part II Implementing Drag and Drop, has been available for a few days. It deals with drag&drop, (that is exactly the subject of the chapter I’m currently reading in Cocoa Programming… page 760 : informal protocols for drag source and drag destination, etc.), collection views and scrollable views, archiving.

A book upon iPhone programming (besides Apple’s great documentation) was released October, 15 : The iPhone Developer’s Cookbook: Building Applications with the iPhone SDK. It is available for Safari Books Online subscrivers. It contains 384 pages (see the chapters list and some samples at Safari Books Online).

Among the new free games for iPhone on the AppStore, we notably find : JellyCar (from the same authors as Trace, the principle is used here to move a car), MazeFinger, PacMan Lite (only one level), and iBall3D (classic labyrinth game with 3 completely different levels/environments).

A 9.0.3 update to X-Plane (iPhone version) is available. We can read the full new features description (and see new screenshots) here. The map (added in the settings pages in version 9.0.2) now provides NAVAID frequencies, and we can display an instruments panel (full screen), in order to set an auto approach (ILS).

Pangea Software provides this week (ends tomorrow) a huge rebate on Bugdom 2 (-75%, only 0,99$) and Nanosaur 2 (-50%, now only 1,99$). Updates are also available : Bugdom 2 version 1.0.2 (improved controls, minor bug fixes and performance enhancements), Enigmo 1.2 (small performance improvements, and now the savegames are stored on the OSX user Documents folder when synchronizing the iPhone).
We can also download a strategy guide for the 10 levels of Bugdom 2 (maps, hints).

FieldRunners is a new strategy game (of Tower Defense type) for iPhone (4,99$), probably the best at this time in that category. We can watch a video here. We can also find an original and free game, Trace, that provides 6 worlds and 120 levels : the purpose of that adventure game is to draw (with touch) the elements that allow to reach the goal (the end of the level) ! A demonstration video is provided.
Finally a free (lite) version of Toy Bot Diaries (some sample levels) is available at the AppStore (the full game is priced 3,99$).

Korg M3 XPanded : free update

Posted: October 10, 2008 in Audio
Tags:

As for the M3 to remain competitive compared with the M50, Korg presented the XPanded M3, an update that doubles the internal samples memory (now 640Mb : new electric pianos, a new 3 velocity levels stereo acoustic piano, the KORG SG-1D stage piano, vintage flutes and strings as with the M50, mono piano, etc.).
That revision also brings new visual and touch editing features for the sequencer (Piano Roll, display of audio tracks waveforms), new effects and enhanced KARMA mode (2.2 version).

Moreover the M3 XPanded is bundled for free with 3 new PCM expansions, 128Mb each (that is 384Mb, besides the enhanced internal memory) : Brass & Woodwinds (EX-USB-PCM01/02) and Concert Grand Piano (EX-USB-PCM03). Finally that whole upgrade is free from an existing M3 (through download) ! Audio demos are available.

Following Cappuccino, a new open-source project (developed by a french man) promoting Cocoa has been launched, JSCocoa. This javascript library uses JavascriptCore (the javascript engine from Apple’s WebKit framework) in order to call C and/or Objective-C code from javascript.

Contrary to Cappuccino (that is a full rewrite of Cocoa classes in javascript, plus a dynamic compiler to convert at runtime Objective-J client code to standard javascript), JSCocoa provides a pure javascript syntax (that is less close to Objective-C than Objective-J). However JSCocoa brings some easy notations derived from Rubby and jQuery in order to simplify the syntax.

Finally, the end code executed is Objective-C (contrary to the Cappuccino solution), through ObjCRuntimeBridgeSupport and libffi. Then JSCocoa only works on MacOSX (10.5.5, PPC and Intel), what greatly reduces its interest. It would be better if Apple decided to release the ObjCRuntime on Windows, but it would sill require a porting of Cocoa classes (that is the YellowBox…) And then the bridge would be less useful (still the case on OSX, in fact it makes deployment of applications easier – only a browser needed – and paves the way for accessibility features, that is access to system fonctionnalities, an area where Cappuccino will have to use a similar bridge).

As it is only a bridge, the install only weights 1,3Mb (includes an example, JSCoreAnimation). The solution also allows to load NIBs from javascript client code, but IBOutlet and IBAction instance variables have to be defined manually in the code.

Then JSCocoa is simply an easier way to use the bridge presented some months ago, that is calling d’Objective-C from a WebView (Webkit view), through a WebScriptObject.
It is the third solution popularizing Cocoa in a few months, without counting the iPhone UIKit.

In March we learnt how to install the iPhone SDK (hidden APIs at that time) and make it work on Windows or Linux (GCC, etc.), and in September we digged in another article about installation of that so called iPhone dev ToolChain.
IBM now provides a tutorial about developing for iPhone using Eclipse CDT (C Development Tooling). It also requires GCC installation.

Among CPView available for now in Cappuccino we find : CPClipView, CPCollectionView, CPControl, CPFlashView (!), CPProgressIndicator, CPScrollView, CPShadowView, CPTabView, NSCustomView, NSView, _CPWindowView. There isn’t yeat any equivalent to NSTableView, NSOutlineView or NSBrowser, but the Cappuccino team is working on the implementation of a CPTableView :

The CPTableView is still under development, it’s already in the repository if you want to have a look. After this is finished i think the cappuccino team or someone else will pickup the work on CPBrowser. 

It seems hard work due to these components complexity :

CPTableView : needs all of NSTableView and supporting classes. We’re not going to be using NSCell’s though, so we’ll also need to make some decisions on exactly what to do here, at least when straight up NSView replacement isn’t enough. 

However that team still managed to write about 20 000 lines of code for Cappuccino’s AppKit and FoundationKit.
Meanwhile they advice using a CPCollectionView (and CPCollectionViewItem), but then we have no column headers no rearrange feature (no column move nor resizing).

Once these hierarchical models display components are available, the Nib2Nic team will be able to manage the appropriate conversion, with the important (and impacting) difference that CPTableView shouldn’t rely on Cell classes.

Usually enterprise applications rely on paginated table components in order to limit the requested data size (in a cursor way). With Cocoa TableView are included in a ScrollView, and only visible rows (at the current position, that is the current position of the vertical scroller) are loaded (requested to the datasource object). Then while scrolling, the datasource provides the additional rows only, never the whole table data (except when they all fit in the visible area).
Cocoa indeed dispatchs the rows on multiple pages when preparing the component for printing.

When the CPTableView will be available in Cappuccino, we will just need to implement that simple datasource object’s method : (id)tableView: (CPTableView *)aTableView objectValueForTableColumn: (CPTableColumn*)aTableColumn row: (int)rowIndex.
It will typically trigger a JSONP request to the server in order to retreive values for that cell. We will probably prefer maintaining a cache to avoid making a database request for only such a cell. In fact in that case the TableView model with scrollable view won’t look appropriate (a tableView: objectsArrayForTableColumn: page: method would be better).
Moreover, if we want to manage sorting (with ascending or descending order) – what is easily done in Cocoa -, we won’t be able to consider the columns separately, and the datasource method will have to look like this (will return a cells values matrix) : tableView: objectsMatrix: forPage: sortingColumn: ascendingOrder:.

Update: We can now use the new CP2JavaWSTableViewDelegate component as CPTableView’s datasource for automatic cached access while scrolling in the table view. It allows fast browsing of tables with thousands of elements without stressing the application server nor database server, and without requriring any pagination !
No GWT component, JSF or other provides that feature yet : they all use pagination (data splitted into multiple pages), that is less practical, less intuitive and slower to reach the desired element (if you have thousands of elements you can’t have all pages number displayed, so you have to use many times forward/fast forward buttons).

Apple dropped (sooner than expected) the NDA around iPhone development. Then exchanges, support forums and code examples should arise. Apple strategy has always been to unleash the iPhone potential step by step (at first there was HTML + javascript development only, then Cocoa but with NDA, etc.) The next step should be the opening of the iPhone filesystem (for now it is tied with the AppStore only). So Apple generates expectations and an interest peak each time they open something.
In the hard economic context these last days (Apple’s quote dropped 20$ down, before being up 8$), the company probably decided it was the time to use that mean, considering it will also help diverting developpers from Android. In fact Apple’s competitors still own an ADC membership, and even participate to WWDC, so the NDA wasn’t for patents concerns.

Client applications based on Cappuccino communicate with servers (remote services) through basic HTTP requests, whose message content (body) can be in various formats, either XML (the schema as to be defined, there isn’t any rule there – this is called XML-RPC) or the standardized and easy to read JSON format (isn’t XML). The message could also be wrapped in a SOAP enveloppe, but it is less frequent (because more complex to deal with) when calling webservices from a rich client (especially if the caller isn’t a Java program – wich is the case with Cappuccino, pure javascript – because we cannot then use generated Axis proxies). Then we will consider here that HTTP requests are originated from javascript client code (that is AJAX – the use of XMLHttpRequest javascript class), the only way to provide a partial refresh in the client-side page. The problem that arises is that, for security concerns, Ajax (XMLHttpRequest class) isn’t allowed to make cross-domain calls, that is the domain of the requested url must be the same as the one from the current page (this is the case at Cjed Audio Home site : news uncollapsing/collapsing is done sending an Ajax request to a php script in the same domain).

In order to circumvent this limitation, a trick has been used, that is known as JSONP (JSON with padding). The point is to dynamically add in the page (through DOM) a script element of javascript type, whose source is pointing to the service url in the other domain. In this situation the cross-domain call is allowed. As we are in an AJAX call context, the end of processing on the server side (extracting news content, doing a search, etc.) must trigger a callback function on the client-side in order for the refresh to happen (use of the result).
The second trick is to not simply return the result – in JSON or other format -, as it wouldn’t produce any result on the client side (the call originates from a script include), but to return a javascript method call instruction – in javascript – (the famous callback function), with passing the result string computed on the server side as a parameter to that callback function call (this parameter can be in JSON or XML format).
For example the result string will be myCallBackFunction( { “x”: 10, “y”: 15} ) if the process returns two integer values in JSON format. Then the interpreted result will trigger the callback javascript function on the client-side (possible from the script area), with the return result passed as a parameter to it. As for the server to know what callback function name to prepend at the start of the result string (myCallBackFunction area), we have to pass that information by adding an aditionnal request parameter to the service url.
Examples :
http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo
&output=json&callback=callBackResult&query=searchValue

http://www.flickr.com/services/rest/?method=flickr.photos.search&tags=searchTag&media=photos&machine_tag_mode=any
&format=json&api_key=ca4dd89d3dfaeaf075144c3fdec76756
&jsoncallback=CPJSONPConnectionCallbacks.callbackXX.

The name of the parameter that stores the callback function name varies depending on the JSONP service called (here callback for Yahoo and jsoncallbacl for Flickr), the same for another parameter that provides the result format (json).
We simply simulate here how the XMLHttpRequest API operates, without relying on in (because it cannot be used for security concerns)… but there is to know if it is a secure way…

Through the source code of Flickr Photo Demo Cappuccino application, we discover the CPJSONPConnection class.
It is instanciated (in the AppController class in that example) through the following Objective-J (javascript) instructions :

var request = [CPURLRequest requestWithURL:"JSONP service url"];
(this url contains a parameter that specifies the result format in the returned string, json here)
var connection = [CPJSONPConnection sendRequest: request callback: "jsoncallback" delegate: self];
(for that service, Flickr JSONP, the parameter that stores the callback method’s name is called jsoncallback)

In the CPJSONPConnection source code we discover that the CPJSONPConnectionCallbacks.callbackXX value is used as for the callback name (that is the value passed to the jsoncallback request parameter – that parameter name is an instance variable of the CPJSONPConnection class). This value is defined as a javascript function (stored in a javascript callback functions array) that contains the following Objective-J (javascript) code :
[_delegate connection:self didReceiveData:data];
[self removeScriptTag];

The connection: didReceiveData method is then called (when the returned javascript is interpreted from the script area) on the AppController class (defined as the delegate when using CPJSONPConnection sendRequest: callback: delegate: – we passed self). This delegate method signature is as follows :
(void)connection:(CPJSONPConnection)aConnection didReceiveData:(CPString)data
Inside that method we can directly extract informations from the returned string – data parameter – (JSON format here, that is the expected result – ie without the prepended callback method name).

If the called service url is hosted in the same domain as the current page, the previous JSONP mechanism isn’t required, and we can simply use the XMLHttpRequest class, wrapped (hidden) by the CPURLConnection class (the call is then pure classical Ajax). We specify the delegate object during the CPURLConnection instance creation, using the following method :
connectionWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate
(the passed url parameter is built the same way as previsously, creating a CPURLRequest object)
However, as here the call will finally be triggered by XMLHttpRequest (will provide the callback method name – always the same) there is no need anymore to pass the callback method name to the service through the url (that information is passed to the XMLHttpRequest class, that manages the callback triggering). So the service only returns the JSON message in the resulting string (no need to prepend the javascript callback method name, we are in a classical Ajax call context).
We only have to implement, in the delegate object (typically AppController), the following method (this name is hard-coded as the XMLHttpRequest callback name in CPURLConnection class implementation, when the later start method is called) :
-(void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data

If the returned data string is in JSON format (and we use either a CPJSONPConnection or a classical Ajax call through CPURLConnection) we can easily deserialize that string into a structured javascript object, thanks to the CPJSObjectCreateWithJSON method :
Example :
-(void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
{
var myJSObject = CPJSObjectCreateWithJSON(data);
...
}

For rich client applications, the requested business services are more likely to be hosted on other severs (and so other domains) that the client interface page, then the JSONP solution will be required.
If the server service is implemented in php, its returning string will look like this (considering the result part is in JSON format) :
<?=$_GET['jsoncallback']?>( { "greeting":"Hello from request."} )

Update : see also the CP2JavaWS Cappuccino client to Java remote services bridge, that allows easy call of remote business services, using provided proxy (client-side) and JSON servlet (server-side). It completely hides the CPJSONPConnection and CPURLConnection classes, manages encoding/decoding and namespace of services methods’s parameters and return (full objects graphs including nested heterogeneous collection elements), call of a delegate handlers for success response and fail (passing the decoded return graph), in the same way (use syntax) as GWT does (but without any generation step). Objects attributes serialization is automatic but can be redefined by implementing the CPCoding protocol in custom objects.