iOS UIView, WebApps and iFrames


One of our existing responsive websites (built using Angular) was being pulled in as part a Cordova project to make an iOS and Android app, and the developers had some weird issues on iOS. Inside the Cordova app, our app was loaded in an iframe. I wanted to write about a few of the issues that came up, particularly with the iOS UIView, and some of the hackery I resorted to in order to resolve the issues.

Issue 1: Fun with iOS Iframes

First issue we had was that the app kept bouncing between the small and xlarge media query. This turned out to be due to what I consider a bug in iOS, in that iframes size to their content, rather than sizing based on the attributes/styles on the iframe itself or parent constraints. We had logic that enabled some functionality on small, which in turned created a wide html element for a carousel and due to the iframe bug in iOS, would cause the width of the iframe to grow to the xlarge size again. The carousel functionality would be destroyed, as it was only for small, causing the element that was created to hold the slides to be destroyed, causing the iframe to shrink back down to the small size again. And then the cycle would repeat, infinitely.

I was able to fix this issue by immediately setting an explicit width on the body before any of the rest of the HTML was loaded/parsed. This worked in our case because the application will always be in portrait mode, we would need to also watch for resize events and things would get more complicated. Right at the top of the body, I added the following code:

<script>
  document.body.style.width = document.body.clientWidth + 'px';
</script>

Issue 2: iOS WebApp links open in Mobile Safari

The second issue we had was that any link clicked in the website being wrapped in this iframe would load in Safari. It didn’t matter if the link was relative or fully qualified, or what kind of target (or lack thereof) it had. Turns out that is normal behavior for web apps on iOS. I’m not proud of the solution, but the fix was to grab all links in the app, watch the click event, stop the default browser action, and load the new page with window.location. It looked something like this:

$('html').on('click', 'a', function (event) {
  var href = $(this).attr('href');
  if(href && href.indexOf('http') !== -1 && !event.defaultPrevented) {
    event.preventDefault();
    document.location.href = href;
  }
});

I had jQuery available, but for a non-jQuery version, check this out here: https://gist.github.com/kylebarrow/1042026

My initial solution broke links in the site that already had JavaScript functionality attached to them, so the click event was delayed briefly from being attached by wrapping it in a timeout. That way it should be the last event attached, and be skipped if the event had already had preventDefault called on it.

Overall, it’s two hacks that fixed the issues we were seeing. Mileage may definitely vary given, but hopefully this will prove useful to the reader (or more likely, a future me trying to figure this out again).

Vanilla JavaScript vs. Framework Functions


Had a quick conversation at work today about whether or not it was good to use built-in framework functions for tasks that are simple to write in vanilla JavaScript. For example:

angular.isFunction(fn) 

vs

typeof fn === 'function'

I’ve tended to do the vanilla JavaScript, but while checking if something is a function is almost identical in complexity/length, while others can be (slightly) more complex:

angular.isObject(yourVariable) 

vs. 

yourVariable !== null && typeof yourVariable === 'object'

Still, either way is pretty readable, and fairly clear what it is doing. I wonder if this is what leads to people bashing frameworks like Angular for teaching people the “framework” rather than vanilla JavaScript, as newer coders who may not have ever had to check variable types who are learning Angular may use the framework checks without knowing how to do a similar thing in vanilla JavaScript.

I like to collect snippets that will help me, and reuse them where appropriate. This probably tends to skew me towards vanilla JavaScript, because I want my snippets to work no matter what project I am working on. For example, the following snippet gets the class (or type) of a JavaScript variable.

/**
 * getClass - get real type of JavaScript object 
 * @param object
 * @returns {string}
 */
function getClass(object) {
    return Object.prototype.toString.call(object).slice(8, -1).toLowerCase();
}

/*
getClass({}) // "object"
getClass([]) // "array"
getClass(function(){}) // "function"
getClass('') // "string"
getClass(1) // "number"
*/

I came away from the conversation thinking there was not one right way. If you are writing an app with the help of of a framework, there is nothing wrong with using the tools the framework provides. At the same time, it shouldn’t become a crutch where a framework is needed because a developer isn’t comfortable doing the same thing in vanilla JavaScript.

Blog theme updated


Getting back to posting more often, and wanted a simple but clean theme. Found one that will do the job with minor customization. While I have the capacity to build my own theme from scratch, I’d agonize over the details, and this lets me focus on the content instead.

Support Net Neutrality, tell the FCC!


PSA: Less than 14 hours to go. That’s how long we have to get pro-Net Neutrality comments submitted to the FCC in front of their first comment period deadline (midnight Tuesday) — and save the Internet from the clutches of Comcast, Time Warner, and their ilk.

This website makes it very easy to send the FCC a formal comment demanding support for Net Neutrality. It’ll only take a minute, although if you customize the message it may have even more impact.

https://www.battleforthenet.com/

SelfConference, chance to learn and to speak


A big thank you to the organizers of SelfConference ’14 in Detroit, MI.  It was held at Cobo, in the recently revamped section, and it was quite nice!  The conference had some great sessions and I had the exciting opportunity of presenting at one of them.

On Friday, I enjoyed talks about owning your own career in the development industry, why you should actively try to piss people off, working with Sass, a bit about Ember and also how to Quantify myself.

On Saturday, it was a bit of a blur as I was concerned about speaking at 2PM, for the session entitled Blind Faith and Best Practices, a talk about front-end best practices and attempting to get developers to research the why behind them rather than blindly following what someone says is a best practice.  That said, I still learned about making the web secure by default, the emerging world of DevOps and a bit about Ionic.  I also sat in on the How to Build a Time Machine talk by Adam Kempa and Karen Ford, a case study of the WhatWasThere website build.

Overall, this weekend was quite enjoyable, and the credit for that goes to the organizers of the conference. Looking forward to future years and watching how the dev. community in Detroit continues to explode.