Follow olivetoast on Twitter

Olive Toast

Purveyors of fine software


Olive Toast - Blog

09 Aug 2012 App Store Rejection for SkyDrive and Google Drive

We recently added support for Google Drive and SkyDrive to our iOS document reader Files Pro using the official Google and Live SDKs. This update became available on to the App Store earlier in August.

Soon after release some users began reporting a crash at startup - not something any developer likes to hear. We quickly found and fixed the problem, submitting a further update to Apple. We requested an expedited review (something we've never had to do since launching Files Pro way back in 2008) to ensure the update got to users as quickly as possible.

On Tuesday this update was rejected from the App Store on the same basis that some apps were rejected for using the Dropbox SDK a couple of months ago: that a link from the Google Drive or SkyDrive login page could lead to somewhere to spend money outside of Apple's ecosystem.

The login web page for both services includes a "Sign Up" button, which is what Apple is objecting to. You have to dig quite deep to actually find any suggestion that you should part with some cash - but the merits (or rather lack of) to Apple's case have been widely discussed elsewhere.

We've notified Google and Microsoft of the issue, and hopefully they'll provide updates, like Dropbox did, removing the "Sign Up" button from their login web page when loaded from their iOS SDK. But if Google digs in its heels, which is not exactly out of the question, we could be in for a protracted battle, in which the main casualties are users and app developers.

In the meantime here is how we have worked around the problem:

Like most web services today, authorisation occurs in a web page loaded in a UIWebView.

For SkyDrive hiding the "Sign Up" button was simply a matter of running some javascript. The only place you can do this in a UIWebView is in the -webViewDidFinishLoad: delegate method. This is a little too late (the page has already rendered), but in this case it works ok. We delay displaying the UIWebView slightly to ensure the javascript has run (other page scripts may run first):

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // Hide the Sign-Up button
    var js = @"document.getElementById('i0280').style.display = 'none';";
    [webView stringByEvaluatingJavaScriptFromString:js];

    // Because the page's own javascript takes a second or two to process delay the animation:
    [UIView animateWithDuration:0.2
                          delay:1.0
                        options:0
                     animations:^{webView.alpha = 1.0;}
                     completion:nil];
}

For Google Drive we tried the same approach. However in this case the web page's own scripts can take 3 or 4 seconds to run. Since -webViewDidFinishLoad: is called late on our own javascript has to wait for the page's scripts to complete, which means the Sign Up button can be visible for some time.

The solution we ended up using was convoluted, but works reliably. Instead of loading the authorisation request straight into the UIWebView we download the page HTML via a NSURLConnection. We then insert an extra style element into the HTML header and only then load this HTML into the UIWebView. This works perfectly and avoids the button ever appearing, even briefly.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // Inject the style to hide the sign-up button:
    NSMutableString* html = [[NSMutableString alloc] initWithData:connectionData_ encoding:NSUTF8StringEncoding];

    [html replaceOccurrencesOfString:@"</head>"
                          withString:@"<style type='text/css'>#link-signup {display:none}</style></head>"
                             options:0
                               range:NSMakeRange(0, html.length)];

    // Now load. The baseURL is important for linked document content.
    [webView_ loadHTMLString:html baseURL:[NSURL URLWithString:@"https://accounts.google.com/ServiceLogin"]];
}

Note that both these approaches are brittle: Google or Microsoft may change their login page layout or element ids at any time. But we needed to find some sort of solution to ensure our users receive a critical bug fix as quickly as possible.

Posted in: files

Latest Posts | Archive