Archived entries for General

Cocoa error 1671

Last week, I came across quite a serious bug in one of our iOS apps: all application data was lost when the app was quit. This is what happened:

Our app used Core Data to store things to disk, making these persist across app runs. Realising no data was available when the app started for the second time, I had a look at our saving routine:

NSError *error = nil;
BOOL saved = [managedObjectContext save:&error];
if (!saved || error) {
    NSLog(@"Failed to save: %@", error);
}

Nothing out of the ordinary. A break point tells that this code is run, the console shows no error, all good.

Having read this post, I now know to poke a little deeper in a case like this, but I hadn’t. So I wandered though the app for a while, until I finally returned here and put a break point on the line:

NSLog(@"Failed to save: %@", error);

Surprise: it breaks. Turns out our trusty NSLog silently fails to log this error! From here on, things start to roll:

(lldb) po error
(NSError *) $1 = 0x0882eec0 [no Objective-C description available]

Hm, that might be related..

(lldb) p (int)[error code]
(int) $5 = 1671
(lldb) po [error domain]
(id) $6 = 0x00b7655c NSCocoaErrorDomain
(lldb) po [error localizedDescription]
(id) $7 = 0x0d628730 The operation couldn’t be completed. (Cocoa error 1671.)

Google (and Bing) tell me: No results found for “Cocoa error 1671″. While 1671 has been used as a number before, there is absolutely nothing to be found in relation to iOS, Cocoa, or Apple. But wait, let’s try:

(lldb) po [error userInfo]
(id) $8 = 0x0882f080 {
    NSLocalizedDescription = "The operation couldn\U2019t be completed. (Cocoa error 1671.)";
    NSValidationErrorKey = firstLetter;
    NSValidationErrorObject = "<NSManagedObject: 0x882c030> (entity: Person;
        id: 0x882c080 <x-coredata:///Person/t41AD32DB-D331-4A65-A964-FB0B4359BAAA2> ;
        data: {\n firstLetter = \"\\Ud83c\";\n})";
    NSValidationErrorValue = "\Ud83c";
}

Et voila. What all printers failed to show me, the NSDictionary description was able to escape for \U2019readability\U2019 purposes. With great success: “\Ud83c” is not a valid string. A quick search on www.unicode.org/charts tells me I’ve been bitten by something out of the High Surrogate Area.

Isolated surrogate code points have no interpretation; consequently, no character code charts or names lists are provided for this range.

My bad. To determine the fist letter of a person’s name, I naively used:

NSString *firstLetter = [fullName substringToIndex:1];

And NSString isn’t really strict when it comes to the more exotic characters of the Supplementary Multilingual Plane, like emojis. These characters are represented by two 16 bit characters, which makes using substring and character methods a lot less obvious. Apple does warn about this in its documentation:

If you need to access string objects character by character, you must understand the Unicode character encoding, specifically issues related to composed character sequences.

Yes Apple, I’ll read it tomorrow, promise. Anyway, the Characters and Grapheme Clusters article from the iOS String programming Guide provides a valuable introduction, leading me to the proper implementation:

NSString *firstLetter = [fullName substringWithRange:
    [fullName rangeOfComposedCharacterSequenceAtIndex:0]];

All of a sudden everything starts working. Core Data stores first letter “\Ud83c\Udf3″, NSLog logs again, lldb debugs again, ttgtb.

Unicode is great fun, don’t miss out on it! Read some on Wikipedia, for example Supplementary Multilingual Plane. Knowing just a few fundamentals will save you lots of time, especially when people start using the iPhone’s Emoji keyboard. And the second lesson learned: do not trust NSLog.

Who’s name did cause all this trouble in the first place? http://en.wikipedia.org/wiki/%F0%9F%8C%B5.

Leonard van Driel
iOS developer at Noodlewerk

Meet the Makers: Growing pains

Noodlewerk and Innovattic organize another Meet the Makers. See below for more infomation:

In the 3rd edition of Meet the Makers: Growing pains two important people from larger companies (100-150 people) will talk about their growth: from startup to mature company.

Wednesday, April 4, 2012, 7:00 PM at Grand Cafe SPING, Nieuwe Plantage 58, Delft (map)

Please RSVP at Meetup.com to attend. We have limited space available.
Entrance is free and drinks are on the house.

We thank Sping to make this event possible.

Mendix
Abstract: hundreds of successful deliveries, one hundred employees, six years, one vision.
Interesting note: Mendix recently raised 13 million dollar.
Speaker: Johan den Haan, CTO of Mendix

Nimbuzz
Nimbuzz combines the powers of the Internet and mobile communications into one, and lets you make calls, send messages and share files, on any mobile device, for free. Nimbuzz is very popular in the East has got 80 million users.

Speaker: Evert-Jaap Lugt, CEO of Nimbuzz

Appsterdam Delft

2011 for Noodlewerk

Looking back at 2011, we are very proud. We expanded the team and got some talented new developers and designers. We made dozens of new iPhone, iPad and Android apps. We gave a design talk at the BNO in Amsterdam, we started Appsterdam Delft together with Innovattic, we did a tech talk at a Cocoa Heads meeting and presented our work at other various events.

This year was the year of the iPad. One of the highlights is “Money and Speed”, one of the iPad apps we made with the VPRO, which has won the Dutch Design Award in Eindhoven.

We made iPad versions of Uitzending Gemist, Radio apps and Z@ppelin for the Publieke Omroep (NPO). Digidentity will release a really nice iPad app for digitally signing documents and Raet has now an iPad version for their Netto app.

Another surprise was that we were nominated for being the developer of the year and our app Uitzending Gemist was nominated for best app of the year at the onemorething Awards 2011.

In 2011 we got the chance to work with companies like Consumentenbond, Raet, Digidentity, Troostwijk, Greenwheels and the Good and Green Guides. Not only did we make new mobile apps for those companies. We continued making apps for the NPO, VPRO and Parkmobile. And of course we should not forget the Android versions we made of Uitzending Gemist, Luisterpaal, Film it Yourself, Radio apps, Parkmobile and Park-line which all came out this year.

We will keep on developing and designing the best apps possible for all the great services our clients provide!

The Noodlewerk Team

Tutorial: Using Charles proxy to debug HTTP(S) communication between server and iOS apps

Abstract

In all the apps we have developed so far, we have witnessed the use of tightly coupled communication between the iOS app on the device and a remote web service. For example, an app might request a JSON encoded list of popular items from the web server that is displayed to the user in a nice table. No matter how much time is spent on defining and specifying communication protocol, during development (and sometimes even during production) there are moments when there are problems with these app vs. server interactions.

Especially when these problems occur on the device or during production, it can be hard to trace the problem without the proper tools. Using a good proxy all communication between app and server can be monitored, which makes tracing these issues much easier. In our tutorial we’ll focus on HTTP and HTTPS traffic only and we will be using the Charles proxy, which is available for Mac, Windows and Linux/UNIX. Knowledge on the HTTP protocol is expected.

Intercepting HTTP traffic

Install Charles. There is a free trial, but costs $50 if you want to get rid of the nagging splash screen. Launch the app. It will immediately prompt you to ask for permission to configure the necessary network settings. This is needed in order for Charles to intercept network traffic. Choose “Grant Privileges” for the easy route.

By default, it will start recording HTTP traffic immediately, so you’ll see the table get filled with calls e.g. if you are browsing the web on your computer. You can try that for a start, for example by visiting google.com like I did here. On first start, the “Structure” tab will be selected. The Structure tab shows an expandable tree of hosts and paths that have been requested and intercepted during this Charles session. If you expand a visited hostname (e.g. www.google.com), you’ll get subpaths that have been visited, etc.

The other view is the “Sequence” view. Instead of presenting requests by hostname and path, it shows requests ordered by time. Personally, I usually use this view most of the times. If you select a request, you will get all the details for that request in the pane below the list of all requests (I selected a request to Twitter’s search.twitter.com in the next screen shot). Basically, the Request and the Response sections present the request sent by the app and the response received from the server.

On the bottom of the details viewer, there are some options that depend on what section of the details you are in. For example, in the Request section, you can view the Request’s Query String (previous screen shot) or the Request Headers (next screen shot).

One of the nice features of Charles is that is able to detect a few commonly used container formats, like JSON and XML, probably based on the Content-Type response header. For example in the case the response contains JSON, Charles will show a “JSON” tab with a view that formats the JSON response conveniently in a more readable way instead of just displaying raw text.

Proxying traffic from an iOS device to Charles

The next step is to use Charles to inspect traffic from an actual iOS device. The easiest way to do this, is to use Charles’ built-in proxy. First you need to tell your iOS to use the proxy. Go to Settings > Wifi > Select the Wifi network and make sure your machine that is running Charles is also in this network. Scroll down to the “HTTP Proxy” setting. (See next screen shot.) Select “Manual”. Enter the IP address of your machine that is running Charles. You can find the IP address quickly in Charles’ Help > Local IP Address menu. Enter “8888″, which is the default proxy port of Charles. Authentication is off by default.

Now open up an app that uses HTTP calls to a server (e.g. browse the web in Safari). Charles will detect that a new host is trying to use its proxy. You will need to accept it once by choosing “Allow”:

Once allowed, traffic will flow from your iOS device through Charles, which will forward it to its destination (while allowing you to inspect it). In the next screen you can see what traffic the Google Maps app is causing when I’m panning over the map on my iPhone (no JSON there but many binary responses):

Intercepting SSL traffic from an iOS device using Charles

Now you might think, wait a minute, what about SSL / HTTPS traffic? What if my fancy web service is using an encrypted connection? Well, fortunately there is a pretty simple way to inspect that as well. In this contrived example, we will look into encrypted traffic from Safari to https://mobile.twitter.com/. Open up the Proxy Settings menu from Charles. Add the hostname of the HTTPS server. In our case we added “mobile.twitter.com” and the default SSL port 443:

If you try visiting https://mobile.twitter.com/ from your proxied iPhone, Safari will present you a warning that it cannot verify the server’s identity because the Charles proxy is using untrusted, self-signed certificates.

You don’t want this, because the (correct) default behaviour of iOS (and NSURLConnection for example) is to disallow untrusted server connections. The solution is to add the Charles root certificate (the certificate that is used to generate SSL certificates on-the-fly when you are using the proxy) to the list of trusted root certificates in your iOS device. To do this you need to add a configuration profile containing Charles root certificate bundle. To save everyone some time, we created a signed configuration profile with Charles’ certificate bundle  for everyone to use.

If you visit http://charles.noodlewerk.com/ using Safari on your iOS device, you will be prompted whether or not you want to install the profile and the containing bundle. Once installed, iOS will trust the Charles proxy and will act as normally. Note that in essence you are weakening the security by installing this profile. So it is wise to remove the profile once you are done debugging if you are using your device in real life :)

Appsterdam Delft

Last week’s first Appsterdam Delft meetup was a blast! Mayor Mike Lee gave a speech about the new initiative in Delft. Not only there’s a place for Appsterdam.rs in Amsterdam, but also in Delft. For everybody who doesn’t know what Appsterdam is, read here.

We start out by having the weekly Meeten & Drinken at the Cafe Belvedere at the Beestenmarkt. Sinds today, there’s an official hangout at the Sping office (SPING villa Vrijenban Hangout) who  is offering its Grand Cafe to App Makers. You can go there during the day and meet your colleagues and spend a couple of hours working beside them. SPING is providing WiFi, coffee and tea.

Appsterdam Delft will organize talks and workshops the coming months. First one will be on August 30 from 14:30 till 17:30. More info will follow.

See also Mike’s Blog post on Appsterdam Delft

This week again, there will be a Meeten & Drinken from 19:00 at Cafe Belvedere in Delft.

Pictures taken by Klaas Speller (@spllr)

SpinAwards: 2x Zilver met Film It Yourself

Gisteren zijn de jaarlijkse SpinAwards uitgedeeld voor “creativiteit in interactieve communicatie”. Daarbij is het project Film It Yourself in de prijzen gevallen, met één zilvere award voor “Beste Mobiele Concept” en één zilvere award voor “Beste Innovatie” (na “Appie” van AH). Noodlewerk heeft afgelopen zomer een substantiële bijdrage aan dit project geleverd, met de ontwikkeling van de iPhone applicatie waarmee tijdens live-concerten met meerdere iPhones tegelijk een videoregistratie gemaakt kan worden, waarbij de video opnames automatisch op-de-videoframe-nauwkeurig gesynchroniseerd worden. Via de website kunnen de concert registraties teruggekeken worden waarbij de kijker kan het concert kan (her)beleven en als een regisseur kan wisselen tussen de verschillende perspectieven van de filmers. De beelden die met de iPhones gefilmd zijn, worden daarnaast aangevuld met een professionele geluidsopname (ook automatisch gesynchroniseerd natuurlijk ;)

Het FIY project is geïnitieerd door VPRO en is een samenwerking tussen Stunst, Noodlewerk, Video dock en Martijn Pannevis.



Copyright © 2004–2009. All rights reserved.

RSS Feed. This blog is proudly powered by Wordpress and uses Modern Clix, a theme by Rodrigo Galindez.