Category Archives: software-development

Asynchronous Data Calls in Windows Store Apps

Below is the way that I’ve written my (MVVM, C#, XAML) Windows store app to make asynchronous data calls. This is necessary so that the UI doesn’t lock up while some network action or request is being performed.

Make a function that gets your data synchronously. This makes it simpler to write, read, and test.

public string GetUsername() 
{ 
    var url = new Uri(API_URL_BASE); 
    var client = new HttpClient() { BaseAddress = url }; 
    var response = client.GetAsync(url).Result; 
    response.EnsureSuccessStatusCode(); 
    return response.Content.ReadAsStringAsync().Result; 
}

Then, in the function where I want to make the call, I create a task to run the function asynchronously, and set up a Completed handler. Use ThreadPool.RunAsync to run it asynchronously. I have a function called RunOnComplete(Action) that helps me invoke any actions on the UI thread when the task is complete. This helps when I’m updating some data that’s going show on the UI.

private string username;
public string Username 
{ 
    get 
    { 
        return username; 
    } 
    set 
    { 
        username = value; 
        RaisePropertyChanged("Username"); 
    } 
}

// Assume this gets called from a command bound to a button, for example
public void UpdateUsername() 
{ 
    var task = ThreadPool.RunAsync(t => 
    { 
        // set the private property to prevent raising property changed, which has to be done on the UI thread
        username = GetUsername(); 
    }); 
    task.Completed = RunOnComplete(RefreshUI); 
} 

public void RefreshUI() 
{
    // set the public property to private one which raises property changed and triggers the UI to update
    Username = username;   
}

public AsyncActionCompletedHandler RunOnComplete(Action method) 
{ 
    return new AsyncActionCompletedHandler((IAsyncAction source, AsyncStatus status) => 
    { 
        DispatcherHelper.CheckBeginInvokeOnUI(() => { method(); }); 
    }); 
} 

I mention the reference to DispatchHelper in this post.

Alarming

This past weekend I got an email from a team member saying that there was an event that occurred at a customer facility which should have triggered an alarm in a system that we wrote, but didn’t. Shortly after, I got an email from our project manager informing me that this error has most likely caused a very large amount of fines for the customer. Trigger minor panic attack.

The two of them (both higher than me on the chain and closer with the customer) had other emails and calls with the customer over the weekend regarding the issue, but the general plan was that we’d analyze it and develop a plan forward on Monday.

We ended up coming out of the situation pretty well, despite the circumstances, partly because of good fortune, but partly because we handled the situation well. I give kudos to my team member and PM for their handling of it. First thing first, we did a root cause analysis. We looked at all available logs and database records until we found the broken link (or didn’t find one, more accurately), then recreated the events as they were described to have occurred, and then recreated the data flow.

We found the root cause, which, by my PM’s judgement, and with the agreement of the customer, was a specific scenario that would have taken a very long time to find in testing, if at all. Additionally, the system behaved according to spec, but the spec didn’t reveal the possibility of this scenario. After this, it was determined that about half of the fines incurred were the result of operator error and that our system performed correctly for the events related.

After we found the root cause, my PM also discussed the procedural issues resulting in this situation. The communication of the completion and testing status was not clear between us and the customer and there was no sign off to decommission the old system and start using the new one for this mission critical functionality. In summary, we found a technical shortcoming with the system, and some procedural missteps. We communicated all of this to the customer and began development to fix the shortcomings.

All in all, I definitely learned a lot about dealing with major problems at a customer site, and the handling of them, in addition to lessons about communication, signing off on mission critical system releases, and testing.

Uploading a Photo as Multipart Form Data in C#

I recently posted about adding a feature to a Windows 8 app I’m working on wherein the user can select a photo from their pictures library. After they select the photo, I need to upload it to the API I’m using in order to post the picture. The API specifies:

POST /api/media [multipart] AUTHENTICATED

Multipart POST parameters:
  • caption — The caption text.
  • media — The file body itself.

This means that I need to perform an (authenticated) multipart form POST to their API with the image body as a parameter called “media” and an optional caption for the image. However, there were a few issues that I ran into: 1. One missing specification and 2. An issue with default naming of HTTPContent added to a MultipartFormDataContent object in C#.

First, I had to build up the MultipartFormDataContent, assuming that photoContents is a Stream from the file chosen by the user.

var uri = new Uri(API_URL_MEDIA);
var content = new MultipartFormDataContent();
content.Add(new StringContent(caption), "\"caption\"");
var t = new StreamContent(photoContents);
t.Headers.ContentType
    = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
fileName = string.IsNullOrEmpty(fileName) ? "\"img.png\"" : fileName;
content.Add(t, "\"media\"", "\"" + fileName + "\"");
var response = PostBuffer(uri, content);
response.EnsureSuccessStatusCode();

If you notice that I explicitly add (escaped) quotation marks to the names of the content objects I’m adding to the MultipartFormDataContent. This was the second from above. When I didn’t explicitly add the quotation marks, the request generated had a ContentDisposition like this (from Fiddler):

Content-Disposition: form-data; name=media; filename=picture.jpg

versus:

Content-Disposition: form-data; name="media"; filename="picture.jpg"

I’m not sure if this is a standard or not. I was able to find that the quotations around the boundary parameter of Multipart request are optional according to my test, but required if the boundary starts with two dashes. I couldn’t find an RFC reference supporting that the quotes around the boundary are optional. The quotes around the parameter’s names may or may not be optional. In any case, when I added them to my request, it succeeded.

As a side note, the “filename” attribute you see was necessary for the request to succeed in the API I’m using, but was not specified in the documentation. This was the first issue above.

In the snippet above, I call PostBuffer(uri, content) which is a helper function to most the MultipartFormDataContent. Here’s what it does, to post the content:

var baseAddress = new Uri(API_URL_BASE);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    // some defaults, add a header and cookie for authenticating with the API
    client.DefaultRequestHeaders.Add("User-Agent", USER_AGENT);
    client.DefaultRequestHeaders.Add("X-AvoSig", AvoSignature);
    cookieContainer.Add(baseAddress, new Cookie(COOKIE_NAME, CookieValue));
    // Post the content and return the result
    var response = client.PostAsync(uri, content);
    return response.Result;
}

Choosing a photo from the Photos library in Windows 8

I’m working on a Windows 8/RT app, and one of the pieces of functionality I needed was the ability for users to select a photo from their library and upload it (more on the uploading here). I wanted to use the built in Windows 8 photo picker (a specific type of file picker) built around the Modern style.  My app is built with the MVVM pattern, using a few different helper libraries, so I had to jump through a couple hoops in order to do it, but it wasn’t too difficult. Here’s the gist, but there was one gotcha.

// Create an OpenFilePicker starting in the pictures library, viewing thumbnails
var filePicker = new FileOpenPicker();
filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
filePicker.ViewMode = PickerViewMode.Thumbnail;

// Filter to include a sample subset of file types
filePicker.FileTypeFilter.Clear();
filePicker.FileTypeFilter.Add(".bmp");
filePicker.FileTypeFilter.Add(".png");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".jpg");
// Open a stream for the selected file
StorageFile file = await filePicker.PickSingleFileAsync();

// Ensure a file was selected
if (file == null)
{
    // Get a stream of the file – I’ll use this for uploading
    var stream = await file.OpenStreamForReadAsync();
}

The gotcha was that this code is happening in a function of my viewmodel (invoked from a button command), so it’s not running on the UI thread. If you try to use the OpenFilePicker outside of the UI thread, it will fail. In order to solve this, I moved this code to its own function PickPhoto and invoked it on the UI thread:

public void AddPhoto()
{
    DispatcherHelper.CheckBeginInvokeOnUI(() => { PickPhoto(); });
}

This Dispatch Helper is definitely a big help! It’s included as a part of the MetroMVVM project which is based off the old MVVMToolkit project. Then what you get is the Modern file picker:

Authenticating an HTTP Request with Client Certificates in iOS

I’m writing an app that uses a client-certificate to authenticate while performing a SOAP request. Unfortunately, I’m writing this app in PhoneGap, and the iOS WebView does not support Client Certificates for AJAX requests. I found some various sources of code and examples for doing this, but it took quite a bit of work to get the final result, so I wanted to post my code and explain how I made it work. I wrote this as a PhoneGap plugin, so I can call the method from javascript, and have the result returned (via a callback function) in the normal PhoneGap plugin style, but I suppose this could be used for any client-certificate authenticated request in a native iOS app. Here’s the important code:

The options object contains my url (host) and my soap request (an xml string data)

NSURL *serverURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@", [options objectForKey:@"host"]]];
NSMutableURLRequest *connectionRequest = [NSMutableURLRequest requestWithURL:serverURL

[connectionRequest setHTTPMethod:@"POST"];
[connectionRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
[connectionRequest setHTTPBody:[[options objectForKey:@"data"] dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection * aConnection = [[NSURLConnection alloc] initWithRequest:connectionRequest delegate:self];

Then I have NSURLConnection Delegate Methods to receive the response. One in particular, didReceiveAuthenticationChallenge is where I handle the client-certificate.

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    // gets a certificate from local resources
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"MyCertificate" ofType:@"pfx"];
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
    CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
    SecIdentityRef identity;

    // extract the ideneity from the certificate
    [self extractIdentity :inPKCS12Data :&identity];

    SecCertificateRef certificate = NULL;
    SecIdentityCopyCertificate (identity, &certificate);

    const void *certs[] = {certificate};
    CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);

    // create a credential from the certificate and ideneity, then reply to the challenge with the credential
    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];
    [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}

Then, We need extractIdentity to pull the identity out of a certificate

- (OSStatus)extractIdentity:(CFDataRef)inP12Data :(SecIdentityRef*)identity {
    OSStatus securityError = errSecSuccess;

    CFStringRef password = CFSTR("MyCertificatePassword");
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };

    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    securityError = SecPKCS12Import(inP12Data, options, &items);

    if (securityError == 0) {
        CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
        *identity = (SecIdentityRef)tempIdentity;
    }

    if (options) {
        CFRelease(options);
    }

    return securityError;
}

Blam! That was the hardest part. From there, just use your other NSURLConnection delegate methods to handle the connection states and events. See my full code below for examples.

SecureRequest.m

Creating an Enterprise App Catalog

Motive

One of the challenges faced with developing in-house (or “enterprise”) mobile applications is deployment. For public applications, deployment is handled almost exclusively through platform app stores, like the iOS App Store or the Google Play Store. Deploying apps to employees of a single company, without making use of those stores, is a difficult problem. Android apps can be deployed just by making the apk available, but browsing, versioning and updating is still a problem.

Many companies solve this problem through the use of a Mobile Device Management (MDM) server that includes app catalog or deployment capabilities. Good Mobile Manager and AirWatch are both popular and (according to Gartner) leading platforms for MDM. My company tried out AirWatch, but ultimately decided that it was a bit too buggy and high maintenance, without much benefit.

Without going too much off topic, here’s a brief overview of what AirWatch was, and wasn’t, for us. MDM servers often provide the ability to remotely encrypt and wipe devices, install or uninstall enterprise apps, enforce usage and security policies, and other things. AirWatch did none of these things well, and some didn’t work at all due to platform limitations *AHEM*android*AHEM*. What we really needed was a way for employees to have access to our in-house developed applications. We already had some security control via our exchange server and it’s policies, and we could enforce other levels of security through the apps themselves (i.e., verifying that the device is encrypted, or has a passcode set).

Idea

I designed, proposed, and implemented a custom enterprise app catalog for my company to solve this problem. This app catalog would meet our greatest need by enabling users to download our in-house applications. It also provides us with some statistical information through basic analytics (a combination of Google Analytics and my own user-agent tracking). It also provides us with security of downloads, by authenticating users and download requests against active directory. It does not provide any remote installation/updating/uninstallation, nor any remote wiping capabilities. Some of the other features include:

  • Automatic PLIST generation for iOS over-the-air installation
  • Token based authentication for iOS over-the-air installation (which doesn’t support authentication cookies)
  • Role based app availability (beta testers, for example)
  • User-to-device tracking
  • A management UI for adding or editing users and roles
  • A management UI for adding and editing apps
  • Automatic “compatible app” views based on detection of device platform and version
  • Mobile optimization including standalone “web app” mode on iOS

Implementation

Frameworks

The app catalog I built (cleverly named “App Catalog”) is built with ASP.NET MVC 3, SQL Server, Entity Framework 4, and jQuery Mobile. Honestly, I used Entity Framework because I wanted to try it out. It ended up being extremely useful, combined with linq-to-entities. I can let my entity data model diagram speak for itself about my design.

image

Authentication and Downloading

Unauthenticated users are redirected to a login page, which accepts domain credentials and authenticates against active-directory using forms authentication. I leverage forms authentication cookies to allow users to remain signed in for 14 days.

To explain the authentication of downloads on iOS, I need to take a brief tangent here and explain how iOS OTA installation works. For more information, check out this blog post. To trigger an iOS OTA download, the link must be formatted with a special itms-services:// protocol link. When clicked, it first requests a plist file (which must be returned with the mimetype text/xml) that includes information like the app package name, version, icon url, package url, and a few other various items (this plist file can be generated by Xcode by selecting “distrubute for enterprise” when archiving an application). Then, it uses the package url to download and install the application package. All of this is invisible to the user except for the initial “foo.com would like to install ‘Bar.’ would you like to continue?” message (which occurs between the plist and package (ipa) downloads). Unfortunately, this double-bounce OTA installation does not support cookies, or at least it does not use Safari’s cookies.

Because of this, if the plist or ipa files are behind an authentication wall, the download will fail. In order to authenticate the downloads, when the link to the plist is output on the app catalog page, it is a link to an unsecured action on my controller, with the current authenticated user’s unique download token as a parameter. Then, when the action is requested, that token is authenticated and the plist file is generated from a template (this killed two birds with one stone – authenticating the plist request, while making the plist dynamically generated. Managing the plists manually is a pain, especially with the weird caching that the OTA service does). The proper icon link, file link, app name, and package name are filled in, and returned as a plist file. The package link works the same way – it’s a link to a file download action, with the token as a parameter. When the request comes to this action, the token is verified again, and the app package file is returned (with mimetype application/octet-stream).

It’s important that we go through these steps to authenticate the plist and ipa files, because our Apple Enterprise Developer license only allows employees of the company to download applications signed with our certificate. If our apps were to be vulnerable to anonymous downloads, our certificate and license could be revoked. Much of this is specific to the iOS OTA installation; for Android, the download link points to the app package download action which authenticates the token and returns the app package directly.

Site Behavior

When a user first arrives at the site, they see our company’s in-house apps that are compatible with their device. This compatibility check is done in the request. A request’s user agent is parsed for platform (Android, iOS, Windows) and version, and I use linq-to-entities to get all apps that match the platform and are compatible with their version or lower. Other views allow viewing all apps, or public apps (like recommended applications in public app stores). The apps are presented in a mobile-friendly jQuery Mobile listview with icons, titles, and descriptions, and two-tap downloads (one to confirm).

image

Because we can check for Windows, we also have some listings for common Windows applications that our teams use, and we have a special page for Windows software stored on our network, which simply displays the path to find it on the network, as opposed to a download or installation link.

iOS Supports standalone web applications and webclip (shortcut) icons, so all of these are configured. This provides a more streamlined feel to the website, almost as if it’s an installed application.

Management

I put quite a bit of effort into the management UI for the app catalog. Naturally, we needed the ability to quickly create and update applications in the catalog, without manually copying files and editing the database. There’s an editor form for uploading new icons and app package files, as well as changing any of the properties of the apps, including availability, version, name, description, and platform/platform compatibility. Likewise, there’s a user manager page, where users can be assigned to roles like “tester” or “admin.” All of these management options allow extremely low overhead for updating applications. We even have a module for our apps that checks the app catalog with it’s catalog Id for newer versions, so when a new version goes up, the user is notified right away.

Conclusion

I’m sure there are some features that I’ve missed, or features that are purposely missing that would be deal breakers for others who might need an app deployment solution. For now, it’s been working pretty well. I’ve only had one logged error in the last 3 months, and we’ve hit 200 downloads (300 if you include all of our testers’ downloads) of apps in our company, from the app catalog. I’ve very open to feedback and questions!

PhoneGap in iOS 6

Update 9/27:  This post relates to PhoneGap 2.0. 2.1 appears to have fixed a number of iOS 6 compatibility issues, and I recommend upgrading.

Today I upgraded my Xcode to 4.5, which now builds apps against the iOS 6 sdk. This included many breakages to my projects that I had to fix, and a couple to my apps themselves.

The two biggest problems were:

1. Apple Mach-O Linker Error. Linker command failed with exit code 1. File is universal but does not contain a(n) armv7s slice.
2. The apps failing to work properly in landscape mode. (The status bar would load landscape, but the webview would load portrait, and never rotate.

To Fix problem 1, I simply had to navigate to Project > Build Settings and change Build Active Architecture Only to “Yes”.

To Fix problem 2, I had to change some of the PhoneGap base code. I found the solution here.

In Classes > AppDelegate.m change the line:

[self.window addSubview:self.viewController.view];

to

self.window.rootViewController = self.viewController;

and in Classes > MainViewController.m, add the line:

 self.webView.frame = CGRectMake ( 0, 20, self.view.frame.size.width, self.view.frame.size.height-20);

right after

  [super viewDidLoad];

That’s it – this makes the WebView inherit from the root view controller instead of a subview, and the additional line allows the webview frame to load without being cut off by the status bar.

15 YesWas this helpful?

jQuery Mobile vs Kendo UI

For the past couple of months, I’ve been developing cross-platform apps using PhoneGap. In this, I’ve been using jQuery Mobile as the client framework, tied with knockout.js. Knockout makes dynamic client side web applications extremely simple much cleaner and easier with an MVVM style design in javascript.

For the sake of being aware of the other options available for mobile frameworks, I checked out Kendo UI mobile from Telerik (I chose to check out Telerik’s mobile framework because my company already has licenses for Telerik products anyway). Here’s what I discovered about Kendo UI mobile:

  • It has MVVM built in which works smoother with the mobile UI framework, compared to jQM + KO
  • The MVVM functionality that is built in is not as fully featured as knockout, though.
    • Specifically, knockout works well with big ViewModels and nested observables (i.e., an observable array, each with observable properties), while Kendo seems to want small viewmodels bound to small parts of the DOM.
    • Also, I should mention, choosing to ignore their built in MVVM in favor of knockout doesn’t work at all. I tried, and confirmed that it doesn’t work/isn’t supported from a Rep posting on their forum
  • There’s a new syntax to learn (a small hurdle)
  • They’re big feature is “native feel” meaning on iOS, it’s supposed to look like iOS native controls, and on Android, it looks completely different.
    • The catch, though, is that they are behind. Both OS’s have been updating and changing how they look, but Kendo is lagging behind – meaning you don’t really get native looking controls, you get deprecated native looking controls.
      • Example: iOS updated toggle controls/background: image001
  • It feels a tiny bit quicker than jQM, but still not snappy

Overall, I think it’s probably a wash in terms of quality of Kendo UI mobile vs jQuery Mobile + Knockout. Having already invested a significant amount of time into learning and becoming familiar with the patterns and syntaxes of jQuery Mobile and Knockout.js, there are no benefits that are significant enough to merit the switch. However, at the rate that mobile frameworks are being updated and improved, it is worth keeping an eye on Kendo UI and others (like Sencha Touch and jQTouch), and reevaluating in the future.

Launch Images in iOS–UX

When developing an iOS app, you can specify a set of “launch images” within Xcode. Apple’s iOS Human Interface document informs the developer that these are required for every app, although this must be referring to the “app store polish” because for building and running the app, there is no technical requirement for having these images – apps run just fine without them. The biggest problem I have with the launch images, or rather, Apple’s design of them is this, from the guidelines:

Avoid using your launch image as an opportunity to provide:

  • An “application entry experience,” such as a splash screen

  • An About window

  • Branding elements, unless they are a static part of your application’s first screen

Because users are likely to switch among applications frequently, you should make every effort to cut launch time to a minimum, and you should design a launch image that downplays the experience rather than drawing attention to it.

Generally, design a launch image that is identical to the first screen of the application.

I understand the rationale is to eliminate the feel of “loading” and make everything look and feel faster, but static-images identical to UI is a problem. It causes a bad experience when the launch image looks too much like the first screen of the application. I have two particular examples for why this creates an issue: the built in iPhone calculator, and Safari.

The iOS calculator’s launch image is essentially just a screenshot of the calculator (although there is a slight color difference between the calculator “screen” color in the image from the actual UI) – which invariably causes me to start punching numbers into the calculator on an image because it looks and feels like the real UI. Compare:

2012-08-17 07.59.492012-08-17 07.59.52

Safari’s launch image includes the header and footer. In the header are the address and search boxes. Because these look and feel like the real app, I almost always tap on them to try to focus, but in reality, I’m attempting to focus by tapping on an image. This doesn’t make it feel like it loaded any faster just because it looks like safari is up and running, it makes it feel slower because it’s not responding to my taps.

Personally, the completely blank screen you get if you leave the launch images out of the app, because it lets me know it’s loading, but without excess elaborate splash screens.