My ad hoc recipe for authentic Pad Thai

So… I had a mixture of ingredients for a Pad Thai and decided to use all of them.  The only ingredient of note missing from this recipe is preserved turnip; mine had spoiled! O.o  If you have some, finely chop 3 tbsp. of it and add it alongside the garlic etc.  In terms of flavour this is pretty authentic.  If you use dried sen lek noodles you will need to have them prepared and soaked for a suitable amount of time in cold water before you start.

In the ingredients below i’ve linked to some of them, it’s not an endorsement as I didn’t order mine through Raan Thai but they do stock the same brands and next time I need to order ingredients I will give them a bash; having had iffy customer service from a better known online thai foods supermarket.

Serves 3, I cooked it all in a 12″ wide flat bottomed pan (about 4″ deep). Mortar and pestle required.  Wooden spatula preferably.

  • Sesame Oil / Vegetable Oil
  • 1 Chicken Breast
  • 3 Tbsp Dried Fried Garlic or Fresh
  • 3 Tbsp Dried Fried Red Onion (Shallot)
  • 6 Spring Onions
  • 100g of Bean Curd (Tofu).  I used Japanese silken tofu as I like the texture and flakyness.
  • 3 Eggs
  • 300g Rice Noodles (I used Amoy Straight to Wok but you really should use proper Sen Lek rice noodles)
  • Palm Sugar lump (Photo) (1.5 tbsp.)
  • 4 Tbsp Nam Pla
  • 1 1/2 Tsp flaked dried chilli
  • Tamarind Pulp
  • 6 Tbsp. Dried Shrimp
  • 100g Bean Sprouts
  • 1 Lemon
  • 1 Lime
  • 6 Tbsp. Peanuts (Roasted, salted ones are OK)
  • Coriander


Cut the chicken into small pieces and set aside. Put 4 sliced spring onions, the garlic & dried onion into a small bowl.  Cut about a 1 to 2 cm wide strip off of your block of tamarid and place in another small bowl with about twice as much warm water as tamarind.  Push and pulp this around with a spoon to start it breaking down.  When that’s separated out and the water is a suitably muddy brown take out the remaining tamarind pulp and discard, to this water add the Nam Pla and palm sugar (mine was a solid disk which dissolved slowly in the pan).

In the mortar and pestle pulverise the dried shrimp as much as you can, and tip into a small bowl.  Then do grind the peanuts into pieces but leave them in the mortar and pestle.

  1. Put the pan on a high heat with your oil, I used a mixture of sesame oil and vegetable 50/50.  When the oil is hot add the chicken and tofu and stir until cooked, the tofu will almost completely break down.  If you are using fresh garlic finely chop it and add it to the pan and brown it off before adding the chicken and tofu.
  2. Tip the bowl containing the spring onion, garlic and dried onion into the pan.  Stir through thoroughly.
  3. Now add the tamarind water, Nam Pla and palm sugar.  Stir through thoroughly and if necessary prod at the palm sugar to break it down.
  4. Turn down the heat a bit.
  5. Add in the noodles and stir to combine completely with the existing ingredients.  If you’re lazy like me and used the straight to wok kind just continue on with the recipe.  If not follow the guidelines for your noodles to ensure they’ll be cooked by the time you finish.
  6. Move the noodles off to the side of a pan and one at a time crack your eggs into the pan.  Each time mixing quickly and thoroughly into the ingredients.
  7. Tip in most of the bean sprouts and all of the dried shrimp. Squeeze in the juice of the lemon.  Combine thoroughly.
  8. Add in most of the peanuts, as much roughly chopped coriander as you wish and combine thoroughly.  I used a handful of coriander.
  9. If cooked through serve onto 3 plates.
  10. Sprinkle each portion with the remaining chopped spring onion, peanuts and bean sprouts.  Decorate with a bit of coriander and serve with a wedge of lime on the side.
Posted in Cooking | Tagged , , | Leave a comment

Good to see Metroid Prime Trilogy on the Wii U

Thanks to a post by Lewie P over on Savy Gamer I found these save files which help greatly with unlocking some content on these old games now the systems that supported it are long gone. So if anyone else is unsure about how to get these save games to work this is what I discovered worked for me. As an aside I was running low on space, and had to install the trilogy to a USB Hard Disk. The game wouldn’t boot and eventually restarted my Wii U. I managed to move some games off the main storage area onto the USB and then move Metroid Prime Trilogy onto the main storage. Worked fine then. So here’s how to get the save game onto the Wii U, assuming you’ve never played Metroid Prime Trilogy via the disk and already have save data.

  1. Start metroid prime and go so far as creating save data and selecting a mii.
  2. Quit and launch the wii menu, copy the save data to SD card.
  3. Put SD card in PC, go to private\wii\title\R3MP and backup data.bin somewhere.
  4. Copy metroid_prime_trilogy_eu.bin over as data.bin.
  5. Eject card and put back into Wii U.
  6. Delete the save game data from the Wii menu.
  7. Copy the SD Card save data back onto the Wii

Then exit Wii mode back to the main Wii U menu, launch the game and viola <sic>.

Posted in Games | Leave a comment

Pretty Reckless – Going to Hell Wallpaper

Couldn’t find a decent sized version of their album cover anywhere in a wallpaper style design, so here’s a quick’n’dirty one at 1920×1200.


The album is pretty damn fine too.

Posted in Art, Miscellany, Music | Leave a comment

CEX stock monitoring

It’s been ages since I posted anything, I’ve been playing with all sorts of stuff, like Cocos2D and SpriteKit… as well as wicked little things like this DIY Gamer kit. Maybe I’ll do some more long form ish posts soon about those. In the meantime though here’s a silly little bash script that I just put in cron:


# for i in `wget -O - -o /dev/null | grep -oE "branchId=([[:digit:]]{1,3})" - | cut -d'=' -f2`; do if [ $i -eq 100 ] then; echo "Found" ; fi ; done



for store in `wget -O - -o /dev/null $DECEPTION_VITA | grep -oE "branchId=([[:digit:]]{1,3})" - | cut -d'=' -f2`; do
if [ $store -eq $ST_ALBANS ]
echo "Vita Deception in stock St. Albans"
if [ $store -eq $WATFORD ]
echo "Vita Deception in stock Watford"
if [ $store -eq $HEMEL ]
echo "Vita Deception in stock Hemel"
# if [ $store -eq $STRATFORD ]
# then
# echo "Test confirmed, PS3 Deception in store Stratford."
# fi

for store in `wget -O - -o /dev/null $DECEPTION_PS3 | grep -oE "branchId=([[:digit:]]{1,3})" - | cut -d'=' -f2`; do
if [ $store -eq $ST_ALBANS ]
echo "PS3 Deception in stock St. Albans"
if [ $store -eq $WATFORD ]
echo "PS3 Deception in stock Watford"
if [ $store -eq $HEMEL ]
echo "PS3 Deception in stock Hemel"

It takes urls for products and store id’s then via crons MAILTO environment variable it will email me if it finds those games in stock. It’s an experiment, and the code is a bit ‘dumb’. It should really loop around URLS and store IDs but for my purposes it’s fine.

Posted in Games, Programming | Leave a comment

Using a UITextField like an ATM keypad.

A small snippet of code that uses a UITextField like an ATM keypad. E.g. You start typing in a sequence like this:

£0.00 -> £0.02 -> £0.20 -> £2.05 -> £20.50

Elsewhere define and store a reference to a NSNumberFormatter like so:

        self.en_GB = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"];
        self.paymentFormatter = [[NSNumberFormatter alloc] init];
        [self.paymentFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        [self.paymentFormatter setLocale:self.en_GB];
        [self.paymentFormatter setGeneratesDecimalNumbers:YES];        

Then as a delegate method to the UITextField:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
    NSMutableString *mutableString = [[textField text] mutableCopy];
    if ([mutableString length] == 0) {
        [mutableString setString:[self.en_GB objectForKey:NSLocaleCurrencySymbol]];
        [mutableString appendString:string];
    } else {
        if ([string length] > 0) {
            [mutableString insertString:string atIndex:range.location];
        } else {
            [mutableString deleteCharactersInRange:range];
    NSString *penceString = [[[mutableString stringByReplacingOccurrencesOfString:
                               [self.en_GB objectForKey:NSLocaleDecimalSeparator] withString:@""]
                               [self.en_GB objectForKey:NSLocaleCurrencySymbol] withString:@""]
                               [self.en_GB objectForKey:NSLocaleGroupingSeparator] withString:@""];
    self.paymentPence = [NSDecimalNumber decimalNumberWithString:penceString];
    [textField setText:[self.paymentFormatter stringFromNumber:[self.paymentPence decimalNumberByMultiplyingByPowerOf10:-2]]];
    return NO;

I want to keep the amount in pence, hence the self.paymentPence property. On the off-chance that the UK moves to the € I also use a NSLocale instance to make sure Decimal Separators, Currency Separators and Symbols are correct rather than hard coded.

Posted in Programming | Tagged , , , , | 2 Comments

Thoughts on The Secret World (Work in Progress)

Thoughts on The Secret World

Around the birth of Massively Multiplayer Online Role Playing Games (MMORPGs) there was a game called Ultima Online, an online variation of the popular Ultima series of RPGs. Ultima Online had, to this day, a unique skill system within mainstream MMOs. Although you selected a starting class or custom made one your skills and thus role in the game were never fixed. Skills improved as you used them be they magic, swordsmanship, parrying or meditation right through to trade skills such as mining and armour smithing. For some reason, which to me remains opaque, in the mainstream every MMO that followed abandoned such a system forcing you to create multiple characters should you wish to experiment. Your skill set essentially set in stone. Imagine being born a miner knowing full well you could never write a line of code or solve a crossword?
There are, of course, less well known games that use such a system but none quite as elegantly as UO did. You could lock a skill, set it only to raise or force it to decrease. Thus with careful management I could forgo my meditation and wrestling skills by marking them down and concentrate on raising my parrying skills with a foil to better protect my mage in combat.

The Secret World although not directly emulating this path also gives you free reign. You earn skill points and can invest them in whatever branch of the skill set you see fit. Thus respeccing (is that shorthand for re-specialising?) is a matter of inputting the time to earn the skill points. As a departure from the UO method you thus don’t lose skills, you simply can’t take advantage of them without the requisite item equipped, say a shotgun or a magic ward or totem.

That’s what drew me to the game but now it is primarily Ragnar Tornquist’s excellent writing. Having cut his teeth on some of the best point and click adventure games in recent times, The Longest Journey and its sequel Dreamfall, the writing is top notch. Suprisingly by and large so is the voice acting, even if the character animation during dialogue is somewhat off.

This coupled with quests liberally scattered around the games areas rarely leaves you feeling bored, though you will find yourself rapidly outclassed even doing the side quests. On that note it’s worth talking about the quests and their associated cut scenes.

The game uses a completely silent protagonist, a raised eyebrow is about as expressive as your avatar becomes in these scenes. After the bountiful dialogue used in Star Wars the Old Republic this is initially jarring but some self conscious nods in the game lead to acceptance of this odd fact by and large. Is my sword wielding chaos magic avatar a mute?

The quests are pretty much of the standard MMO variety. Escort, Kill, Retrieve, Follow, Assist etc. etc. However the presentation of these quests sells them well. Gone for the most part is plain text and following arrows to the next waypoint (although waypoints are very much present, they generally lead you to the area no the spot). In are snippets of newspapers and maps shown as handwritten notes and scrawled stained maps and photos. The main quest chain appears devoid of the more exotic puzzles, I assume only so as not to hinder progress for those that have neither the time or inclination to solve them.

It’s in the side quests for me that the game therefore shines, being optional the designers appear to have had a bloody field day. So, as an example: (SPOILERS, I’ll put this behind a cut later)


One quest wants you to track down four satellite dishes in a site and repoint them to a different satellite. You do this not by just clicking on them but entering the err azimuth/elevation data. A simple change but an important one as you need to refer to your notes if you don’t have it memorised. It is at this point things get better. The first satellite displays this:

29 21 68 6f 24 28 23 23 2c 20 63 28 23 20 5f 6f
23 20 68 24 21 29 20 24 23 3f 20 43 2b 3d 2a 28
25 20 40 2b 72 20 29 5e 78 20 24 21 79 24 20 40
28 21 20 23 24 2a 25 6e 20 21 2a 67 23 29 23 2e
20 21 63 21 28 23 73 20 74 2b 24 20 25 5e 26 40
20 6f 2a 20 24 69 2b 40 2e 20 46 5f 24 2a 21 79
2d 28 5e 75 29 20 21 65 61 23 2b 23 20 5e 26 5e
76 21 20 21 68 5f 25 20 2a 20 21 28 40 23 79 2c
20 62 40 25 20 2a 20 63 24 69 29 40 20 28 2b 20
69 40 20 5e 2a 20 23 28 65 20 5e 2a 26 21 65 20
2b 7e 20 21 65 21 5f 24 21 20 48 25 2a 40 20 6d
2a 20 5f 6f 3d 24 40 21

The second this:

83 33 61 42 108 97 35 35 44 32 33 40 110 32
95 61 35 32 64 101 33 41 32 109 35 63 32 64
104 61 42 40 100 32 102 43 37 32 41 94 40 32
100 33 42 36 32 97 40 33 32 115 101 42 37 35
32 110 105 36 35 41 35 46 32 65 41 33 40 35 61
32 64 104 36 32 37 94 38 115 32 33 42 32 36 94
114 64 46 32 64 95 117 114 33 42 45 40 94 40
114 32 98 38 42 35 43 35 32 94 38 94 64 101
32 33 64 97 37 32 42 32 99 40 64 114 94 44 32
42 117 37 32 42 32 33 36 37 110 64 32 40 111
32 36 64 32 94 110 32 35 40 36 32 104 42 38
33 42 32 43 102 32 33 42 97 95 36 33 32 40 37
42 100 32 36 42 32 119 33 61 36 64 33

The third this:


and the fourth:

00101001 00100001 00111101 00101010 01101100
00101000 00100011 01110011 00101100 00100000
00100001 00101000 00100011 00100000 01111001
00111101 00100011 00100000 01000000 00100100
01100001 00101001 00100000 00100100 01100101
00111111 00100000 01000000 00101011 00111101
01110011 01100101 00100101 00100000 01000000
01101111 00100101 00100000 00101001 01101001
00101000 00100000 00100100 01100001 00101010
00100100 00100000 01000000 00101000 01100100
00100000 00100011 00100100 00101010 01100101
00100011 00100000 00100001 00101010 00100100
00100011 01110100 01110011 00101110 00100000
00100001 00101001 01110010 01101111 00100011
00111101 00100000 01000000 00101011 00100100
00100000 01110000 01101001 00100110 01000000
00100000 00100001 00101010 00100000 01100110
01011110 00101011 01000000 00101110 00100000
01000000 01011111 00100100 00101010 01110100
00101010 00101101 00100001 01101111 00101000
00101001 00100000 00100001
00100110 00101010 01110011 00101011 00100011
00100000 01100011 01110010 01011110 01000000
00100001 00100000 00100001 01000000 01011111
01110100 00100000 00101010 00100000 00101100
00100000 00101010 01000000 00100101 00100000
01001001 00100000 00100001 00100100 00100101
00101001 01000000 00100000 01110100 00101011
00100000 00100100 01110100 00100000 01011110
00101010 00100000 00100011 01101000 00100100
00100000 01011110 00101010 00100110 01110011
00101010 00100000 01101111 01111110 00100000
00100001 00101010 00100001 01011111 01101000
00100001 00100000 00101000 01100101 00101010
01000000 00100000 00100100 00101010 00100000
01011111 00100001 00111101 01100100 01000000

As a programmer this quest seemed tailor made for me. They are all ASCII. The first is displayed as Hex, the second the base-10, the third is Base64 encoded and the fourth is pure binary (essentially the same as 1 and 2. 1 is Base16, 2 is Base10 and 4 is Base2).

Decoding these and putting them underneath each other gives, with a few line breaks for clarity:

)!ho$(##, c(# _o# h$!) $#? C+=*(% @+r )^x $!y$ @(! #$*%n !*g#)#. !c!(#s
S!=*la##, !(n _=# @e!) m#? @h=*(d f+% )^( d!*$ a(! se*%# ni$#)#. A)!(#=
)c=*$(r#, !a# _=u @$!r $#? @+a*(% @+% s^( $!*s @n! #$v%# !*$h)#. !)!(s=
)!=*l(#s, !(# y=# @$a) $e? @+=se% @o% )i( $a*$ @(d #$*e# !*$#ts. !)ro#=

t+$ %^&@ o* $i+@. F_$*!y-(^u) !ea#+# ^&^v! !h_% * !(@#y, b@% * c$i)@ (+
@h$ %^&s !* $^r@. @_ur!*-(^(r b&*#+# ^&^@e !@a% * c(@r^, *u% * !$%n@ (o
@+e %^t@ !f $^+e. @o$*!*-f^() !&*#ts ^&a@! w@_% I !a@#^, *@t * !l%)g (+
@+$ pi&@ !* f^+@. @_$*t*-!o() !&*s+# cr^@! !@_t *      , *@% I !$%)@ t+

i@ ^* #(e ^*&!e +~ !e!_$! H%*@ m* _o=$@!
$@ ^n #($ h*&!* +f !*a_$! (%*d $* w!=$@!
$@ i* t($ ^ou!* +~ d*!t$! (%e@ $y _!r$s!
$t ^* #h$ ^*&s* o~ !*!_h! (e*@ $* _!=d@!

Reading down each column and picking only a valid letter from each gives you this:

Scholars, can you hear me? Chased for six days and seven nights. Across
the pits of fire. Fourty-four beasts crave what I carry, but I cling to it
in the house of death! Heed my words!

Instructions, heed the words indeed. Travel across the pits of fire (a huge burning scar opened up in the egyptian desert outside a town) and follow it north to a tomb. In there against the pillar is a body clutching a box, the pin to unlock it is 6744.


End of spoilers. It's not the only example of this in the game but it's by far the most complicated I've encountered and in fact I quit out of the game to solve it, not having ready access to base64 and other command line tools and not wanting to use the in game web browser for fear of spoilers. This sets me thinking, why has no other online game done this? Sadly within the TSW comes the solution. The chat is commonly flooded with "I can't be bothered." and "What's the password for the doctors computer?" (a simple enough clue about the four seasons, vivaldi). Oh well.

In other news, the combat is initially solid but unenspiring with no real feel of 'connection' with your attacks. A common problem in such games and certainly not unique to TSW. However as you progress the range of skills becomes broader and the limitation of only having 6 active and 6 passive skills can lead to some judicious skill set building working out what of your array of skills will let you chain attacks to the most effect or perform efficient crowd control should the need arise.

This, coupled with underlying artifice on which the game is built (that every conspiracy theory is true) is why I love The Secret World. It really does deserve more subscribers, sadly it's not the most immediately fulfilling MMO. Either way, I'll be there as I have no monthly fees in the game. What I do need to find is a guild; those dungeons are calling me and without a group I would die screaming.

P.S. Free three day trial here, clicky you know you want to.

Posted in Games | Tagged , , , , | Leave a comment

Wow it’s been sometime huh? Here’s a brief rundown…

It’s all been rather hectic. Lots has been happening and unhappening. The most obvious being that the box that runs this website went a bit mental as the hard disks succumbed to age; and I’ve been too busy to fix it until this rather wet and dull bank holiday.

Anyway it’s more alive now than it has been. However because I’m a muppet I lost the website. I have a very very old copy but it’s gonna take me sometime to massage it back to life. I suspect I’ll start from scratch. In fact I know I’ll start from scratch!

In other news I’ve been playing a lot of The Secret World and been having a nose around Guild Wars 2 this morning. All looks good there. I bought a K90 Corsair keyboard, which was gorgeous until it stopped working OK. Thankfully Overclockers and Corsair rock and a new one is in the post as I type this. Should arrive tomorrow at work.

On the subject of work that’s been going really well… everyones cool and rather supportive; even when I’m doing stuff I don’t quite understand (re: PHP/Zend/Security/Forms/Payment Systems etc.).

All the PHP coding at work however has given me the impetus to revisit my own Objective-C code. I’ve spend the last week polishing my own scrobbling app which may not ever see the light of day in the app store. It does what I want, it’s very minimal and it does musicbrainz lookups to supplement the data when rejects the scrobble. Normally because it falls foul of a fubared filter, as Alanis Morissette’s “Incomplete” track did a few months ago. The downside is background notifications of song plays appear to be limited to three, so the only two ways to have it as a background app are:

– Hacks
– Check play counts on tracks and scrobble plays that have occurred in the backgrounded period (iffy but I’m looking into it)
– Integrate a music player into the app itself. Not keen on this idea and have no idea how much other processing I can do with the app running like that.

My idea to have my Delicious Library database on my iPhone has reached fruition. This is a piece of software that will definitely never be released. Mostly because I’m not allowed, though I do have permission for it on a personal learning basis. It’s actually a project I started doing whilst learning to code for iOS but quickly got back burnered when I’d learnt what I needed from it and moved onto Chef’s Book as a project that could see the light of day. I’ve still got some Core Data wizardry to do so I can search it etc. That should hopefully stop me buying books/cds/games and movies I already own when I’m out shopping!

As for Chef’s Book I have the compound predicates needed for recipe searching working. They need spit and polish and need to have a bit more natural language processing put in. Either by removing words such as and/or/with or actually processing them into their respective meanings and modifying the search accordingly.

I’ve taken lots of photos but haven’t yet punted them up to Flickr.

I took a step I’ve been thinking of taking for several years, I shut down my Facebook account. It feels good, although it would appear that many people missed the posting where I said “Hey I’m shutting down my account, you’ve got my number please call me if you want to chat”. Essentially I’d rather speak to my friends and meet them for a coffee once in a while than exchange banalities electronically!

Also there’s less photos in my face of things I don’t care about or wish to see! }:-)

What else? Not a lot. I keep a proper hand written daily journal now, having finally found a pen I can write with that doesn’t cause muscle cramps/carpal tunnel whatever the hell is wrong with my hands to flare up. I’m still going to the gym twice a week. Errr… I’m single. Again, but there’s a nice lady I talk to once a week about that crap. **grin**

I might post the odd journal type entry here now. Seeing as I can excerpt them from my diary. My pre-daily journal diary has now become my personal to-do list appointment diary, the paper that Moleskine use is crap with fountain pens compare to these lovely creations Paper Blanks. These particularly are nice Paper Blanks Mucha but too small for journal needs so I don’t know what I’m going to use them for. This is the one I’m using for journal stuff Scott Fitzgerald The Great Gatsby Ultra. The papers nice and thick and they look lovely. I’d hunted and hunted for the Mucha ones, trying to find somewhere that had them in stock. Just because I like Mucha. They are a lot more gold in person than they look in photos on the web. Having ordered them online I found that the Waterstones in St. Albans has a tonne of them in stock upstairs. They also have a decent enough selection of the much larger ones, as does Smiths in Hemel Hempstead (upstairs).

Posted in Art, Chef's Book, Computer, Cooking, Drawing, Exercise, Games, Literature, Miscellany, Music, Photography, Programming | Tagged , , , , , , , | Leave a comment

Diablo 3 – Launch Day Blues

21:20 – Diziet Embless Sma: Meh.. let’s put it this way dude. You’re simply playing a slightly different version of Diablo 3.
21:21 – Diziet Embless Sma: Last night I made Level 10 at Error 37, and Level 3 at Error 12. Today I’ve got level 50 Entering Password and Level 45 Retrieving Character List.
21:21 – Diziet Embless Sma: You made Level 7 Can’t Fucking Install.

Posted in Games | 1 Comment

Backing up Steam with CWRsync

This may or may not be of use to other people, and seeing as I’ve not written a blog post for ages, I thought I’d post it here. Before demolishing my PC last year and building a new one once I found myself gainfully employed once again I was working on something to back up Steam (and indeed image my PC). I never got the hang of using windows ghost copies from batch scripts to image the windows drive out but I did come up with a bash script to copy steam off to a USB or eSATA drive:



REM ** CUSTOMIZE ** Specify where to find rsync and related files (C:\CWRSYNC)
SET CWRSYNCHOME="D:\Program Files (x86)\cwRsync"

REM Set CYGWIN variable to 'nontsec'. That makes sure that permissions
REM on your windows machine are not updated as a side effect of cygwin
REM operations.
SET CYGWIN=nontsec

REM Set HOME variable to your windows home directory. That makes sure
REM that ssh command creates known_hosts in a directory you have access.

REM Make cwRsync home as a part of system PATH to find required DLLs

REM rsync
REM -r recursive
REM -v verbose
REM -P progress
REM -k transform hard link to dir on dest.
REM -L transform symlink to dir on dest.
REM -u update, probably a winblows timestamp fix to stop it copying every file every time.
sc stop MsMpSvc
taskkill /f /im msmpeng.exe
REM rsync --delete -rvuP --exclude='Google' -exclude='Temporary Internet Files' --exclude='Local Low' --exclude='Backup' --exclude='Temp' --exclude='*Cache*' /cygdrive/c/Users /cygdrive/h/
rsync -rvukPL --exclude='httpcache' --exclude='htmlcache' --exclude='overlayhtmlcache' /cygdrive/d/Games/Steam /cygdrive/g/Games/PC/
sc start MsMpSvc

Hopefully it’s of use to someone. If you’re not comfortable with the sc stops and taskkill commands then get rid of them, I just found (especially when copying the windows users directory) that it interfered and made the rsync slow to a crawl).

In other news there’s err not a lot. If there was I’d post it here. 😛

Actually that’s not true. I’ve written tonnes and tonnes of code over the last six months some of which I’d love to post but never seemed to get around to it. I’ll try and post more some. Some of things I’ve been wrestling with have been:

– Clustering Algorithms for geo location data.
– MKMapKit with transparent overlays and mad exc_bad_access errors buried deep within Map Kit/iOS. Which are mostly solved, but it still crashes occassionally even with only 1 overlay. Notably on zooming out.
– OpenGL ES, briefly last week. I’m hoping to do more fun coding in this area and have even asked my nephew to design a game. That should be amusing. 😀 It will be very very weird.
– Last.fms API, I want a basic no frills scrobbling app for the iPhone that lets me use the including It turns out it’s non trivial.

There will definitely be a post on the latter. NSNotifications from the music app are particularly interesting when your app is in the background. They go missing and there’s not hard and fast rule it would appear on how long they are kept for or under what conditions they are dropped. A rule of thumb would appear to be that you receive about 3 track change notifications and that’s it. So you can’t receive information for a whole album with the app backgrounded. Whilst tackling this supposedly obvious ‘why the hell hasn’t anyone done this already?’ app I’ve realised why the apps that are out there either:

– Don’t work.
– Use a built in player.
– Build horrible caches of your play history each time (iScrobble I’m looking at you).

Sadly the latter was particularly good when it worked but now appears to not receive updates and recent changes to iOS have rendered it useless. I can only assume because it caches it’s data in a directory that is now cleared out by the OS.

On the Chef’s Book count I’ve been wanting to sneak the time in to polish off the recipe search and update the graphics and UI. It just never seems to happen. :( I’ll do it, I just don’t know when.

Posted in Games, Programming | Tagged , , , , , , | Leave a comment

Progress with adding iCloud to Chef’s Book.

There are some interesting challenges with incorporating iCloud support, especially into an existing application. One, which I’ve been working through, is that you can no longer copy in a pre-existing store for the purposes of loading data. Such a move appears to work but does not upload anything to the cloud, the cloud store will only see future changes and not have the initial data set.
The solution to this is to use NSPersistentStoreCordinator’s migratePersistentStore:toURL:options:withType:error method. However I found the documentation somewhat lacking in clarity so here is the solution that now appears to be working for me.

There are some things I wanted to guarantee, which are probably not applicable to many so I’ll document them here:

– The application has gone through a few object model changes and I wanted to support people that may have skipped versions.
– The application’s data store location has changed on one occasion, when I moved the store out of Documents and into the Library directory due to adding iTunes document sharing.

Before we look at the code we’ll have a look at a rough outline of the procedure, in handy bullet points, step is 4 is the one that took some figuring out:

  1. Run everything following this asynchronously.
  2. Determine location of any existing stores, if not default to initial data set.
  3. Check to see if application supports iCloud, e.g. is running iOS 5.
  4. Configure store options if it does support iCloud.
  5. Lock the persistent store coordinator.
  6. If there is a cloud data set already, simply add it.
  7. If there isn’t DON’T add it, the migrate function adds it.
  8. Unlock persistent store coordinator.
  9. Send messages out so that view controllers that need to can redo their fetches.

A few caveats about the following, it’s not tested aside from ensuring it does migrate data into the store. I’ve not yet verified that the data then careers across the cloud to another device but I’ll update the post as soon as I do.

The code isn’t optimal, but that should be obvious! 😉 The method should be called where in your code you’d normally add the store. A lot of the framework, minus the migrations stuff, is based on some example iCloud code.
Also note that the if block with the “//Migrate old store to new AND migrate into cloud” comment is devoid of code. In that block I would need to update the old store to match the new one and THEN migrate the store as I’m using my own migrations code which also allows importing of new data and a few other tweaks, which I think I’ve previously blogged.

CLOUD_NAME,STORE_NAME are #defines. DLog is a #define macro to NSLog that is blank in production environments.

- (void)aSynchronouslyAddPersistentStore {
  NSString *cloudPath = [[self applicationLibraryDirectory] stringByAppendingPathComponent:CLOUD_NAME];
  NSString *preCloudPath = [[self applicationLibraryDirectory] stringByAppendingPathComponent:STORE_NAME];
  NSString *defaultStorePath = [[NSBundle mainBundle] 
                                pathForResource:@"InitialData" ofType:@"sqlite"];
  NSString *oldStorePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:STORE_NAME];
  // do this asynchronously since if this is the first time this particular device is syncing with preexisting
  // iCloud content it may take a long long time to download
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *storeUrl = [NSURL fileURLWithPath:cloudPath];
    NSURL *migrateUrl = nil;
     Find out which store has the data we need to migrate,
     if any.
    if (![fileManager fileExistsAtPath:cloudPath]) {
      if ([fileManager fileExistsAtPath:preCloudPath]) {
        // Migrate old application data.
        migrateUrl = [NSURL fileURLWithPath:preCloudPath];
      } else if ([fileManager fileExistsAtPath:oldStorePath]) {
        // Migrate old store to new AND migrate into cloud.
      } else if ([fileManager fileExistsAtPath:defaultStorePath]) {
        // Migrate (copy) in initial recipe data set.
        migrateUrl = [NSURL fileURLWithPath:defaultStorePath];

    // this needs to match the entitlements and provisioning profile
    NSURL *cloudURL = nil;
    if([fileManager respondsToSelector:@selector(URLForUbiquityContainerIdentifier:)])
      cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
      NSString* coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:@"chefsbook_v14b3"];
      cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];
      DLog(@"cloudURL : %@", cloudURL);
    //  The API to turn on Core Data iCloud support here.
    NSDictionary *options = nil;
    if (cloudURL) {
      options = [NSDictionary dictionaryWithObjectsAndKeys:
                 @"com.thelostsouls.chefsbook", NSPersistentStoreUbiquitousContentNameKey, 
                 cloudURL, NSPersistentStoreUbiquitousContentURLKey, 
                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption
    NSError *error = nil;
    [persistentStoreCoordinator_ lock];
    DLog(@"Persistent Store ****LOCKED****");
     If I migrate url is set don't just add, migrate!
     Otherwise proceed as planned.
    if (migrateUrl) {
      NSPersistentStore *srcPS = [persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType
      if (![persistentStoreCoordinator_ migratePersistentStore:srcPS
                                                         error:&error]) {
        DLog(@"Error migrating data: %@, %@", error, [error userInfo]);
      if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType 
                                                             error:&error]) {
        DLog(@"Error adding persistent store: %@, %@", error, [error userInfo]);
    [persistentStoreCoordinator_ unlock];
    DLog(@"Persistent Store ****UNLOCKED****");
    // tell the UI on the main thread we finally added the store and then
    // post a custom notification to make your views do whatever they need to such as tell their
    // NSFetchedResultsController to -performFetch again now there is a real store
    dispatch_async(dispatch_get_main_queue(), ^{
      DLog(@"asynchronously added persistent store!");
      [[NSNotificationCenter defaultCenter] 
       object:self userInfo:nil];


So there you go.

Still a worry are scenarios where iCloud support is enabled/disabled and/or the data deleted from the cloud via the settings menu. Hopefully nobody would do that and leave iCloud enabled or they’d end up with an empty application and no recovery. That’s also the reason I’m still supporting and improving the code that saves the docs out to iTunes.

Another thought just occurred to me. The following scenario needs serious consideration:

  1. User starts app with iCloud support, initial data set loaded.
  2. User proceeds to add a handful of data.
  3. User installs Chef’s Book on second device with iCloud enabled for app.
  4. App starts and copies in default data PLUS receiving iCloud data.

Will it fail, magically know it’s the same (eminently probable), or duplicate data?

Time to find out!


Well I found out, it hangs permanently. Thanks to some helpful people on the apple forums I know why. So the above code is only partially correct. What needs to be done is to also query data on the cloud using NSMetadataQuery and examine the results, if there is cloud data you should use that and not add a persistent store in the normal way (I guess?). What I now need to find out, having successfully been able to query the cloud and find LOTS of data on there from my previous tests, is how you should add that data.

Then I’m going to rewrite the entire core data start up code from the bottom up.

Posted in Chef's Book, Programming | Tagged , , , , , , | 15 Comments