Got a number but no name? Facebook will tell you!

There’s been a bit of news about Facebook’s new (or at least newly publicised) Contacts feature. The gist of it is that when installing the mobile app, you can have it sync your phone contacts with Facebook. That way, all your contacts are available on Facebook, and you also get Facebook friends’ phone numbers on your phone.

But what I haven’t seen mentioned, and what I noticed today, was that in my Contacts on Facebook, there were a whole lot of random people’s names and photos. With an Add Friend button.

Who are these people?

Most of them were French. I used to live in France. I moved there nearly five years ago. I was only there for a year, as a teaching assistant. A lot of my friends there were also doing the same. And we all had mobiles. And we don’t any more. That was over four years ago. And numbers get recycled.

So now I have names, photos and telephone numbers of strange people in France, because Facebook is making the assumption that if I have a phone number in my phone, and someone else has the same phone number in their Facebook profile, I might know them. It’s not the case, and it’s downright creepy. Some of these people don’t even have public profiles. Yet Facebook has sent me to their profile.

It’s not difficult to put a specific phone number (or a whole series of numbers) into my contacts, sync with Facebook, and then have the names, photos and any other public information Facebook has on whoever has that number. A nefarious individual would have a field day. They could call somebody, ask for them by name, know where they work and who their friends are. Children could also be put in danger.

This is either a major bug, or it just hasn’t been thought through properly. Just because I have a phone number doesn’t mean I know who they are. And it definitely doesn’t mean Facebook should tell me.

Where are the home and end keys on a Chromebook?

I’m writing to you on my shiny new Samsung Series 5 Chromebook, which I was sent by Google after the Google I/O conference in San Francisco earlier this year. It doesn’t have a normal keyboad. Which is somewhat annoying, as it’s missing several keys.

So, for your reference, here are the key combinations for some of the missing keys:

Home
Ctrl+Alt+Up
End
Ctrl+Alt+Down
Page Up
Alt+Up
Page Down
Alt+Down
Delete
Alt+Backspace

I originally found this information over at chromeoslounge.com.

Other key combinations like Ctrl+W to close and Alt+Tab to switch windows also seem to work. I assume that the same key combinations that apply to the Linux version of Chrome would apply to Chromebooks.

As an aside, I’m not sure how these keystrokes are recognised in JavaScript. If I can be bothered I will investigate and report back. I’ll probably forget, though.

Also annoying is that it has a British keyboard, which I am not that used to any more, after working on iOS development a fair bit recently, and on my NZ-bought ThinkPad, as well. Wonder if I can switch layouts?

The OVH Kimsufi Ubuntu kernel doesn’t support NFS

That is kind of annoying.

I am going to follow the instructions from http://neuro.me.uk/2009/09/20/revert-to-standard-ubuntu-kernel-on-ovh-or-kimsufi-servers/ later this weekend, and get back to a standard kernel. Or next week.

So if the server goes does down, that’s why!

Update: Not happening this weekend! Too much work to do.

Update 2: Did it. It works. No problems there.

Odd bug with inheritance and Objective C synthesized properties (with solution)

This is a weird one.

I have a class. And it has a subclass.

I kept getting error: 'psc' undeclared (first use in this function).

Strangely, it would only occur when compiling for the device. The simulator was fine. psc is an ivar of the superclass.

I did a bit of research and found the word @synthesize. I noticed that none of my other subclasses of that same class synthesized anything. I removed the synthesize statement. And it compiled. I put the synthesize statement back in, but this time with the backing ivar explicitly declared.

And it still worked.

I am not sure what the problem is, but this fixed it.

APIs and dates

Time for a rant. If you are building an API, whether it is for public consumption or not, you should make sure you communicate dates in an unambiguous way.

You should always be able to figure out the exact time, regardless of time zone or daylight saving. The best way is to just use UTC. Or, if you can’t/won’t do that, you should include the time zone every time you mention a date. If you don’t, then you’re going to run into trouble when daylight saving ends, because you end up with the hour that precedes the changeover, and the hour that follows it, being the same. And that causes problems.

You should also not rely on date offsets from the current date, because your clients cannot be guaranteed to have an accurate time. So if you have an offset of 0 in your data that means “today” but your clients’ clocks are off, then they might think the data belongs as part of yesterday. Or tomorrow. And that is annoying.

Offsets from a particular point in time are fine though. And I don’t mind what epoch/reference date you choose. As long as it’s consistent.

APIs, in my opinion, are meant for computer-to-computer communication. They shouldn’t handle prettifying dates, for example. So you should pick the right tool for the job.

That is all.

Facebook asking you to rate Places

I just noticed this, not sure if it’s new or part of their A/B testing. They’ve got a box on the right hand side asking which of two places I have previously checked into was better.

It looks like Facebook are trying to gather information about places so they can provide recommendations, much like foursquare’s Explore tab.

Have any of you noticed this on Facebook? Answer in the comments or on Twitter @arunstephens.

Core Data not returning a custom concrete class

Ever had a problem when you’re fetching something from an NSManagedObjectContext, and you’ve set a concrete class in your model, only to find that it is an NSManagedObject? Me too.

I read this post at StackOverflow, which suggested that you have to create the subclass using Xcode, from within the modeler. OK, I thought. I’ll try that.

I deleted my old .h and .m files. I went into the modeler. I created a new Managed Object class. And put my custom code back in.

And it didn’t work!

But never fear. I did a Clean, and it worked.

Temporary NSManagedObjectIDs

I’ve run into a problem where I insert a managed object into a managed object context, in a separate thread, and then return the object ID to the main thread and then retrieve the object from the main thread’s context using that ID.

It didn’t always work. It is because I saved the first managed object context after I took the object ID. And the object ID was temporary because the object hadn’t been persisted. And the temporary object ID became invalid after the context was saved.

It didn’t always happen because my code will either insert or update when doing the JSON deserialisation. So if the object already existed in my persistent store, it would retrieve a proper object ID.

So the moral of the story is that you should always save your managed object context before getting the newly inserted object’s ID.

binding not implemented for this SQLType 7: Core Data and iPhone OS 3

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'binding not implemented for this SQLType 7'

That’s not something you want to read. And it doesn’t make much sense. And there’s not a lot out there on that problem, either.

I am adding Core Data to Zoopcast (the people-powered local search app). The first few releases just took data from the JSON web service, and put it into unmanaged objects. (As it turns out, I probably should have gone with Core Data from day one. Despite what the docs say, it’s not that difficult. In fact, probably easier than what I was doing.)

I read that SQLType 7 is the REAL storage class in SQLite. And that storage class can handle different types of data. And I thought to myself… perhaps I am putting floats instead of doubles, somewhere in my code (which is permitted in C, and my managed objects have NSNumber properties anyway) and it’s that mapping that is getting the Core Data/SQLite layer confused.

So I had a look.

The NSDictionaries that were being decoded from JSON with JSON Framework had NSNumber objects that were NSDecimal (one of the private subclasses of NSNumber). I’m not sure if they were all NSDecimal, but they probably were: they’re stored as double precision floating point numbers in the service, and obviously have to be rounded for JSON transport, so decimal makes the most sense.

So I thought… why not force these to all be doubles, like so:

double doubleValue = [(NSNumber *)value doubleValue];
value = [NSNumber numberWithDouble:doubleValue];

And guess what? It fixed it.

This wasn’t a problem on iOS 4. It was only a problem on an iPod touch first generation running iPhone OS 3.1.3. But it’s not longer a problem for me.

It was this post on Stack Overflow that lead me on the right track, and Brian King’s answer actually makes perfect sense to me now that I’ve re-read it after figuring it for myself and explaining it in long form.

Azure Full IIS: RoleEntryPoint runs in different process to web app

I just found this one out thanks to this post from the Azure team.

Basically, I was configuring Table Storage (as you may have guessed, if you’ve read my other posts today), and using the CloudStorageAccount.FromConfigurationSetting(string) method. As you are probably aware (if you are aware of this sort of stuff), to be able to use that method, you must first set a function that tells Cloud Storage how to figure out how to get configuration settings. You do that with the CloudStorageAccount.SetConfigurationSettingPublisher(Action> configurationSettingPublisher) method. I knew that.

So I put it in my WebRole class, which inherits from RoleEntryPoint. That was fine. Code within my WebRole.OnStart method that used Table Storage was fine.

But when some of my other code, inside the web app, tried to access Table Storage, I got the exception saying I hadn’t called SetConfigurationSettingPublisher. It turns out that with Full IIS in Azure (which is the default if you create a project using the SDK version 1.3), the RoleEntryPoint runs in a different process (WaIISHost.exe, apparently) and my app runs under w3wp.exe.

And this exact problem is mentioned in that blog article, under the heading “Accessing Static Members from RoleEntryPoint and your web site”.

As annoying as this is, I’m kind of glad I figured out the problem (it all comes down to search keywords) in such a short amount of time!