Feb 19

What Facebook says about HTML5 mobile apps

“We’ve tried in the past to just build web apps that we could wrap in thin native wrappers, but it doesn’t work. […] Anytime somebody tries to reimplement a native widget using HTML, CSS and JavaScript it always feels like shit.” – Tom Occhino while introducing Facebook’s new React Native

It’s exactly my experience since I started developing mobile apps four years ago. Therefore, I focused on Appcelerator Titanium which does for years what Facebook tries to do now.

Nevertheless, at the moment I’m developing a BlackBerry 10 app using HTML5, and I’m quite satisfied with the outcome – but only because it’s a relatively small app that only needs to store small amounts of data on the device, and where small UI glitches are acceptable.

But in the end, there are UI glitches. Like a bar at the top that should be fixed, but scrolls with the content for a small moment before it’s being placed at the top again. Or small, subtile differences in transition animations. On the other hand, I like that I can control the UI as much as I want – since it’s only HTML that can be modified at any time using JavaScript.

So it’s as always: there is no “one solution that rules them all”. HTML5 apps are fine in several cases. But if you want to develop huge, complex apps I’m sure an approach like Titanium is the better way. And if you want to synchronize with Notes, you need to do it in Titanium anyway, so that you can use DominoToGo.


Feb 06

How to make a Quickr blog post out of a mail?

A customer has a Quickr installation where he uses a Quickr blog. Quickr supports sending mails to a place (=NSF), which the customer did setup.

Unfortunately, a mail sent to the Quickr blog NSF does not show up in the place as blog entry, it only shows up in the index as standard Quickr document.

I did a quick look at the items of a Quickr blog entry document, and added some items like c_BlogDate, c_Location and so on to the mail. Then the mail is displayed as blog entry, but without the mail’s body.

That’s because in a blog entry the content should be in the items c_BlogText1 and c_BlogText2, but in the mail the content is stored as MIME in PageBody0, PageBody1 and so on.

So before I dive deeper into that topic I ask you: do you have by any chance a ready-to-use script to solve this problem?

 


Posted in Uncategorized
Jan 29

New DominoToGo release

DominoToGo 3.3 was just released with the following improvements:

  • Limited support for BlackBerry 10: synchronisation of a Notes view and all basic functionality like DTGDatabase works. Synchronisation is not as capable as on iOS and Android regarding the amount of data and speed. Functionality regarding Notes documents have not been tested yet.
  • New (fast) synchronization option to sync changes only: see {dtg.NotesView.syncModifiedOnly} for details. In short, if your view’s last column has the programatic name $dtgIsRemoved and contains a value of “1” indicating that a view entry should be treated as ‘removed’, DTG now is able to do a real “modified only” sync while still being able to delete ‘removed’ entries in the local DTG view.
  • NotesView: a full sync now checks if the last column has the programatic name $dtgIsRemoved. If so and if that column contains “1” for an entry, this entry will not be synchronized. This is useful to mark view entries as ‘removed’ in a view and therefore ignore them in a full synchronisation but honor them in a modifiedOnly synchronisation.
  • NotesDocument: new argument localOnly in save() method to save a document as draft in the local XML representation only, without uploading to Domino.

Click here for full version history.

If you want to build an App that needs to work with Notes data, you really should have a look at DominoToGo!


Posted in Uncategorized
Jan 23

DRM is bad for the customer. And for 7 year old children.

Friday is children’s movie day in our house. Tonight my 7 year old daughter selected a movie which we have on DVD. Normally we’re watching movies via Amazon Instant Video or from a file server using Plex. Therefore I forgot.

Guess what happened when I put the DVD into the Mac Mini which is attached to the TV?

DVDPlayer started, we heared sound but there was no picture. And why? Because Apple does not allow us to watch a DVD for which we paid on a TV which is attached with a HDMI-to-DVI adapter. Because of that, the Mac Mini cannot talk to the TV and ask it if it supports all the copy protection crap. And so the Mac Mini only displays a white picture.

That’s so silly. As if this kind of measures prevents anyone of making copies from a DVD. It only punishes people like us. Families who simply want to watch a DVD.

And so my daughter cried.


Jan 20

Working with WebSQL in an HTML5 mobile app

I wrote some days ago that I now work on a BlackBerry 10 app using BlackBerry WebWorks, which is basically Apache Cordova (Phonegap).

The app needs to read data from JSON sources and store it locally, so that the app works offline. So I need local storage, and although the WebSQL specification came to an end, it’s supported in WebWorks, Chrome and other platforms.

Working with WebSQL is relatively straightforward because in the end it’s the well known SQLite in the backend. But, you have to deal with callbacks. For example, to write stuff you’re using this kind of code:

// size in bytes, for example 1024*1024*1
// params may be an array of data for the sql statement
var size = 1024*1024*1;
var db = openDatabase("mydb", '1.0', "mydb", size);
var f = function(tx) {
  tx.executeSql(sql, params, function(transaction, result) {
	// success, do something with the result
  }, function(tx, e) {
     // failure, error is in e.message
  });
};
db.transaction(f);	

So there are two callbacks, one in case of success and one in case of error. If you want to execute multiple statements at once, you can put them all into one transaction. In that case you have to do some work to handle the results and errors. Something like this:

f = function(tx) {
	var hasError = false;
	var errors = [];
	var results = [];
	_.each(sql, function(singlesql) {
		tx.executeSql(singlesql, params, function(transaction, result) {
			results.push(result);						
		}, function(tx, e) {
			// failure
			hasError = true;
			errors.push(e.message);						
		});	
	});
	// do something with the result
};

(Note: _.each() is a method of underscore.js framework.)

Unfortunately this does not work reliable. Do you spot the error?

The function iterates though an array of sql statements, and each statement is being executed and in the result callback the result of that statement is added to a result array.

But what happens if you want to use the result array right after the _.each() loop? You’re using the result array before all the callbacks from the sql statements has been executed! So it may be null or contains only some entries, but not all.

You need to work on the results only when all sql statements have been executed:

f = function(tx) {
	var hasError = false;
	var errors = [];
	var results = [];
	var len = sql.length;
	for (var i = 0; i < len; i++) {
		tx.executeSql(sql[i], params, function(transaction, result) {
			results.push(result);
			if (i == (len-1)) {
				// do something with the result HERE!
			}			
		}, function(tx, e) {
			// failure
			hasError = true;
			errors.push(e.message);						
		});	
	};
};

In a real world app that may get cumbersome when you do lot of work with WebSQL. Therefore I started to write a framework, just like I always do when things get complicated 🙂

What about this code:

b = new JBUDatabase("mydb");
// create table if it does not exist yet
db.createTable("tickets", [ {
	name : 'id',
	type : 'TEXT'
}, {
	name : 'title',
	type : 'TEXT'
} ]);
// create a demo array of data for 100 tickets
var data = [];
for (var i = 1; i < 100; i++) {
	data.push(["ID "+i,"ticket title "+i])
}
// write the data to the WebSQL database
db.writeEntries("tickets", data);

All the WebSQL stuff packaged in a simple to use API. Much more clear, isn't it?


Jan 14

News about BlackBerry 10 development

Some weeks ago I wrote about my efforts do build a BlackBerry 10 app with DominoToGo and Titanium.

I made progress with the app since then. I can synchronize data from IBM Domino using DominoToGo, I can display the data in views and forms. So is everything good?

Unfortunately: no.

During the work on this Titanium based BlackBerry 10 app I discovered several features that were unstable, and I discovered a lot of Titanium features that are simply not implemented for BlackBerry 10. Furthermore, there is no word from Appcelerator that they will continue to support BlackBerry 10 (although there is no word against that, too).

In the end, working on that app felt more and more like riding a dead horse. So my customer and I made a decision: move away from Titanium for this BlackBerry 10 app (while staying with Titanium for another complex, iOS based app).

It’s a tough decision since time is pressing. But what’s an app without future and with potential stability problems good for?

Now I’m re-implementing the app with BlackBerry WebWorks, which is an enhanced Apache Cordova (Phonegap) version for BlackBerry. So basically I’m developing HTML5 now.

One bad thing about mobile development with HTML5 is how to style the app so that it looks and feels like a native app. Yes, there are apps where users accept that they look different, but in most cases users like it when the app looks and feels the way they know.

I looked at Sencha, Dojo mobile, jQuery mobile etc. But for BlackBerry, they all didn’t convinced me. The solution seems to be bbUI.js. That framework not only does a good job in providing UI controls, but delivers an easy to use screen architecture, too. Each screen is simply an HTML file with a special DIV as root element.

Furthermore, each screen can use it’s own JavaScript resources. That way, I can separate UI from logic similar to Titanium’s model-view-controller architecture.

In addition I’m using underscore.js, Backbone.js and the core of jQuery.

I still don’t like Cordova’s way of using callbacks in callbacks in callbacks in callbacks. It’s hard to write clean, readable code when you’re forced to deal with so many callbacks. I understand why they chose this architecture, nevertheless, using too many callbacks lead to code that’s hard to understand.

The good part is that I can re-use much code I already wrote in Titanium, so it’s not a start from the beginning. And so far the performance on an old Z10 device is surprisingly good.


Dec 10

XPages HTML5 MultiFile Upload With Drag and Drop

Year ago I published a HTML5 Multi File Upload Control on openntf, now I extended it with drag & drop capability. And after doing some research, it was suprisingly easy.

First you need the custom control, download it here from openntf.

Then you need to add a div as target for dropping files:

Drop files here

Add some CSS to make the div pretty.

Finally you need to add this CSJS to the end of the custom control:




In the drop event we get the list of files dropped onto the div from the dataTransfer object, and we can put this list of file objects to the ynUploader_worker function which is already defined in the custom control.

I tested this in Chrome, Firefox and IE11 and – what a pleasant suprise – it works in all of them, even in IE.


Dec 09

That was hard. Problems with BlackBerry deployment fixed by changing “ü” against “u”.

I fought with this issue for a week: when trying to deploy a BlackBerry 10 app to a device, I got this error:

result::failure 500 ‘ascii’ codec can’t decode byte 0xc3 in position 111: ordinal not in range(128)

I posted the issue in the developer forum, asked fellow developers and asked for help in this blog, with no results. Every day I thought about the problem and tried new approaches, without any luck. Today I finally found a way to submit a ticket to a BlackBerry issue tracker, and shortly after en engineer responded. After some exchange of comments and files the issue was found: I used an umlaut in the author name in the debug token’s certificate. The author was set to “Ingenieurbüro Julian Buss”, and the “ü” was the problem. After I changed the author name to “Julian Buss” and recreated the debug token, the deployment ran without any problem.

In my last comment in the issue I suggested to improve the error message in this case. It’s really hard to believe that this issue slipped through quality assurance.

Nevertheless, now I’m able to test my Titanium and DominoToGo BlackBerry app on the device and so far it runs fine!


Dec 05

Making a “immedidate” ft index really immediate – please try this notes.ini variable

Yesterday I wrote about problems with the “immediate” update frequency of a ft index. I didn’t found any way to make the indexer faster.

A collegue from IBM told me to try this notes.ini setting on the Domino server:

UPDATE_SUPPRESSION_TIME=-1

Which should set the interval when the indexer looks for work to one second. Sounds wonderful in theory, but on two 9.01 servers I tested this setting does not do anything.

If you have a Domino server at your hands where you can test things, can you please set UPDATE_SUPPRESSION_TIME=-1 to the server’s notes.ini and check if the ft index of a database with the update frequency “immediate” is updated faster than usual?

Thanks!

 


Dec 05

Anyone with BlackBerry 10 / Momentics IDE experience out there? I cannot deploy a project to a device.

So far my experiences with BlackBerry 10 development is quite mixed. I managed to work around most issues when creating a Blackberry app with Titanium, but now I want to deploy the app to a test device, a BlackBerry Z 10.

And it simply does not work. The process always breaks with a quite cryptic message:

Error in final launch sequence
Cannot prepare and download the binary
result::failure 500 ‘ascii’ codec can’t decode byte 0xc3 in position 111: ordinal not in range(128)

It’s the same when I try to create a blank “Hello World” project in BlackBerry’s native development environment, the Momentics IDE. Here is what I did:

  • downloaded and installed Momentics
  • downloaded and installed API level 10.2 (target device is a Z10)
  • created a new BlackBerry app in Momentics from the most basic “Hello World” template
  • ran deploymend wizard, installed debug token on device
  • device is connected via USB, Momentics shows me a green light for USB
  • clicked “Run”

And again the same error is reported and the app is not deployed on the device. The app does work in the simulator, though.

I learned that such kind of message can occur when one tries to deploy a project compiled for the simulator (x86) to the device (arm). So I looked everywhere to make sure that the project was compiled for arm, and indeed all settings in Momentics are set to arm and not x86.

So far I tried these steps on three different computers, one Windows 7 machine and two Macs. It’s always the same.

I posted the issue to the BlackBerry developer forum, without any useful response so far. Anyone who is doing BlackBerry development and experienced similar issues?