The Power of Encouraging Women Who Code

Personal Capital is proud to sponsor Women Who Code, a non-profit organization dedicated to inspiring women to excel in the technology industry.

Most articles about the ratio of women to men in tech focus on the negative, citing differences in population, salary, and leadership roles. I would like to take time to put a spotlight on a couple of positive anecdotes that show how people can make a huge difference by providing a little support.

About a year ago, a female friend of mine pulled me aside at dinner and told me she had made a career change to become a web developer. She said the idea of entering the tech industry first took hold after a discussion we had years back, in which I (as a female developer myself) had encouraged her toward this new direction. The news was such a pleasant surprise because it made me realize how a simple conversation can change the course of a person’s life in a positive way, either through the introduction of an idea or by instilling confidence in one that had been lying dormant.

It reminded me of a conversation that changed the course of my own life. It was my first year at UC Berkeley, and I was taking CS3: Introduction to Symbolic Programming, on a whim. I loved the class and considered departing the hazy pre-med path my parents laid out for a computer science focus. I was concerned, though, because so many people in the class had previous programming experience and I was starting from scratch. I asked my sister if I was crazy for pursuing this foreign path, and she told me that if I was good at it and liked it, go for it.

Fast forward to now, I’m the Director of Mobile Technology at Personal Capital, a company that I believe in, where I’m doing what I love. It just goes to show how a little inspiration and support can go a long way, and I’m proud that Personal Capital is sponsoring Women Who Code, an organization that is dedicated in providing both.

A High-Level Look at NSURLSession

Though Apple introduced NSURLSession in 2013, NSURLConnection has served as such a strong networking infrastructure that there really hasn’t been a need to update it. With the upcoming release of watchOS 2 and iOS 9 in September, refreshing Personal Capital’s tech stacks seem appropriate so we can take full advantage of Apple’s latest technology offerings.

The NSURLSession API comprises of the same components as NSURLConnection (NSURLRequest, NSURLResponse, NSHTTPCookieStorage, NSURLCache and NSURLProtocol) but replaces NSURLConnection with NSURLSession, NSURLSessionConfiguration, and NSURLSessionTask.

 

NSURLSession: divide and conquer

NSURLSession introduces the concept of configuring cache, cookie, credential, and protocol policies into sessions instead of sharing these policies throughout the app. This allows you to separate network tasks into appropriate sessions as needed so changes to protocols, credentials, cookie storage, or cache storage can be localized to only the tasks in that session. This is done by initializing an NSURLSession with an NSURLSessionConfiguration. After initialization, you cannot change a session’s configuration. If you feel a need to do so, this probably means the network request or task belongs in a different session. If needed, you can override HTTP header values set in the HTTPAdditionalHeaders property of a session’s configuration by setting them in the NSURLRequest.

 

NSURLSessionConfiguration: persist/share, private, and background

NSURLSessionConfiguration has 3 types of constructors.
+ defaultSessionConfiguration returns the default configuration and defaults to using the same shared cache, cookie, and credentials storage that are familiar with NSURLConnection.
+ ephemeralSessionConfiguration returns a configuration that uses no persistent storage for cache, cookie, and credentials. This configuration would be used if you wanted to create a feature similar to private browsing.
+ backgroundSessionConfigurationWithIdentifier: returns a configuration that allows HTTP and HTTPS uploads and downloads while the app is in the background. If an upload or download is interrupted because the app is terminated by the system, the upload or download can be resumed by creating a new NSURLSessionConfiguration with the same identifier that was used for the interrupted configuration and passing that to a new NSURLSession. Interrupted tasks cannot be resumed if the app was terminated by the user.

 

NSURLSessionTask: reminds me of NSURLConnection with a completionHandler … and background support!

NSURLSessionTask is analogous to NSURLConnection because it’s the base class for handling requests for data as well as the uploading and downloading of files. NSURLSessionTask consists of three different subclasses.

  • NSURLSessionDataTask is used for making HTTP and HTTPS requests and return the server’s response as NSData in memory. An NSURLSessionTask can be constructed by providing an NSURL object or an NSURLRequest. These tasks are only supported in default and ephemeral sessions.
  • NSURLSessionUploadTask is a subclass of NSURLSessionDataTask but these tasks provide an easier way to upload content. For example, you can create an NSURLSessionUploadTask by passing an NSURLRequest with either NSData representing the body data of the request or an NSURL object for the URL of the file to upload. These tasks are allowed in background sessions and provide callbacks to the session’s delegate as data is uploading. Since these tasks are allowed in background sessions, you can technically create an NSURLSessionUploadTask (pass nil for the body data) instead of an NSURLSessionDataTask if you really require the task to continue in the background.
  • NSURLSessionDownloadTask is a task that directly writes the server’s response data to a temporary file. After completion, the app needs to move the temporary file to an appropriate place. These tasks can run in any type of session.

Instead of allocating an NSURLSessionTask on it’s own, tasks are instantiated by an NSURLSession object. An NSURLSessionTask can be constructed with and without a completionHandler. If a completionHandler is provided, it will be executed after the request is completed on the delegate queue. For NSURLSessionDataTask and NSURLSessionUploadTask tasks, the completionHandler will return the NSData and NSURLResponse object returned by the server or an NSError object if an error occurred. The completionHandler for an NSURLSessionDownloadTask task returns the location of the downloaded file as an NSURL object, the NSURLResponse from the server, or an NSError object if an error occurred.

 

Delegates: why to not construct with a completionHandler

You may be wondering why you would ever create an NSURLSessionTask without a completionHandler. If you require finer control over the progress of an NSURLSessionTask, you need to provide a delegate. If you provide a delegate and also provide a completionHandler, you will notice that none of the callbacks related to progress are called. (You will still get URLSession:task:didReceiveChallenge:completionHandler:.) If you want to receive all of the callbacks, you need to construct your task without a completionHandler. The combination of NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, and NSURLDataDownloadDelegate cover the delegate methods that NSURLConnectionDelegate and NSURLConnectionDataDelegate provided for NSURLConnection. Each of these delegates are well documented so there’s no need to go over them in this article. One thing to note, though, is that both NSURLSessionDelegate and NSURLSessionTaskDelegate provide callbacks for authentication challenges. The callback for NSURLSessionDelegate handles authentication challenges at the connection level (NSURLAuthenticationMethodNTLM, NSURLAuthenticationMethodNegotiate, NSURLAuthenticationMethodClientCertificate, and NSURLAuthenticationMethodServerTrust). If URLSession:didReceiveChallenge:completionHandler: is not implemented at the session level, the callback at the task level is called. URLSession:task:didReceiveChallenge:completionHandler: will additionally handle authentication challenges at the request level.

 

Further reading

All of the information mentioned in this article can be further studied in the NSURLSession Class Reference from the iOS Developer Library (https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/).

Mobile Development: Testing for Multiple Device Configurations

All Android developers should have at least 1 “old” device running OS 2.3.3 and a current “popular” device. Ideally, one should also have a current device that is considered “maxed out” on specs. A company should additionally have the latest “Google” device (currently the Nexus series), and an HTC, Sony, and Samsung device. (These manufacturers are mentioned because of popularity and/or significant differences not found when developing on other devices.) Additionally, OS 4.2, 4.3, and 4.4, though minor OS increments, offer differences that should be considered.

Though development for iPhone/iPad is more forgiving given the fewer configurations, it still offers challenges. For example, if you are developing on a Mac running OS X Mavericks with a version of Xcode above 5.0 for a product that still needs to support iOS 5.x, you will need a physical device because the iOS 5.x simulator isn’t available for that development configuration.

If testing mobile websites, the configurations can be endless.

At Apps World 2014, Perfecto Mobile (http://www.perfectomobile.com) introduced me to mobile cloud device testing. Their product offers access to real devices (not emulators or simulators) connected to actual carriers physically hosted at one of their sites around the world.

The concept of mobile cloud device testing allows the ability to test on a multitude of configurations of devices, locations/timezones, carriers, and operating systems.

Beyond access to multiple devices, Perfecto Mobile offers automation testing across these platforms via scripts written in Java. I wasn’t able to personally delve as far as I wanted into these automation tests, the recording feature, or the object mapper before my trial ran out, but the demo at Apps World gave me the impression it behaves similar to Xcode’s Automation instrument but expanded to all devices.  The scripts enable your team to target certain device configurations and automatically launch, execute the given tests, clean and close the devices, and export the test results to your team.  I wish I could say more because it looked really promising but without actual usage, I can only mention what I viewed during the demo.

It’s impossible to cover every configuration during native Android application development, but after a release, for all platforms, if your product is experiencing issues and a crash report doesn’t reveal enough, mobile cloud device testing offers the a real option for true coverage.

Below is a listing of some features of interest Perfecto Mobile offers:
- Access to real devices connected to actual carriers (not emulators or simulators) physically hosted at one of Perfecto’s sites around the world. Since these are real devices, you can dial numbers, make calls, send text messages, and install apps.
- UI for devices available displays availability, manufacturer, model, os + version, location, network, phone number, device id, firmware, resolution.
- Ability to open multiple devices at the same time.
- Requests for devices and configurations not available are responded to in real-time.
- Ability to take screenshots and record sessions to save and/or share results with others.
- Ability to share the device screen in real-time with your team.
- Ability to collect information for a device such as battery level, CPU, memory, and network activity.
- Export of device logs.
- Beta of MobileCloud for Jenkins plug-in that allows running scripts on actual cloud devices after a build so you can see reports on a single device after a build (multiple devices is not available yet).

WYSIWYG…but there’s a whole lot more to see without it

Personal Capital recently updated its iPhone/iPad application to include a new 401k fund fee feature as well as add support for iOS 6 and iPhone 5. Adding support for a new OS as well as a new device, especially one with a new screen size, is always a great test to a project’s architecture and code. A properly architected project allows the developer to add support for new features with minimal adjustments to the project.

The Personal Capital iPhone/iPad project is a testament to the value of not using WYSIWYG tools. The application supports a range of operating systems as far back as 4.3, and takes advantage of each device’s retina display if available. Every screen is created purely from code and takes advantage of Apple’s APIs that allow a view to re-size and/or adjust the position and functionality of objects based on the current screen size and device rotation. Based on this architecture, updating the project to support iOS 6 and iPhone 5′s 4-inch display only required a few changes.

WYSIWYG tools are SDK dependent. This means that when a new feature is introduced, there will need to be an update to the SDK and accompanying WYSIWYG tool to support these features. Since these features did not exist in the previous WYSIWYG, you will need to update each of the corresponding WYSIWYG files associated with the tool to correctly utilize these features.  For example, the latest version of XCode’s Interface Builder allows support for the iPhone 5’s new 4-inch retina display by providing an additional “Size” property for views.   If your application uses Interface Builder to create its screens, you will need to update each of your nib files if you want your application’s views to re-size correctly.  If your project was built without Interface Builder and is coded for a dynamic screen size by utilizing the frame and bound properties of a view, you don’t need to do anything to your code to support additional screen sizes and layouts.

When a new OS rolls out, there are exciting new features to take advantage of as well as deprecated methods.  If your project is fully code-based, you can do a simple word search to find the points in your code that you want to update.  WYSIWYG tools are unique to each SDK but most are not easily searchable since they are designed to be visual tools.  If the WYSIWYG files aren’t binary, you can do a word search on them but most likely the keywords you need to search upon are specific to the tool and will be different than the property or method name associated with the class’s code-based counterpart.  This means even if you can search upon a WYSIWYG file, your efforts are doubled.

This brings me to the concept of developing for multiple clients.  Successful applications will eventually port to multiple clients and the need to not have to “reinvent the wheel” for each client is essential.  If you are building an application that doesn’t need to utilize UI elements specific to a platform, you can develop your entire application in C so it compiles for iPhone/iPad devices and also support Android devices using the Android NDK.  Obviously, this approach is great for code-reuse but doesn’t allow you to utilize some platform specific features that are accessed via platform specific classes.  I’d love to build an application completely in C so that the code is shared across platforms, but this way can be a little masochistic if you actually want to incorporate platform specific elements into your application.

So what options are left?  If the exact code can’t be reused across clients, you can still reuse the logic.  The Personal Capital application features a variety of dynamic and interactive visual elements that are all built using custom code.  Since they are built entirely in Objective-C without the use of a WYSIWYG, I was able to take the exact code and “Javacize” it for the Android platform.  This meant literally taking the code and just changing it to Java but leaving the logic.  I had not looked at parts of the code in months, so some of it was a little foreign to me.  Since I was simply converting Objective-C to Java, though, it didn’t matter.  This means sections of an application that had been complicated to create on one platform can be delegated to anyone who knows both Objective-C and Java even if they aren’t familiar with the code.

Reusing code in this manner also facilitates the QA process of application development.  Since the same logic is used on all platforms, your QA department doesn’t have to deal with testing a completely new product.  Any issues that arise can be fixed by resolving the issue on one client and then quickly mapped to the other clients.

If portions of your application are created with platform specific WYSIWYG tools, though, this process begins to fall apart.  Besides being platform specific, WYSIWYG tools create a black-box effect on a project.  Most tools do not go into depth the one-to-one relationship between what is being achieved and how to accomplish it in code.  If a developer is familiar with the platform API and its classes, the process becomes mappable, but at this level of understanding, most developers opt out of using a WYSIWYG for actual code since it’s more dynamic and customizable.

There are cross-platform WYSIWYG tools, most of which are HTML5 based.  Many of the simpler applications that you see in the market place actually could have been built using these tools which would have saved the developer the hassle of managing multiple code-bases.  But the key word is simple.  HTML5 applications will never perform as well as a native application and can’t integrate platform specific functionality at the level that a native application can.

There is nothing wrong with using a WYSIWYG if you’re new to a development environment and need to get up and running quickly.  But if your developing complex, dynamic applications that extend beyond out-of-the-box platform elements, you will find that most of your work will be done in code and you’ll most likely drop the use of any WYSIWYG implementation to maintain a clean code-base that can be ported to different platforms.