Closure; the missing piece


White jigsaw puzzleWhile doing a code review this week, the developer asked me if we could refactor some TypeScript. Basically take some repetitive client side code, pop it into a new file and make it easier to implement elsewhere.  The project is using the powerful DevExpress ASPxGridView control in a lot of places (multiple controls on a page and multiple pages) and in batch edit mode. The users wanted the ‘Save / Cancel’ panel to be at the top of the screen instead of the default location in the grid footer. Simple enough process, we can create a user control to handle a couple of nicely themed ASPxButtons, link to a helper class for the common work on the grid and we should be done.

First we take a look at the original markup, the client side client event is being wired to a TypeScript method


Inside the TypeScript file, the method was doing some checks and calling another method on the grid control, gvTemplates.UpdateEdit(); This is where the repetition was, each grid had its own ‘save’ method.

helper.saveGrid = function ( ) {
        gvTemplates.UpdateEdit();
}

In order to optimise the code, we have to pass in the name of the grid being edited, then find the grid in the DOM and execute the method on it.

The first part was to update the markup to call to the helper class


The key difference here is the introduction of the brackets into the assignment, we are no longer just pointing the click event to our TypeScript method, but actually executing it, which is bad. This is where the closure comes in. For more information about closures I suggest you read the following article from Julian Bucknall.

For our needs, the code should look something like this

helper.saveGrid = function (gridId: string) {
        return function (s, e) {
            var grid: ASPxClientGridView = ASPxClientControl.GetControlCollection().GetByName(gridId);
               grid.UpdateEdit();
      }
}

The ‘gridId’ parameter is going to contain the grid’s client side ID, the saveGrid() method then returns a function that is passed back to the click event handler on the button. There are a few cool things going on with the new code. Firstly (and this is where you can come unstuck very quickly) is the use of the parameter that is passed in. The inner function can use the value from the outer function. The second thing to note is the nice helper class provided by DevExpress to get access to the control, so you don’t need to go searching through the DOM. Code cleaned, duplication removed and a much nicer way to handle calls from multiple controls and/or pages.

While this serves as a very quick tutorial on being able to call common methods, I really want to highlight a) the power of the closure, b) the frustration they can cause to JavaScript / TypeScript beginners.

For more detailed information on closures and best practices please see these fantastic articles:

Caught out with closures

The module pattern

Ode to 2017


2017 Just Ahead Green Road Sign Against Clouds

A year so filled with ups and downs, tears and laughter too, 2016 you’ve tried and tested me, I’m glad you’re almost through.

2017, you’re nearly here, but yet, I claim you now, to be the year of goals and dreams, the fattened calf or cow.

The year of reconciliation, be it race, religion, creed, the year we learn to give, and put away our greed.

Let’s learn religious tolerance, offer all a helping hand, let’s share the blessings of our land, so rich with golden sands.

Families, start afresh, put yesterday aside, our forefathers never wanted this, they’d be turning in their grave.

If each of us could do one thing, different to the norm, pay it forward, help someone, a new world could be born.

To those I’ve hurt or wronged, I ask, your forgiveness and you grace. My heart just breaks for all of the human race.

2017.  The year we take back.

Life. Love. Dream. Achieve. Believe.

Go forth with love.

Bad Apple! The real cost of two factor auth


There are so many other words I wanted to put there, most of them unprintable. But right now I’m really pissed off with Apple. I’m an advocate for keeping things safe, I’m a fan of two factor authentication. But as far as I’m concerned Apple have it wrong, desperately wrong.

Currently there is a lot of press around on whether Apple should release information to the FBI (or at least provide access to devices), this is not a rant about the rights or wrongs of that. It’s personal, much more personal.

2013 I had been using an Apple account associated with my main email address, with two factor auth set up. Due to a series of unfortunate events I lost access to the device. I knew the password but no phone (it was only trusted device at the time), in short I lost ability to use that account, it was frustrating, $00’s of software, music and movies had been purchased but none available anymore, primarily because I had not written down the recovery key which was the only other way to reset the account. Accepting that it was my own stupidity that had caused the loss I set up a new account and started from fresh. Again choosing two factor auth but this time carefully recording the number in my trusty Evernote file. Two and a half years later, $000’s of dollars of software, music and movies later (example here FCP is $500 alone) and I need to reset the account. Following all the prompts I was a little shocked to see ‘Your recovery key is not valid’. Double checking everything I tried a few more times, each attempt met with the same warning. To be clear, the recovery key wasn’t written down, the actual Apple screen was captured, there was no chance of error there. The date and time stamp on the Evernote entry matched within 1 minute of the email received that day from Apple advising two factor auth had been activated.

So I was becoming agitated with this and decided to call Apple. One hour ten minutes later and we were no further forward. I’d been escalated a number of times, technicians had me repeat all the same steps all with the same result. It looks like I have to start everything again. Unbelievable.

I use two factor auth on a lot of accounts, and feel secure, be it a text message or an authentication app, I’ve never had a problem. Apple however have gone out of their way to complicate this whole process.

I feel that strongly about this, I’m seriously considering removing all Apple products/software from my life!

Should it be this difficult to get access to things you’ve paid for?

 

 

A refreshing change…


Happy New Year everyone, some people are still in 2014 while this is being composed, but hour by hour each part of the world will join the wonder that will be 2015.

I was checking my email this morning and came across a note from the CEO of SmartSheet. They produce an amazing tool for business collaboration, powerful spreadsheet functionality, gantt charts along with a raft of cool tools.

LetterFromMark

What struck me with this letter was the fact that Mark was upfront, no sugar coating, just told it as it was, they had problems, took action and resolved it. The approach to tell their customers exactly what went down I feel was something other CEO’s should take on board. I hate not knowing what went wrong when tech doesn’t work, worse I hate being lied to and hoodwinked. There are so many services we are dependant on these days, glitches are going to occur. Of course I’m likely to be upset when it does, but I’ll get over it. It goes a long way to keeping my custom when letters like the one above are sent though.

The other thing that I noticed is the phrase … “Your passion and commentary exhibited on social, email, and via phone” – how often do we vent on Twitter or other social media outlets when something is wrong, and it got me wondering how healthy or fair that really is for a business. In the case above there was a problem, but a quick look at some accounts and you can see individuals ranting and publicly ridiculing products when in fact the issue was their lack of understanding or knowledge on how to do something.

Well, kudos to Mark for the letter and I hope as we usher in 2015 more companies will be transparent when dealing with the masses.

HAPPY NEW YEAR !

iPhone 6 -> 3 weeks in


Over the years I have always enjoyed getting my hands on the latest gadgets, and my time as an Apple developer has been no different, as soon as a phone was announced I’d want to be among the first to get it.  This year Apple announced that it would release to multiple countries on the same day, so being in Australia would mean we would be one of the first in the world!!

The pre-order site went live at 5:30pm local time on Friday September 12 and my order was completed within minutes….  let the wait begin.

At 8:30am on Friday September 19, the courier knocked on the door delivering my coveted device. My first thoughts on removing the wrapping … what a dull box, the rather nondescript plain white with slightly raised outline was a little disappointing, next the unboxing itself…

I must say that I felt a little underwhelmed when I first took hold of the phone, it felt, well, wrong. After a short wait for my backup to be transferred I was able to start playing.  There is no dispute that the form factor is amazing, thin and feels nice, I’m just not a fan of the size. All of a sudden I’m using too hands or doing crazy thumb stretches to reach different parts of the screen. I knew a quick double tap on the home button would bring screens down to make this easier, but there are so many issues trying to do this I found it simply not worth it.

Three weeks on and I’m still getting used to the phone, I don’t think I could go back to an iPhone 5s, though its still a little awkward if not frustrating dealing with thumb stretches. A friend of mine decided to go with the 6 Plus, I’m pleased I didn’t, it just seems uncomfortable, we jokingly call it the iPad mini mini. One annoyance and I’m not yet sure if it is an iOS 8 issue or the phone, is the lack of rotation support (read: BUG), many apps (including Apple ones) do not respond to the phone being rotated, I have to go back to the home screen then back again, weird!

What has been really quite fun to play with writing code that takes advantage of the new sizing API’s in iOS8 but thats a post for another day. In the meantime I’m watching eagerly for the release date of the Apple Watch 🙂

Azure, iOS and enterprise deployment


If you want to deploy an iOS application provisioned under an enterprise license on an IIS box the steps are simple enough:

– Create a folder where the .ipa file will be stored such as \inetpub\wwwroot\myApp
– Create a manifest (.plist) file, here is an example of what that should look like


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>items</key>
  <array>
    <dict>
     <key>assets</key>
      <array>
       <dict>
        <key>kind</key>
        <string>software-package</string>
        <key>url</key>
        <string>http://www.yourdomain.com/myApp/myApp.ipa</string>
       </dict>
      </array>
    <key>metadata</key>
     <dict>
      <key>bundle-identifier</key>
      <string>com.yourdomain.myApp</string>
      <key>bundle-version</key>
      <string>1.12.08.1200</string>
      <key>kind</key>
      <string>software</string>
      <key>title</key>
      <string>myApp</string>
     </dict>
    </dict>
  </array>
</dict>
</plist>

– Next step would be to create a link in your web page that points to the manifest file you just created, notice it is a special type of scheme:

...
<a href="itms-services://?action=download-manifest&url=http://www.yourdomain.com/myApp/myApp.plist"> Tap Here to Install myApp</a>
...

Now if you tried to click on the link at this stage you would start receiving errors. So the next thing to do is add a couple of extensions into your MIME types

.ipa – application/octet-stream
.plist – text/xml

Done, you can now browse to the page on your iPhone/iPad/iPod and install your newly provisioned enterprise application.

WHAT ABOUT AZURE? I did mention Azure in the title of the post, so what’s different if you want to deploy via a Azure Website?

Technically, nothing is different, you still need the manifest file, and you still need to set up the href. The caveat here is that you cannot edit MIME Types in your Azure admin area.

Thankfully it is not a difficult thing to overcome. You can add your MIME Type directly to the web.config file

...
<system.webServer>
    <staticContent>
      <mimeMap fileExtension=".ipa" mimeType="application/octet-stream" /> 
      <mimeMap fileExtension=".plist" mimeType="text/xml" /> 
    </staticContent>   
</system.webServer>  
...

Now your enterprise application can be distributed using the power of Azure Websites 🙂

NSInternalInconsistencyException – reason: ‘Could not load NIB in bundle’


Is it ambiguous ? Well at the outset it seems to be.

After a swag of updates (iOS 6, Xcode, OSX 10.8.2 ::modem has officially asked for time off now::) I opened an existing client project that was working previously. This project was used during a prototyping session with the client, so why does it break now ?

The error:
2012-09-21 07:42:07.257 Stenhouse Workshop[3017:c07] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Could not load NIB in bundle: ‘NSBundle /Users/paulusher 1/Library/Application Support/iPhone Simulator/6.0/Applications/B1F4C9E9-EAB6-4AD8-96D6-D82EDD9E6E48/Stenhouse Workshop.app (loaded)’ with name ‘WorksheetViewController”
*** First throw call stack:
(0x1c99012 0x10d6e7e 0x1c98deb 0x239fac 0xfee37 0xff418 0xff648 0xff882 0x10b235 0x30a3d2 0x1084f3 0x108777 0x96d933f 0x1087b7 0x25ee 0x10ea705 0x21920 0x218b8 0xe2671 0xe2bcf 0xe1d38 0x5133f 0x51552 0x2f3aa 0x20cf8 0x1bf4df9 0x1bf4ad0 0x1c0ebf5 0x1c0e962 0x1c3fbb6 0x1c3ef44 0x1c3ee1b 0x1bf37e3 0x1bf3668 0x1e65c 0x1e7d 0x1da5)
libc++abi.dylib: terminate called throwing an exception

Googling this type of thing will send you on a wild goose chase, the NSInternalConsistancyException seems to cover a lot of ground.

Because of the number of upgrades that had taken place I decided to start by doing a ‘clean’ on the project,when that failed, reseting the content on the iOS Simulator, still nothing, (insert head banging here). I checked all the connections, made sure no objects had been removed leaving bad things behind. There were some ‘warnings’ on the project, pointing at deprecated color options on my grids. So dutifully, I changed the selection to something that was current, did another clean and build but the app still crashed.

I then noticed the smallest difference, the NIB name was “WorksheetViewController” and the code was calling “WorkSheetViewController”. It seems the issue of the Simulator correcting these behind the scenes has been fixed (see the note here on Simulator black magic)

After a quick alteration of the NIB name the project was useable again. So while technically it was not anything specific to the OS changes that broke the project, it was changes in Xcode and the Simulator. Of course the app would have crashed on the device anyway, so at least we were spared that pain.

What would have been nice to see was an error message something like- reason: ‘Could not load NIB in bundle: NIB File Not Found’.