All posts by admin

THE ROLES OF A MOBILE APPLICATION DEVELOPMENT TEAM

img

With over 5 billion mobile users across the globe, there can’t be a better time than now for you to start considering mobile application development. However, before you start developing mobile applications for your business or brand, it is important for you to understand that mobile application development is a comprehensive process that requires a lot of people to work harmoniously and be on the same page to deliver a quality mobile application.

Below, we’re letting you in on the roles and responsibilities of the different people that will be involved in the development process to help you understand the team that you’re supposed to be looking for when you think of developing mobile applications for your business or brand.

The Perfect Mobile Application Development Team

As mentioned earlier, a lot of people need to work together and be on the same page at all times if you’re interested in crafting a product or application the likes of which has never been seen before.

Here are some of the positions that are important for a promising mobile application development team.

Project Manager

While all members of the team are extremely important to create a successful and impeccable mobile application, it would not be incorrect to say that the responsibility of streamlining the entire process from start to finish is on the shoulders of the project manager.

The project manager of any mobile application development team is not only responsible for delivering on the requirements of the client, but it is also essential for the product manager to ensure that the entire team has the same vision regarding the application or software that is being developed.Managing and preventing roadblocks in communication, too, is one of the responsibilities of the project manager who is often also referred to as the team leader.

UX Designer

The user interface is one of the most important parts of any mobile application and a user friendly interface is almost synonymous to a great application. A designer will not only be able to help you with an impeccable interface, but also with aspects related to branding and marketing, and other important tasks like the creation of the logo for the application.

Technical Writer/Business Analyst

Technical documentation, in the case of mobile app development, is the road map, the steps your team will follow to create the app. It includes a business logic, the apps purpose, product manual, steps involved in the development, marketing research, information about the technology being used, the kind of testing you are doing, the time-line, and the budget. It acts as a resource for the development team as well as the manager. Without the road-map, you have to rely on the skills of the developer who skills typically do not include technical writing or business analysis.

Developer

As you might have guessed, the technicalities of the application are the responsibility of the developer. With that said, there is rarely anyone who does as much work as the developer in the creation of a great mobile application. A developer is not only responsible for writing great code, but also for ensuring that the application continues to work seamlessly even after it has been launched.

QA Tester

Quality Assurance testing is extremely important in the app development process. QA’s primary role is to search for bugs and make sure that they are eliminated. Quality Assurance testers aim at preventing errors and bugs and are constantly improving the process. QA is responsible for training, setting standards, reviewing quality and selecting tools.

Interested in creating high quality mobile applications? We can help! At Atimi, we have professional teams of developers, QA testers, designers, technical writers and project managers that can help you create your application – all without going through the hassle of finding the right people to hire!

With our affordable high quality outsourcing and staff augmentation services, you’ll never have to shy away from or be intimidated by the process of launching an application for your brand or business. All you need to do is give us a call at
778-372-2800

info@atimi.com

img

FLOW: PRIORITY ONE FOR MOBILE INTERACTION DESIGN

img

Find out more about 5G

Find out more about IEEE and High Speed Wireless

Find out more about the sublime Mihaly Csikszentmihalyi

Find out more about Mihaly Csikszentmihalyi’s book on FLOW

Find out more about the magnificent Bill Moggridge

Find out more about AIDA (Attention, Interest, Decision, Action)

Get in touch with us to find out how Atimi Software can help you build a custom, innovative, enterprise app that offers a superior user experience and stands the test of time.

778-372-2800

info@atimi.com

img

AUTOMATION WITH VISUAL RECOGNITION

img

Automation is not a new topic, with most software development QA teams employing its use in one way or another. There is also no lack of tools to choose from.

On desktop, there are the ever popular Selenium and the HP backed HP – UFT (formerly QTP). For mobile, Appium and MonkeyTalk are among the more frequently used solutions.

All of these tools are fine choices for functional and data driven tests due to their object-oriented nature. However, in my experience, there is one type of automation that is seldom mentioned, visual based testing using OCR (Optical Character Recognition) technology.

What is Visual Automation?

Visual automation relies on the appearance of on-screen elements to perform an action. This is different from traditional automation, which relies on the occurrence of elements in the background resources. To accomplish this, a set of pre-defined or determined visual images and/or transitions are stored. Scripts are written to compare the stored images to the current screen appearance in a set sequence to ensure the application is running through the expected on-screen transitions.

Actions can also be scripted in response to on-screen changes. For example, the tools would check for the appearance of a login screen and compare its appearance to the expected result. If the screen matches the expected result, the tool would fill in the user name and password fields by mimicking mouse clicks and keyboard strokes.

Visual automation tools not only watch the screen for the appearance of specific elements but they can also act on element transitions, the disappearance of elements, or elapsed time. Actions against these on-screen elements mimic human actions. The tools can attempt to perform functions such as clicking, double-clicking, dragging and dropping, filling forms, etc.

The range of action is at the full extent of what humans can do. There are several tools currently available to perform visual automation, including Squish and my favorite, Sikuli.

Why Visual Automation?

Visual automation acts much closer to human behavior than object-oriented automation tools. The actions and reactions are only based on visual stimuli to which humans can react. This allows testing to be conducted in a way that is much closer to the human experience than any other type of automation. Consider the following examples:

In the case above, a real human end user would have issues with the page but automated tools would have no trouble finding the login button as long as only the front-end graphic is missing.

The above test would pass when using object-oriented automation where the tool is used to find if an element exists without considering its proper placement whereas if visual automation is utilized, the defect would be properly identified.

The above scenarios are only a couple examples from a long list of scenarios where an automation tool that behaves similarly to a human user would be more useful

Another advantage of an OCR-based automation tool is that it is not bound to an application while some other tools have limited access or even no access to the system outside of the application being tested. Visual automation tools can watch the entire screen for any change regardless of source. This way, it is possible to launch multiple unrelated applications and watch for their interactions. It is also possible, if one were to be inclined to do so, to launch a virtual machine and then launch multiple applications within it, with all of them under the control of a single automation tool. It can be quite powerful under the right circumstances.

The Case Against Visual Automation Tools

Visual automation also has some glaring disadvantages. If it didn’t, it would be much more widespread.

Firstly, it is not well suited for repetitive fast-paced testing. This is typical in a stress test scenario. Due to the nature of human user mimicry, this automation waits for the application to fully load and respond before proceeding. Therefore, testing time is usually much longer than with object-oriented automation. As a secondary effect of this, visual automation is also ill-suite for fast data verification. It is possible to run through a set of data (possibly stored in a spreadsheet or csv) but it would be much more time consuming than with object-oriented automation tools.

Secondly, it can’t handle multiple instances of the same application being tested. This type of automation watches the monitor for predetermined screens to show up. If multiple instances of the same or even similar screens appear at the same time, it can quickly become confusing. This is an unfortunate side effect of the ability to watch the entire system screen rather than just the single application.

Lastly and maybe most importantly, there is potentially a higher maintenance cost. Due to the fact that expected results need to be stored and updated, there would be a much higher human involvement in the maintenance of the comparison banks. Every change to the visual look would require capturing and restoring the new expected result. Even a change in transition would require script updates. Now, of course, the usual tricks of modulation and function extractions would work but this only reduces labor without eliminating it.

Opening New Doors

In the world of automation, visual automation (OCR-based) tools are often overlooked even though there are plenty of scenarios where they could offer a superior solution. By their nature of behaving closer to human end users, they can catch errors that would be overlooked by object-oriented tools. Having system wide influence can also open new doors in automation.

Yes, there are indeed several glaring shortcomings in visual automation, as I mentioned above, but I’m not saying other tools are not needed or that any tool should be used in exclusivity. For any serious automation of testing, a QA manager should evaluate all available tools and utilize any and all tools to their strengths. I just don’t want you to miss out on OCR tools and the advantages they offer.

Get in touch with us to find out how Atimi Software can help you build a custom, innovative, enterprise app that offers a superior user experience and stands the test of time.

778-372-2800

info@atimi.com

IOS DYNAMIC TYPE IS IMPORTANT (AND ABOUT TO BECOME MORE SO)

img

Dynamic Type is not new. It has been around since iOS 7, but its adoption by applications has been somewhat patchy – until now. With iOS 11, Apple is making significant improvements to the feature that should lead to wide scale adoption. This article goes through these changes and considers how they will impact good app design and implementation.

What is Dynamic Type?

iOS has always included great support for text. The OS has dozens of high quality, scalable fonts and a sophisticated text rendering engine. Designers and developers have been able to leverage this rich feature set to produce attractive and functional UIs.

However, with a small screen, UI design is always a compromise between fitting content into the view and readability. And as the size of readable text varies from person to person, what works for one may be unusable for another. Text-heavy applications (such as news readers) might offer a text size setting but as such features need to be coded manually, most applications just don’t warrant the effort.

To solve this issue, Apple introduced Dynamic Type in iOS 7. It allows designers to utilize a set of seven (later increased to ten) text styles when selecting fonts. These styles are then mapped to different fonts and sizes according to the user’s text size setting. With Dynamic Type, any application can be responsive to the user’s size preference, which improves the experience for a broader range of users.

Dynamic Type supports seven size settings, allowing a significant variation in font size. For example, Body text style is 17pt at the default setting but ranges from 14pt to 23pt. However, this is not the limit as iOS includes an accessibility setting that adds five larger sizes, all the way up to 53pt for body text. (Note that, at present time, only body text size changes in the accessibility sizes – this will change in iOS 11.)

This flexibility comes with its own challenges. The dynamic range of body text is roughly 4:1, making even short sentences span multiple lines. Static layouts clearly will not function with Dynamic Text. Fortunately, Auto Layout will handle most of the heavy lifting, allowing the UI to adjust layout without the need for code.

Nevertheless, not all layout issues can be solved with Auto Layout alone. Also, retrofitting Dynamic Type into an existing application (particularly if it includes manual layout code) can be difficult. Finally, adopting Dynamic Type means abandoning the other OS-supplied fonts, not to mention custom fonts; not an easy choice for designers seeking a distinctive look.

These challenges have led many apps to be slow to adopt Dynamic Type, or to do so in a naive fashion, resulting in broken UIs, particularly for the larger settings.

However, all this should be about to change…

What is Coming in iOS 11?

At this year’s WWDC, Apple announced several improvements to Dynamic Type for iOS 11 that will have a big impact on the rate and cost of its adoption.

Perhaps the most significant is the ability to use other fonts with Dynamic Type. This allows designers effectively to redefine the text style palette (including typeface and point size) and the system will automatically scale them according to the user’s text size.

To understand the impact of this, just consider an educational application that wants to use Chalkboard SE (one of the standard iOS fonts) as its main typeface. Previously that would rule out Dynamic Type. In iOS 11, not only is this possible, but the designer could decide that the text should be slightly bigger (18pt, say, for body text) to look clearer with the handwriting typeface – and the fonts will still scale appropriately at other text sizes.

It also becomes easier to update existing UIs for Dynamic Text. Auto Layout gets the ability to adjust vertical spacing according to text size so text doesn’t get cramped at larger sizes. And for manual layout code, it is possible to scale pixel distances according to text size for similar effect.

Images can also scale to allow icons to be more visible in large accessibility text sizes. UIKit is even capable of keeping icons in vector form to avoid pixelation issues.

Beyond this, there is improved layout tuning as the text size is being made available as part of UITraitCollection, which is the standard way to track other factors affecting layout.

One final change is that now all text styles change point size with accessibility. This will greatly improve the reading experience for low-vision users as all text, not just body text, will scale. It also impacts design thinking as it means much more variation in content size.

What Does Apple Say?

Perhaps more important than the technical improvements to Dynamic Type is the push by Apple to promote accessibility in iOS 11. This includes applying “design for everyone” principles to the applications and utilities that ship with the OS. Amongst these principles are three goals for the use of text.

1. Text should be large enough for the user to read. (In other words, text should scale with Dynamic Type.)

2. Text should be fully readable. It shouldn’t be truncated unnecessarily and it shouldn’t be overlapped or clipping.

3. An app’s UI should look beautiful at all text sizes.

Achieving these goals requires UIs to be more adaptive than simply allowing text to grow. For example, table cell content is often organized horizontally with an image or icon on the leading side and text label trailing. This looks great for regular text sizes but the larger accessibility fonts lead to the label looking cramped (even to the extent of long words being broken across multiple lines) while the icon sits in a large vertical whitespace. Switching to a vertical layout with the icon above the text maximizes the horizontal space for the text while fitting more content onscreen.

In other situations, accommodating larger fonts may mean reordering vertical content to ensure that action buttons don’t get pushed down by multiline text, reorganizing tool buttons into multiple rows, or hiding ancillary content to make room for important text.

None of these adaptive designs come for free but Apple makes the point that they are worth it to deliver a great experience for everybody. And by delivering such an experience within the system applications, Apple is raising the bar for third-party apps. With iOS 11, users will be more willing to enable accessibility features to improve ease of use, and apps that fail to support Dynamic Type well will ultimately lose out to those that do.

Get in touch with us to find out how Atimi Software can help you build a custom, innovative, enterprise app that offers a superior user experience and stands the test of time.

778-372-2800

info@atimi.com

6 THINGS TO CONSIDER WHEN BUILDING A MOBILE STRATEGY FOR YOUR APP

img

Here’s a hard truth that most app developers don’t want to hear: the majority of the millions of apps available for download in app stores today are never going to find success. The fact is, the app market is overloaded with apps that don’t provide enough value to the end user and they are outperformed by their competitors.

To avoid ending up in the pile of apps that never did and never will succeed, it’s paramount that you have a concrete mobile strategy in place before launching your app. Whether your app is consumer or employee facing, we’ve come up with some helpful tips for building a winning mobile strategy that’s sure to help your app succeed.

1. Determine Your Goals

As with all strategies in business, the first step in building an app mobile strategy is to define your goals and objectives. Before you start planning for app development, come up with a wish list for what you want your app to have and why – if you don’t have the “why” piece, you won’t be creating an app that makes sense for your enterprise.

Here are some questions to get you started:

a. Why are you building an app?

b. Who is your app for (customers or employees)?

c. Is your app going to improve the lives of others and how will it do that (for instance, will it enhance your employees’ productivity or entertain consumers and if so, how)?

Be sure to look for an app development company that will help you define your goals and build a sustainable mobile strategy. For instance, the first step in Atimi’s process is to work closely with you to create an app blueprint that’s tailored to your needs. We know the right questions to ask to get our clients thinking through the fine details that separate the outstanding apps from the merely good apps.

2. Do Your Homework

Another key element in any successful mobile strategy is research. In order to understand what your users are looking for in an app and demonstrate why they should choose your app over others, you must have done some research on your competitors (if consumer facing) and users. Once you’ve done your homework, you’ll be in a better position to build an app that your users will enjoy.

3. Define Your Monetization Plans

There are several ways in which you can monetize your consumer app. Let’s run through three of the most popular options:

A. In-App Ads (Free With Advertising)

As App Developer Magazine stated in a recent article, “Ads can prove to be a successful option if you collect data about your customers because you have the opportunity to show them highly-targeted ads”. Targeting is what makes in-app ads so appealing to advertisers, so if you opt to go this route, be sure to have a plan for how you’ll track your users’ data. For instance, your app could utilize a device’s GPS so that relevant ads can be shown to users based on their location.

Alternatively, your app signup form might include demographic and psychographic information such as gender, age, geographic region, and interests. If you can collect meaningful user data, you’ll attract marketers with advertising dollars to spend. As a testament to this type of advertising, a recent study found that in-app advertising grew by 66% in the US last year to $21 billion and is expected to increase to $35 billion in the coming years. This explosive growth in ad spend is promising for app developers everywhere.

One thing to be mindful of when venturing into in-app ad monetization is that you must always respect your users’ privacy and put them first. As premium ad platform, Jun Group, was quoted saying in a recent Appticle blog post, “The best practice continues to be to ask audiences before gathering, storing and using their mobile data. Let consumers opt-in to a better ad experience, but if they do not want to be tracked or have their data used, publishers and advertiser should respect that.” We couldn’t agree more.

B. Paid App (Free With Advertising)

Paid apps are exactly what you might have thought they were: apps that users must buy in order to download and use. Keep in mind that if you’re going to charge for your app, you must ensure that your app is better than any other free app that’s similar to yours. This is why we research our target users and competitors – to find our competitive edge! There are millions of apps available for download, so you must convey that your app is worth the purchase and prove it once users have downloaded it (this will increase app downloads, engagement, and drive positive app store reviews).

C. Freemium

This popular monetization model offers users a free app download along with some limited free features. To get access to additional features and content, users are required to make an in-app purchase/upgrade. This model is often used for gaming and media apps that hook users with great free features and content and then persuades them to make an upgrade to access deeper or exclusive content and features through a purchase. Apple notes, “While freemium apps are very popular, this model isn’t appropriate for every app. Successful freemium apps operate as services that are continuously supported, often requiring sustained content development to retain users.” So, if you’re planning on going this route, understand that your team will need to have the capacity to frequently produce and publish new content in order to persuade users to buy an upgrade and keep them coming back for more.

D. In-App Purchases

This is a great way to add a new revenue stream to your business. Specifically, if you already sell products and services on your website or in a physical location, creating an app that makes it even more convenient for your customers to shop with you might be a viable option to consider.

Other popular app monetization methods include app sponsorships, subscriptions, along with strategic partnerships and affiliations (we’ll cover these in a future article).

4. Define What Success Looks Like

Once you’ve outlined your objectives and monetization plan, you should define how you’ll track and measure your app’s success. One of the many wonderful aspects of owning an app is that you have the opportunity to gather meaningful user insights and analytics. To attain such data, ensure that your app developer has a plan to track user behaviour. Some key performance indicators you may find useful (depending on your goals) include app engagement (such as time spent in-app), average daily active users (DAU) and average monthly active users (MAU), purchases, installs, subscriptions, conversion rate, and more. You should also monitor user reviews in App Stores – doing so can help you stay in-tune with your user base and discover how to improve your app over time.

5. Consider Future Releases

So, you’ve done your research and defined your goals and monetization plan, now it’s time to consider what the future of your app looks like. Releasing version 1.0 of your app is nothing short of exciting, but even more compelling is the future plans you have. Like most things in business, apps need to change over time to evolve and improve with shifting consumer (or employee) trends, technology and competitors. To build an app that keeps users engaged, you should create an app roadmap that encompasses your future releases. Business Insider notes that more frequent updates are typically associated with higher app user ratings. This can be attributed to several factors, including app improvements such as added features and bug fixes. Further, since users receive push notifications about each app update, apps that are updated more often will benefit from increased top-of-mind awareness.

6. Put User Experience First

As we’ve mentioned in a previous post, 6 Reasons Your Enterprise Mobile App Needs Quality Assurance Testing, if you want consumers or employees to actually use your app, it’s key to make user experience a top priority. Your brand image – both in the eyes of your employees and consumers—is at stake every time you build a new app or release an update, so be sure that you’ve hired the right mobile app development partner. This partner or agency should be experienced at building best-in-breed apps across platforms and devices that provide a seamless user experience (UX) and interface (UI). You can learn more about choosing the right mobile app development partner in this Atimi blog post.

Now that you have a feel for what your app mobile strategy might look like, get in touch with us – we’d be happy to help you solidify your mobile strategy and build an app that your users will love.

Feel free to give us a call. We’re always happy to chat.

778-372-2800

info@atimi.com

5 MOBILE APP DEVELOPMENT TRENDS TO WATCH IN 2017

img

With the New Year in full swing, it’s a good time to reflect on last year’s advancements in mobile technology and look at what’s in store for app development in 2017. Here’s our list of the top app dev trends to watch this year.

1. Security

As more organizations instate “bring your own device” or “BYOD” policies, you can bet that enterprise app hacks will occur more frequently. This can be attributed to employees using the same device for both personal and business use, which tends to pose vast security risks to organizations and their data. As one Security Innovation Europe article states, “employees are putting their organisation’s data at risk if they adopt poor security practices in their own time.” For instance, one of the most prevalent security threats occurs when employees access unsecure Wi-Fi connections in places such as airports and shopping malls. By using corporate devices and apps while connected to these unsecure servers, employees may unwittingly share their login credentials with strangers. Additionally, they could be sharing the documents they’re working on along with content their viewing on websites and more – all of which may provide hackers access to highly confidential corporate information.

While cyber crime is on the rise, you can protect yourself and your company data by ensuring that the enterprise app development partner you choose offers stringent risk management policies and procedures, as well as built-in app security features.

If you aren’t sure where to start when building an app, check out our article on outsourcing mobile app development.

2. The Internet of Things

With the continued explosive growth of the Internet of Things or IoT (devices that connect to the internet such as smart watches and smart home items like Nest), apps that can connect to IoT devices are sure to be popular in 2017.

If you’re thinking about creating an enterprise mobile app, you may want to consider building one that can connect to IoT devices, for instance, employee activity trackers or smart watches. Connecting your enterprise app to IoT devices that employees and vendors use is a great way to boost app adoption and engagement.

Not only will we see more mobile apps connecting to IoT this year, it’s a trend that will continue growing for the foreseeable future. One Gartner study recently estimated that the number of connected things in use in 2016 was 6.4 billion – and that number will reach 20.8 billion by 2020.

Source

3. Augmented Reality

With the incredible success of the Pokémon Go app – the most downloaded iOS app in 2016 — businesses everywhere have taken notice and are looking at how they can cash in on the augmented reality (AR) mobile app trend. One of the reasons that Pokémon Go and other AR apps have done so well can be attributed to their highly interactive user experience. As one Forbes tech contributor recently stated in an article, “The mainstream shift toward AR and VR provides new ways to connect with customers and offer unique, memorable interactions.” This couldn’t be truer. As more companies gain momentum with AR apps, others are sure to follow. AR is a hot trend to watch in 2017 and you can be sure that Atimi Software will be there to help you navigate the AR enterprise app space.

4. Virtual Reality

Virtual reality (VR) headsets, like the Oculus Rift and Samsung Gear VR – both of which launched last year – have kick-started a new era of mobile app innovation. From healthcare to national defense, retail and beyond, VR is continuing to grow in popularity and will certainly be a space where more enterprise mobile apps can and will thrive. The booming consumer interest in the immersive experience that VR provides along with the fast-growing number of VR headsets available means that there’s plenty of opportunities for VR apps to flourish.

Source

5. Automation

From Google’s self-driving cars to Facebook’s chatbots, automation is a growing trend that experts suggest is here to stay. As Wealth Daily recently explained, “while automated technology has already begun to creep into our daily lives, what we see today is nothing compared to what the future holds…Investors will specifically want to look for the companies taking advantage of this technology, the companies providing it, and the supply chains that support it all.” This is because automation saves companies and individuals time and money.

Source

This year and in the years after, you can expect to see enterprises creating more intelligent chatbots that help with onboarding employees – reducing the financial and time costs associated with hiring and training. Further, the World Economic Forum predicts that “automation of checkout processes and smart inventory management through sensors and other applications of the Internet of Things” will lead to a reduced demand for traditional sales-related roles. Suffice to say that automation is here to stay – it isn’t just a trend. This disruptive technology is and will continue to change the way we work, live, and interact with companies and brands. It’s a space that we at Atimi see as having endless opportunities for enterprise apps.

Now that you know the top five enterprise mobile app trends to watch this year, you’re in a better position to build an enterprise app that’s both relevant and engaging.

Get in touch with us to find out how Atimi Software can help you build a custom, innovative, enterprise app that offers a superior user experience and stands the test of time.

778-372-2800

info@atimi.com

OPTIMIZING DEVICE FRAGMENTATION TESTING

img

There are a number of issues that are regularly cited as the main problems with testing mobile apps: fragmentation of devices/manufacturers, OS versions, networks (changing connection types and speeds), usability, testing tools, automation and security. Whilst some are complex and require skilled and experienced testers, some of these can be overcome with a bit of knowledge of mobile apps and a good plan. I want to talk about one specifically and offer the benefit of our experience.

The fragmentation of the device market, especially Android (although more recently the iOS family has grown as well!), is overwhelming. You can find infographics that will graphically display the overabundance of devices. How can you test all these devices, and if not, how do you choose a reasonable set of devices to test?

For the purposes of this article I will focus on Android devices, and I am not considering OS version. The principles are the same whatever the platform is.

1. Factors

There are a number of key factors that we will need to consider:

* Screen size and screen resolution

* Device manufacturer

* Carrier

* Processor chipset

* Memory

* User demographics

* App design

Firstly, lets get rid of the least important ones starting with device manufacturer and carrier as these have very little impact on the performance of the app; we find very few issues that are specific to either of these factors. And you can cover a number of different manufacturers when making your device selections anyway.

Processor chipset and memory will affect the performance and that is why you need to consider app design. If your app is primarily downloading content from a web service and displaying it in a simple UI, the biggest influences on performance are network bandwidth and web service performance. The device performance will not have a significant impact. If your app is a UI heavy game, then you will need to test on high-end and low-end devices.

The profile of the expected users of your app will also have an influence: are you expecting affluent, low-cost, or a wide range of users. And then you may not have that information to be able to make a choice based on this factor.

Screen size and resolution are the biggest factors for most consumer apps. This also includes aspect ratio and portrait/landscape rotation. Designing your UI to work across the range of possibilities effectively whilst maximizing the appeal of your design is a challenge. The size and position of buttons and other user input controls, dynamically resizing UI controls and text, and scrolling and zooming controls are just some of the issues that you need to test for.

2. Selection Method

One of the most useful pieces of information you can have for selecting your set of devices is usage data. The volume of sales for each device is interesting but far more useful is, what devices are being used with apps that are similar to yours. If you have a mobile-friendly website that is being used by a similar group of users to those you expect to use your app, you can look at the profile of devices from that. If not, there are a few places that publish usage data by device type. You can look at those and decide whether they are close enough to your app. This will give you a long list, with each device type probably only accounting for a few percent of the traffic.
Next you need to find the screen size and resolution for each one – this may take a while first time round. Then if you are repeating the exercise every quarter, the number of new devices that will appear in your list will be relatively small. Once you have the screen size and resolutions, you will see that the devices will start to fall into groups. You can then select a single device from each group to represent that group.

How do you select which device represents each group? You then consider the following factors:

User profile – If you have a specific target group of users, does this affect your selection based on the price of devices? (Make sure your original list of devices was relevant to the geographical area you are considering.)

App performance – Is there an aspect of the app that will be affected by the processor, graphics chip, or memory? If so, select from high and lower performing devices.

Manufacturer – Select from a range of manufacturers.

And finally, pick devices you want to test. If there is a device that has just been released so it won’t appear on historical usage stats and despite that it is interesting to you, pick it. I’ll talk in the test planning section below about how you can test additional devices without significant extra effort.

3. Test Planning

Let us create an imaginary test suite that is 40% functional tests, 10% performance tests, and 50% UI tests. You have selected six devices to test. One approach you can take to avoid running every test on every device is to spread the functional tests across all six devices, running each test only once per cycle of testing. In subsequent test cycles, you can swap the devices used for a test to gain more coverage.
The UI tests can then be split into two sets: those that are unlikely to be affected by screen size/resolution and those that will. Again, you can spread the first set of tests across all six devices. You are then left with only the UI tests affected by screen size/resolution that you need to run on all devices. If you have performance issues for the app, then you would run the performance tests on the highest and lowest performing devices.
With this risk based approach, you can reduce the amount of testing from all tests on all devices by 60%.

4. Conclusion

Device fragmentation can be daunting when you first consider it. However, with careful consideration of the parameters of your app and your target audience, and systematic analysis of the available devices, you can achieve wide coverage without an excessive increase in testing effort. Or you can engage Atimi’s QA team and we will work with you to create and execute the optimum test suite.

Get in touch with us to find out how Atimi Software can help you build a custom, innovative, enterprise app that offers a superior user experience and stands the test of time.

778-372-2800

info@atimi.com

5 REASONS TO OUTSOURCE YOUR MOBILE APP DEVELOPMENT

img

From harnessing the power of big data to adding a new stream of revenue to your business, there are hundreds of reasons why you may have decided to build an enterprise mobile app for your brand. Now that you’ve determined that a custom mobile app makes sense for your business, it’s time to select an avenue for building it.

There are two ways in which you can go about developing your mobile enterprise app: you can outsource your development (have someone or an agency build it) or insource it (have an in-house app developer or a team of them build it).

With each of these options comes a list of pros and cons but to keep it simple we’ve put together a list of the top reasons why you should outsource your mobile app development to a third party agency.

1. Speed up development time

Mobile app development agencies such as Atimi specialize in mobile app development. They are highly motivated, experienced in developing custom apps for various types of clients across platforms such as Android and iOS, and they have the know-how to work efficiently and effectively.

On the contrary, an in-house developer may not be as experienced as developers at an agency and, as a result, may take longer to create your app and later find and fix bugs. In addition to a lack of experience, in-house developers often have competing priorities and daily tasks outside of building your mobile app. This can further reduce the time it takes to launch your app.

Hiring an outsourced app development partner can be extremely cost effective in terms of time and money since they’re well-versed in the app development space and their sole focus will be your project, so in the long run you’ll be better off outsourcing all or at least part of your app development.

2. Save on hidden costs

While insourcing your app development team may appear to cost less on paper than outsourcing to an agency, when you add in hiring expenses plus training (not to mention employee benefits), the cost of time (typically, in-house teams can’t complete projects as quickly as a dedicated, specialized agency), the cost of developing in-house can quickly escalate. This is why outsourcing often proves to make more sense financially – the hidden costs associated with hiring in-house developers simply do not exist when working with a third party.

3. Maintain control over your app

It’s a common myth that outsourcing your app development limits the control you’ll have over your app. In reality, this is not the case. As Rahul Varshneya states, “The trick is to set up systems that work efficiently and create a process of delivery and communication. Create a weekly sprint to review direction of the project. Have a daily stand up on what is expected as tasks of the day and review the previous day. Document everything in emails.” In short, if you communicate well with your chosen app development partner, you won’t lose any control.

4. Higher productivity

If you insource your mobile app development, you can expect your developers to have a thousand other projects on the go. Further, your developers may not be interested in mundane post-launch maintenance tasks such as updating for new iOS and Android versions, bug fixes and so on. This could result in a lack of motivation to maintain the app, causing slower app version releases, code error oversights and more.

Alternatively, when you outsource an app development company such as Atimi, you can rest assured that they’ll be highly engaged and motivated as their job is to cater to you. Your app’s success is their success. When your mobile app developer (or in this case, app development partner) is motivated, they will be far more productive. Again, let the specialists handle the large and mundane tasks – we at Atimi love everything about what we do, which is why we’ve developed hundreds of premium apps for some of the largest brands in North America.

5. Keep peace of mind – you’ve hired experts

Hiring a third party app development partner means you get to have peace of mind in knowing that your app is being built by experts you can trust. Speaking from an app development agency standpoint, we at Atimi understand the ins and outs of app development across multiple platforms and devices. We are experts at what we do and can help create your dream app complete with a solid user experience and seamless user interface – all on time and on budget. The bottom line: let the app specialists handle the app development so that you can focus on other areas of your business.

Now you’ve discovered the benefits of outsourcing your app development to a third-party agency, but whether your development choice is to insource or outsource, look no further than Atimi Software. Based in Vancouver, BC, we are a full-service mobile app development firm. We offer custom engagement that includes 100% outsourcing, or insourcing support where we can work alongside your team to make them stronger and more efficient. Atimi can consult on your complete mobile strategy that includes project management, user retention as well as mobile app monetization.

Interested to learn more about how we can help you create your enterprise mobile app? Feel free to give us a call. We’re always happy to chat.

778-372-2800

info@atimi.com

CAP HEIGHT ALIGNMENT FOR IOS AUTO LAYOUT

img

Many times graphic designs include the need to align text vertically at cap height (the top of the capitals) and baseline. For example, someone displaying a list of news articles might want to align the cap height of each article title and the baseline of the associated description with the thumbnail image (as shown in the figure below). iOS Auto Layout already supports baseline alignment for vertical (as well as horizontal) layout, but there is no built-in mechanism to deal with cap height. This article will show you how this can be done with a simple subclass of UILabel.

A Short lesson in iOS Typography

Before getting into implementation, let’s just run through the terminology that will be needed. The figure below is taken from Apple’s Text Programming Guide for iOS and shows the various vertical measures used in layout.

The important terms (along with their UIFont property names) for this discussion are:

• Line height (lineHeight) is the distance from one line of text to the next;

• Baseline is the vertical origin of the text, that is, the line upon which the characters stand;

• Ascent(ascender) is the distance from the baseline to the top of the text cell (including space for accents and the like);

• Descent(descender) is the distance below the baseline to the bottom of the text cell;

• Cap height(capHeight) is the distance from the baseline to the top of the capital letters.

Because of the additional space for accents and the like, a font’s ascent is typically higher than its cap height. Therefore, even when a UILabel (or other text view) is sized to hug its content, it will still have a gap between the top of the view and the top of the text.

Curiously, the diagram shows space below the descent for line gap (leading), but there is no corresponding property in UIFont—there is a “leading” property, but it is synonymous with the line height property. Having surveyed all the fonts currently available on iOS, the line gap appears to be universally zero and so will be ignored for the rest of this discussion.

Changing the Meaning of “Top”

It may come as a surprise, but when Auto Layout does alignment it does so against a view’s alignment rectangle and not simply its edges. By default, this alignment rectangle is the same as the view’s frame, but it can be different. For example, suppose a view displays an image within some custom border. It may be more appropriate to align layout against the image and not include the border.

We can use this feature on the labels for which we want cap height alignment. UIView defines a number of methods that can be used, but the simplest is alignment RectInsets, which returns a UIEdgeInsets specifying the insets of the content with respect to the frame. The default implementation returns UIEdgeInsets.zero but if we subclass UILabel we can override it as follows:

override var alignmentRectInsets: UIEdgeInsets {
var insets = UIEdgeInsets.zero
insets.top = round(font.ascender – font.capHeight)
return insets
}

This simply defines the top margin to be the gap between the ascender and the cap height of the label’s font, causing Auto Layout to shift the meaning of “top alignment” into the view so it rests on the cap height instead.

This is all that is needed for basic functionality. Wherever cap alignment is required, just replace the UILabel with its subclass and Auto Layout top alignment will align with cap height instead—well, approximately so; see below for a more accurate calculation of cap height positioning.

This simply defines the top margin to be the gap between the ascender and the cap height of the label’s font, causing Auto Layout to shift the meaning of “top alignment” into the view so it rests on the cap height instead.

Of course, having to switch the class of the label whenever we want to change alignment could get annoying, particularly if a graphic design requires a dynamic switching from top to cap height. To support this, we can introduce a boolean property (alignCapHeight) to control the type of alignment. Our revised alignment RectInsets now looks like:

override var alignmentRectInsets: UIEdgeInsets {
var insets = UIEdgeInsets.zero
if alignCapHeight {
insets.top = round(font.ascender – font.capHeight)
}
return insets
}

As the alignment method is only called during layout, we also need to ensure that Auto Layout is rerun whenever the property changes:

var alignCapHeight: Bool = false {
didSet {
setNeedsUpdateConstraints()
}
}

Working With IB

Great, but wouldn’t it be nice if the new vertical alignment showed up in IB? Well, that’s easily fixed: just add the @IBDesignable designation to the class definition as follows:

@IBDesignable
class CapHeightLabel: UILabel {

}

This tells IB that the class will co-operate with it to display correctly. In our case, this just means that IB will instantiate the label object and execute the alignmentRectInsets method so the positioning by IB’s Auto Layout matches the runtime.

Likewise, we can surface our align CapHeight property to IB using @IBInspectable

@IBInspectable var alignCapHeight: Bool = false

This makes the property accessible in the attributes inspector (per the screenshot below). This is pretty cool—as you change the Align Cap Height attribute, IB will automatically update the layout so you see the impact in realtime.

A More Accurate Cap Height

In the code above, we approximated the cap height position by calculating the rounded difference between the ascender and the cap height. However, this is a very naive approach, given how text is actually rendered, and so the method is only accurate to ±1 point. To understand why this is so, and how to calculate a more accurate position, we need to work through how the text is actually rendered in a UILabel.

Suppose we have a label that is using a 24pt Helvetica font. That font will have the following metrics:

The fractional part of each number is important. When the font engine renders the glyphs it uses anti-aliasing to simulate the fractions of pixels, as shown in the enlarged image below. The other point to note is that glyphs are always laid out with respect to the baseline, and so the baseline is always on a pixel boundary.

Starting with lineHeight, we can see that it is the sum of the ascender and descender. However, as baseline is always on a pixel boundary, the actual line height of the rendered font must be an integral number of pixels. Also, as fractional parts are simulated through anti-aliasing, the line height cannot be rounded to the nearest pixel without risking the last partial pixel being clipped. Therefore, the calculated line height will be ceil(lineHeight).

This same principle holds for ascender and descender. Each may have a fractional part that needs to always round up to the next pixel. However, there is a catch, ceil(lineHeight) does not always equal ceil(ascender) + ceil(descender). Sometimes the calculated line height is one pixel shorter than the sum of the calculated parts. In such cases, the descender is given precedence on the basis that many common glyphs have descenders, whereas only a few diacritical marks touch the top of the ascender.

To find the position of the baseline within the label, we should move down by the calculated line height and then back up by the calculated descender. (Point of detail, for UIFont the descender is always expressed as a negative value because the Y access is “up”—all calculations therefore need to take this into account.)

With the baseline calculated, we can move up using the capHeight. However, in this case we actually do want to round to the nearest pixel as the visual position will depend on whether the fractional pixel is more or less than 50% opacity.

This gives us a more accurate adjustment calculation of:

ceil(lineHeight) – ceil(-descender) – round(capHeight)

However, there is one more consideration. All the metrics are in points but the rounding occurs at the pixel boundary. Therefore, the final calculation needs to handle the screen scaling as follows:

(ceil(font.lineHeight * scale) – ceil(-font.descender * scale) –
round(font.capHeight * scale)) / scale

Here is the final version of the code:

override var alignmentRectInsets: UIEdgeInsets {
var insets = UIEdgeInsets.zero
if alignCapHeight, let scale = window?.screen.scale {
insets.top = (ceil(font.lineHeight * scale) – ceil(-
font.descender * scale) – round(font.capHeight * scale)) / scale
}
return insets
}

Final Considerations

What has been presented here works for UILabels, but the technique can also be applied to UITextField and UITextView. Also, it could be extended to support UILabels that use attributed strings (though it would be difficult to achieve a general solution for multi-line, multi-font labels).

It does not handle labels where the bounds do not hug the content. Although this can be calculated, there seems little practical use as it implies constraints that align both the content and the frame itself.

778-372-2800

info@atimi.com

6 REASONS YOUR ENTERPRISE MOBILE APP NEEDS QUALITY ASSURANCE TESTING

img

According to a recent Smart Insights study, 90% of consumers’ time spent on mobile devices is expended in mobile apps. Because of this proliferation in app usage, brands everywhere are rushing to create their own enterprise mobile apps, which often tend to fail due to bugs and other quality issues that could have been prevented if these apps had been put through proper quality assurance (QA) testing.

To help you better understand why quality assurance is crucial, we’ve put together this list of reasons why your enterprise app needs proper QA testing:

1. Preserve & enhance your brand’s reputation

In the same way that your website, staff, and marketing collateral speak to the quality of your brand, products and/or services, your app is another reflection of your business. If your app provides a subpar user experience, your brand image could be tainted in the eyes of your app users. Think of it like this: the quality of your brand can be equated with your app. If your app crashes or doesn’t function the way it should, users will complain about it in a public forum. The last thing you want to do is upset your users and have them vent their grievances in app store reviews or on social media. Bottom line: Keep your reputation strong so that more users will download your app and give it the positive engagement and reviews it deserves.

2. Prevent users from uninstalling your app

Did you know that, according to a recent Android Authority article, 77% of users never use an app again just 72 hours after they’ve installed it? Should your mobile app provide a poor user experience, it could wind up where thousands of apps have gone before – to the app graveyard where users uninstall or simply no longer engage with your app. If you don’t want your app to be abandoned by your users, it’s paramount that you have a process in place for thorough quality assurance – it’s crucial that you fix bugs and prevent them from popping up before your app launches in the app stores.

3. Increase app installations & engagement

Building on the previous point, if you have the right QA in place throughout your app’s development process, your app will run smoothly and provide an optimal experience for your users. And if that’s the case, you’re sure to foster app engagement, positive app store reviews, and a lift in new installations – all of which should be every developer’s goals. To restate point number one, having a high-performing app with a smooth user experience will help to bolster your brand in the eyes of consumers and other stakeholders.

4. Save cash in the long run

It’s important to keep in mind that developing an enterprise mobile app is an investment. You’re investing time and money into building an app that you hope everyone will love and use for a long time. While you may expect to receive a high return on your investment, this can and will not happen if your app fails due to low quality UI (user interface), unstable infrastructure, functionality and/or usability – issues like these will be more costly to your business than you can imagine for a number of reasons:

• App stores may penalize you, making you remove the app, fix the issues and then re-submit it for approval (which can take weeks in some cases – using up your developers time and your budget).

• As mentioned, users may get frustrated with your buggy app and vent on social media and in app store reviews, resulting in poor word-of-mouth, a reduction in new app installs, app engagement and overall perceived brand quality, which could hinder your business for years to come.

• It is far more expensive to find and fix bugs in an app later in the development process than it is to find and fix them in the early stages. As this Agile Modeling essay states, “the cost of fixing errors increases exponentially the later they are detected in the development lifecycle because the artifacts within a serial process build on each other.” In short, it is much wiser to have proper QA processes implemented right from the start of your app build. This way, you can rest assured that your app development partner will locate and resolve bugs earlier in the development process – saving you time and, potentially, exorbitant costs.

5. Decrease the threat of security-related issues

If you don’t run your app through thorough testing, you run the risk of compromising your users’ data security — and that PR nightmare is certainly not worth the risk! Be sure to have your QA team run tests on everything including basic things like app updates. Doing so will help to ensure that your users (and ultimately your brand’s reputation) are protected.

6. Reduce risk of future app problems

By having the right app QA and testing processes in place, you’ll significantly reduce the risk of experiencing issues with your app when it launches. By ensuring your mobile app functions the way it was meant to and provides a strong user experience from the get-go, you’ll be safeguarding your investment by preventing unnecessary developer “cleaning up” costs.

To further reduce the risk of app malfunctions, it’s highly recommended that you hire a QA specialist for a number of reasons, including the fact that a fresh set of eyes can help point out bugs that may not have otherwise been discovered by your in-house team.

Beyond the basic functionality and security testing on an app, QA specialists ensure apps run properly on all of the operating systems and devices that the app was intended for. Because of the broad range of devices (from the iPad Air, to iPhone 7, Google Pixel and more), you must consider the different environments that your app will be used in. Will your smartphone app work on all versions of an operating system (OS), such as Android or iOS? What about different devices with different screen resolutions/sizes? You could make it the responsibility of your developer to test your app across devices and platforms, but that’s not likely to be their skillset. In other words, your developer’s time is best spent developing, so it’s recommended that you engage with a QA specialist who is as enthusiastic about testing as they are efficient at it.

At Atimi Software, We specialize in extensive QA testing to help ensure that your app functions flawlessly and your mobile app users have an extraordinary experience. Atimi’s proprietary scripting tools deliver complete cross-platform automated testing for any platform, substantially increasing the amount of bugs we’re able to locate and fix.

Now that you know how important it is to incorporate QA testing when developing enterprise mobile apps, you may be interested in seeing what our quality assurance process looks like. To get a feel for how we work, or if you have any questions or want to learn more about Atimi and how our experts can work for you, feel free to give us a call. We’re always happy to chat.

778-372-2800

info@atimi.com

6 THINGS TO CONSIDER WHEN CHOOSING A MOBILE APP DEVELOPMENT PARTNER

img

So, you’ve recognized that there’s a need to build a mobile app for your business, but you’re not quite sure where to start in terms of seeking a mobile app development partner. There are a large number of app development partners out there from small boutique app development agencies to large-scale corporate firms (of course we want you to choose Atimi, but even if you don’t, you should at least know what to look for so you can find the right fit for you).

Here’s our list of the top considerations you should take when shopping for a mobile app development partner:

1. Agility

Much like in business, the competitive landscape in the app world is ever-changing and if you’re going to stay ahead of the curve, it’s paramount that the app development partner you choose is one who can stay nimble and adapt to your business’ changing needs. If your app development partner isn’t willing to negotiate on scope of work when necessary, they may not be the right partner for you. You need them to be mindful and understanding of the fact that things change and they should be more than willing to shift scope or focus as needed. Be sure to ask your potential vendors for an example of when something changed during development and how it was dealt with. This behavioural-type question will help you assess whether or not the company handles change well.

In addition to being flexible, you should look for an app development partner who has expertise and experience in working with different budget sizes and project processes – the last thing you want is a vendor who encourages sweeping changes to a project and runs wild with your budget.

2. Likability

Hiring a mobile app development partner is not a task to be taken lightly. Since apps require updates and maintenance from time to time to suit end user feedback, operating system updates, and more, the relationship you have with your app development partner doesn’t end once your app is released. Because this is not a short term relationship, you need to be sure that you and your team actually like the people you’re going to be working with. Just like you would consider culture fit when hiring a new employee, you should consider culture fit when hiring a mobile app development partner. For instance, if you’re company prides itself on professionalism and accountability, you certainly wouldn’t want to work with a vendor who is opposite to that.

At Atimi, we believe in open communication and collaboration. It’s important for us to keep our clients informed with scheduled status updates so that we ensure we’re all on the same page in terms of progress and priorities. We also believe strongly in holding one another accountable. These are just a few of the ways we keep our clients happy and in the know – every step of the way.

3. Engagement Capabilities

Think about how you and your team would like to be engaged in the app building process; do you want a developer and/or engineer to be on-site with your in-house team working alongside them (insourced), or would you prefer for everything to be outsourced (completely handled outside of your office)? Ask the app development partners you’re speaking with to run you through their process. If you want to be completely collaborative and hands on during app development, you may be better off hiring an app development partner who can provide that. You wouldn’t want a vendor coming in – not knowing what your business needs are – and being too overbearing or too underwhelming in their approach to app development, so be sure to find a partner who offers custom engagement, the way that we do at Atimi. We understand that each and every client and project has unique needs. That’s why we’ll work on or off-site and inject our expertise into your in-house development team, stand them up, and get the project completed on time and on budget.

4. Proven Success

Key point: Just because they say they’re awesome doesn’t mean they are. Do your due diligence before hiring an app development partner; when you’re in a meeting with a potential vendor, ask them to provide you with examples of apps they’ve developed – you may even go so far as to download those apps to get a feel for the overall user experience they provide. If they’re good, great! If not, move on and continue your search. Additionally, ask about the developer’s professional experience. It’s important to know that whichever app development partner you choose has experience building apps across mobile platforms and devices. In addition to finding an app development partner who has experience and a strong portfolio, you should consider finding a vendor who partners with popular operating systems, such as Apple. At Atimi, we’re proud to be an Apple Mobility Partner. We’ve been a part of the AMP program since the first iPhone launched and the opening day of Apple’s App Store. Not to toot our own horn, but we’re one of a select few of Apple Mobility Partners in North America.

5. Business Savvy & Client Focused

Sometimes, IT people don’t speak the same language as the business execs, which can be challenging when deciding on app features and functionality. Because of this, it’s of utmost importance that you find a mobile app development partner who communicates effectively and understands that, at the end of the day, you’re running a business and your app needs to accomplish specific business objectives. This type of business-savvy partner will help ensure a smooth app development process for everyone involved – sans miscommunications and headaches.

At Atimi, we understand that you have important business goals and KPIs, so we keep you, your end users’ experience and your bottom line at the forefront of everything we do.

6. Quality Assurance

This is a piece that often gets left out of these types of articles, but it should be one of the key things to consider when hiring a mobile app development partner. Without proper quality assurance (QA), your app is destined to fail. As mentioned in a previous Atimi Blog post, user experience is everything. You must provide your users with a seamless, extraordinary experience if you want your app to be successful. If your app isn’t regularly and thoroughly tested, you could find your users frustrated and annoyed, giving you poor reviews in the app stores and uninstalling your app altogether – not a road you want to go down.

At Atimi, our robust QA process ensures that your app features remarkable functionality. Our proprietary scripting tools deliver complete cross-platform automated testing, substantially increasing the amount of bugs we’re able to find and remedy. We take pride in our work and do everything in our power to ensure the mobile app we develop for your business provides your users with a stunning user interface and experience.

Hopefully you will find this useful. If you have any questions or want to learn more about Atimi and how our experts can work for you, feel free to give us a call. We’re always happy to chat.

778-372-2800

info@atimi.com

SIMPLE JSON PARSING WITH SWIFT3

img

Many mobile applications rely on JSON-based web services for their data. For iOS, there has long been ample JSON support through third-party libraries and, since iOS 5, NSJSONSerialization. The typical output of such is a dictionary containing other dictionaries, arrays, numbers and strings, which works very nicely for Objective-C but can present some problems for the strongly typed Swift. However, using Swift’s powerful support for enumerations, this common task can be just as straightforward without compromising good type checking.

The Joy of JSON

JSON is a lightweight data-interchange format that is great for many classes of web service. It allows the transmission of simple object graphs in an easy to read form (both for developers and code).

Here is an example of a contact record for Johnny Appleseed:

{
“type” : “person”,
“first name” : “Johnny”,
“last name” : “Appleseed”,
“nickname” : null,
“age” : 42,
“phone numbers” : [
{
“type” : “work”,
“number” : “+1 (555) 555-5555”
},
{
“type” : “home”,
“number” : null
}
],
“work address” : {
“line 1” : “1234 5th Avenue”,
“line 2” : null,
“city” : “Hometown”
},
“home address” : null
}

Whether or not you have seen JSON before, you have probably already figured out the data structure: the name and age are simple attributes; the work and home addresses are objects (though we don’t have his home address); and there is a list of phone numbers, each of which is its own object.

The Previous State of Art

Now, suppose you are writing an application that consumes a web service that returns the JSON example from above. Once the data has been read from the network it can be converted into a dictionary like so:

NSError* error = nil;
NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];

(Actually, JSONObjectWithData:options:error: returns an ID but the code has been kept simple for illustration.)
With the object parsed, it’s possible to start extracting information of interest:

NSString* firstName = jsonObject[@”first name”];
int age = [jsonObject[@”age”] intValue];
NSString* workCity = jsonObject[@”work address”][@”city”];
NSLog(@”%@ is %d years and works in %@”, firstName, age, workCity);
// Johnny is 42 years and works in Hometown

That looks pretty straightforward but there is a gotcha lurking in the code. Although getting the work city was fine, the same code for Johnny’s home town will throw an exception. To see why it is necessary to understand what actually happens when the expression jsonObject[@“home address”][@“city”] is evaluated. At runtime, this breaks down into the following:

id temp1 = [jsonObject objectForKey:@“home address”];
id temp2 = [temp1 objectForKey:@“city”];
NSString* homeCity = temp2;

Looking back at the sample JSON, “home address” is null, so you might think that temp1 will be set to nil and, as every good Objective-C developer knows, invoking a method on nil returns nil, which means homeCity will be nil, right?

Wrong. The trouble is that NSDictionary does not allow nil as a value so the parser sets the value to the null singleton, [NSNull null]. This is not the same as nil; it is an object, and invoking objectForKey: triggers an “unrecognized selector” exception.

To handle the sample correctly, we need to explicitly test for the missing address:

NSString* homeCity = nil;
id homeAddress = jsonObject[@”home address”];
if ([homeAddress isKindOfClass:[NSDictionary class]])
{
homeCity = homeAddress[@”city”];
}

Unfortunately, this is the tip of quite a large iceberg: what if “city” is null, or “first name”? And what about “age”? Suddenly, three lines of code have become twenty! Well, to be fair, you could condense the checks to keep to three lines but it gets pretty ugly…

NSString* firstName = ([jsonObject[@”first name”] isKindOfClass:[NSString class]] ?
jsonObject[@”first name”] : nil);
int age = ([jsonObject[@”age”] isKindOfClass:[NSNumber class]] ? [jsonObject[@”age”] intValue] : 0);
NSString* workCity = ([jsonObject[@”work address”] isKindOfClass:[NSDictionary class]] ?
([jsonObject[@”work address”][@”city”] isKindOfClass:[NSString class]] ?
jsonObject[@”work address”][@”city”] : nil) : nil);

Enter Swift

How does this same code play out in Swift? First, here is the equivalent of the first Objective-C version.

let jsonObject: Any = try JSONSerialization.jsonObject(with: data, options: .allowFragments)

let firstName = (jsonObject as! [String: Any])[“first name”] as! String
let workCity = ((jsonObject as! [String: Any])[“work address”] as!
[String: Any])[“city”] as! String

Already you can see the type safety pushing into the frame with the explicit casts to NSDictionary. And in addition to the NSNull issue already highlighted, the Swift code will also fail if any of the JSON elements are plain missing, which would have worked in the Objective-C code. To successfully get the home city requires the following:

var homeCity: String?
if let jsonDict = jsonObject as? NSDictionary {
if let address = jsonDict[“home address”] as? NSDictionary {
if let city = address[“city”] as? String {
homeCity = city
}
}
}

As with Objective-C, the Swift code can be collapsed into a single line, as long as you’re prepared for a very long line full of parentheses and question marks.

Wouldn’t it be good if you could have the compact style of the original Objective-C with all the type safety of Swift. How about something like this?

let jsonObject = JSON.parse(data!)
let firstName = jsonObject?[“first name”]?.string
let age = jsonObject?[“age”]?.int
let workCity = jsonObject?[“work address”]?[“city”]?.string

A Node by Any Other Name

What we want to make this happen is some sort of wrapper around the data that can do all the heavy lifting for us without getting in the way of chaining down the data tree to get at deeply embedded values. It turns out that Swift enumerations are an ideal solution.

Firstly, we want to define an enumeration that can wrap a JSON value. Because Swift enumerations can have associated values, we can neatly package type-dependent values.

public enum JSON : CustomStringConvertible {
case array([Any])
case dictionary([String: Any])
case string(String)
case number(Double)
case bool(Bool)
case null
}

Though very neat, it’s not very useful in itself. However, because enumerations are first-class types, we can add code to do all that work we had to previously do by hand. (Note that all the methods that follow belong to the enum – we are just presenting them separately for annotation.)

The first task is to generate a wrapped JSON value. Let’s define a static method to do this:

public static func wrap(_ json: Any) -> JSON {
if let str = json as? String {
return .string(str)
}
if let num = json as? NSNumber {
if (num.objCType.pointee == 99) { // check if objCType == ‘c’
return .bool(num.boolValue)
}
return .number(num.doubleValue)
}

if let dictionary = json as? [String: Any] {
return .dictionary(dictionary)
}
if let array = json as? [Any] {
return .array(array)
}
assert(json is NSNull, “Unsupported Type”)
return .Null
}

The method simply inspects the supplied value and returns the appropriate enum with the value associated. (Note the use of objCType to determine if the original JSON value is a boolean. This works but is not guaranteed by the documentation. Consequentially, you may choose to drop support for the .bool value and treat all JSON booleans as integers.)

While we’re thinking about wrapping, we might as well define a convenience method to parse JSON data into our enum.

public static func parse(data: Data) -> JSON? {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
return wrap(json)
} catch {
return nil
}
}

Pretty straightforward: use NSJSONSerialization to parse the data and, if successful, wrap it in our enum. Of course, for a full implementation you may want some error handling, and probably define other parse methods that take the data in other formats.

Having created a JSON enum, let’s define ways of getting at the data. First, we can define computed properties that provide type-safe access to simple values:

public var string: Swift.String? {
switch self {
case .String(let s):
return s
default:
return nil
}
}

public var int: Int? {
switch self {
case .Number(let d):
return Int(d)
default:
return nil
}
}

public var double: Double? {
switch self {
case .Number(let d):
return d
default:
return nil
}
}

public var bool: Bool? {
switch self {
case .bool(let b):
return b
default:
return nil
}
}

Notice that, in each case, the value is returned if it matches the expected type, otherwise the result is nil. Testing for null itself requires a slightly different pattern but the principle is the same.

public var isNull: Bool {
switch self {
case .null:
return true
default:
return false
}
}

For returning dictionaries and arrays, we need to do more work because we need to wrap each value in the collection with a JSON enumeration value.

public var dictionary: [Swift.String: JSON]? {
switch self {
case .Dictionary(let d):
var jsonObject: [Swift.String: JSON] = [:]
for (k,v) in d {
jsonObject[k] = JSON.wrap(v)
}
return jsonObject
default:
return nil
}
}

public var array: [JSON]? {
switch self {
case .Array(let array):
let jsonArray = array.map({ JSON.wrap($0) })
return jsonArray
default:
return nil
}
}

So now it’s possible to do something like

let age2 = jsonObject?.dictionary?[“age”]?.int?

but that’s pretty ugly (not to mention inefficient) so we can go further and eliminate the explicit test for dictionary by defining the subscript methods.

public subscript(index: Swift.String) -> JSON? {
switch self {
case .Dictionary(let dictionary):
if let value: AnyObject = dictionary[index] {
return JSON.wrap(value)
}
fallthrough
default:
return nil
}
}

public subscript(index: Int) -> JSON? {
switch self {
case .Array(let array):
return JSON.wrap(array[index])
default:
return nil
}
}

And that’s it.

The Acid Test

So, let’s go back and check that our example code does what we expect. Here is the code again from above.

let jsonObject = JSON.parse(data!)
let firstName = jsonObject?[“first name”]?.string
let age = jsonObject?[“age”]?.int
let workCity = jsonObject?[“work address”]?[“city”]?.string

Let’s first convert our JSON data (held in an NSData object) into a an optional JSON enumeration. To get the first name:

1. Unwrap the top-level object,

2. Look up the “first name” key, which returns any value as an optional JSON enumeration,

3. Unwrap it, and

4. Read it as an optional String value.

If any step isn’t as expected, the whole expression will simply result in nil.

It is the same pattern for Johnny’s age.

But what about the work city and home town that derailed our simplistic Objective-C in the first place? When we ask for “work address”, the code will return an JSON.Dictionary value and the city lookup will work as expected. In the case of “home address”, the code will return a JSON.Null so the “city” subscript will evaluate to nil (because the value is not JSON.Dictionary), and the optional unwrap will end the expression and return nil. No exception!

Wrapping it Up

Hopefully you will find this little enumeration useful in your own applications and inspire you to find many other great uses for Swift’s feature-rich enumerations. If you have any questions or want more information on Swift, feel free to give us a call. We’re always happy to chat.

778-372-2800

info@atimi.com

HOW TO MOVE ACTIVITY CONTENT AND ACTION BAR WHEN CLOSING AND OPENING A NAVIGATION DRAWER

Like me, you’ve probably searched online for a navigation drawer solution that doesn’t require a third-party library. When developing apps, we’re always wary about adding extra dependencies, and in this case, the libraries available don’t even mimic all navigation drawer features.

This tutorial shows you how to modify the navigation drawer so it moves the window’s content when it opens and closes. We will modify Google’s sample app with around 10 lines of code to add this functionality.

Implementation

Begin by loading the sample app. We’ll add code directly to these files to illustrate the technique.
http://developer.android.com/training/implementing-navigation/nav-drawer.html
Since the action bar will be moving over when the drawer opens and closes, the drawer needs to claim the area under the action bar. This is achieved by making the action bar an overlay so the window lays out the content to its full height. Any changes to the code are highlighted in yellow. Set the window’s flag inside the Activity.java file. It must happen before super.onCreate() and can alternatively be set in the manifest.xml, if you prefer.

@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
// for v7support use: supportRequestWindowFeature
super.onCreate(savedInstanceState);

}

The obvious drawback of the action bar overlay is that it now overlaps the window’s content. While we want the drawer to extend the height of the window, we still want the other content to fit below the action bar. To make it look normal again, set a top padding on the layout. I prefer keeping a ‘host’ layout with this setting and then adding and removing child layouts with ‘match parent’ attributes. activity_main.xml will look something like this (modified from the Google sample project):

In order to be notified when the drawer is moving, and how far it has moved, add a callback method from the Android API. The sample app illustrates onDrawerOpen() and onDrawerClosed() but there are additional methods available. Add the onDrawerSlide() method in MainActivity.java within the anonymous class defined by ‘mDrawerToggle’. This portion of the file will then look like this, with the added changes in bold:

@Override
protected void onCreate(Bundle savedInstanceState) {

// ActionBarDrawerToggle ties together the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace ‘Up’ caret */
R.string.drawer_open, /* “open drawer” description for accessibility */
R.string.drawer_close /* “close drawer” description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/**
* {@link DrawerLayout.DrawerListener} callback method. If you do not use your
* ActionBarDrawerToggle instance directly as your DrawerLayout’s listener, you should call
* through to this method from your own listener object.
*
* @param drawerView The child view that was moved
* @param slideOffset The new offset of this drawer within its range, from 0-1
*/
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
}
};

}

To know where to put the window’s content, we can find the visible width of the drawer by treating ‘slideOffset’ as a percentage. The edge of the drawer is the x-location for the window’s content.

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
float xPositionOpenDrawer = mDrawerList.getWidth();
float xPositionWindowContent = (slideOffset * xPositionOpenDrawer);
}

There are two things to move with the drawer: the layout and the action bar. To move the layout, create a reference in MainActivity to the FrameLayout (i.e., ‘content_frame’) defined in activity_main.xml. For example:

mHostFragment = findViewById(R.id.content_frame);

Then we can change its position during drawer movement.

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
float xPositionOpenDrawer = mDrawerList.getWidth();
float xPositionWindowContent = (slideOffset * xPositionOpenDrawer);
mHostFragment.setX(xPositionWindowContent);
}

The final ingredient is to move the action bar. This requires accessing its associated view, which unfortunately is not straightforward, but is simple enough. This helper method within MainActivity does the trick on 4.0 and above:

/** (For supporting ActionBarActivity, define packageName as:
packageName = getActivity() instanceof ActionBarActivity ?
getActivity().getPackageName() : “android”;
*/
public View getActionBarView() {
Window window = this.getWindow();
final View decorView = window.getDecorView();
final String packageName = “android”;
final int resId = this.getResources().getIdentifier(“action_bar_container”, “id”, packageName);
final View actionBarView = decorView.findViewById(resId);
return actionBarView;
}

Now the action bar can be moved with the content:

@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
float xPositionOpenDrawer = mDrawerList.getWidth();
float xPositionWindowContent = (slideOffset * xPositionOpenDrawer);
mHostFragment.setX(xPositionWindowContent);
getActionBarView().setX(xPositionWindowContent);
}

In Conclusion

The notable modifications are overriding onDrawerSlide() and making the action bar an overlay. Notice that providing v7 support requires changing the call name of some methods. In development, you can put all this logic into its own Fragment class outside the activity. In doing this, you would also move the ListView in activity_main (‘left_drawer’) into the new fragment, and replace it with a reference. activity_main.xml will then look something like this:

 

 

 <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
		  android:paddingTop="?android:actionBarSize">

      <fragment android:id="@+id/navigation_drawer"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="com.yourapp.NavigationDrawerFragment"
        tools:layout=“@layout/layout_with_listview_for_this_fragment” />
</android.support.v4.widget.DrawerLayout>

 

 

If you have any questions or want to talk more about navigation drawer tips and tricks, give us a call. We’re always happy to chat!

778-372-2800

info@atimi.com

SCROLLING MADE EASY WITH AUTO LAYOUT

img

It’s a common problem. You have a screen in your iOS app that looks great on an iPhone 6 Plus and then QA opens a bug because the content is off the bottom of the screen on an iPhone 6. Or perhaps someone hands you new copy for the About text, and it’s longer than the space available. Whatever the reason, you have a screen and now you need to make it scrollable. If only there was a way of doing this without having to disrupt existing code. Well, with Auto Layout, there is.

Screen Cut Off

Let’s start with an example layout. Here is the storyboard for an About screen.

In the constrained design, it looks great. It’s all laid out with constraints so there should be no trouble for Auto Layout to adapt the design to the various form factors our app supports. As a test, here is the preview for 5.5” and 4.7” iPhones.

OK. Auto Layout has handled the title on the narrower screen and our constraints neatly pushed the description down, but the buttons are off the bottom of the iPhone 6 screen. After checking with our designer, the decision is to make the content scrollable on the smaller screen.

Auto Layout and Scroll Views

Before rushing into the solution to our problem screen, it’s worth going through some Auto Layout theory.

Auto Layout relies on every view’s basic geometry (its size and position) being defined through constraints and/or content. Constraints describe limitations on where and how big a view can be, often in relation to other views. Some views also have an intrinsicContentSize, which is the natural size based on their content. For example, a UILabel will define its intrinsicContentSize to fit the text it has to display, a UIButton will size to include its label and icon, plus any content edge insets. Views that contain other views also have an implied size determined by the size and constraints of their subviews.

The UIScrollView (and its derivatives), however, have a more complicated relationship to Auto Layout, and for good reason. Quite simply, the purpose of a scroll view is to display content that is bigger than itself – having it sized to its content would rather defeat that! Instead, Auto Layout uses the layout of content in a scroll view to set its contentSize, while constraints external to the scroll view determine its size and position. Of course, there are many scenarios where you don’t want Auto Layout managing a scroll view’s content because often the content is loaded dynamically during scrolling, but it is this pattern that we will use to solve our problematic screen.

Adding the Scroll View

Our first step is not, in fact, to put our content into a UIScrollView. Before we get there, we must move everything into a UIView. Interface Builder (IB) makes this relatively painless by providing an Embed command in the Editor menu. Just select all the views and choose Embed in View.

Actually, “relatively painless” is correct. Unfortunately, Xcode (at least the current Xcode 6.1) isn’t able to carry over the constraints that are defined in the superview of the views being embedded, which in our case is most of our layout. So the next step is to quickly add them again…

…and we’re back. Now that we have a view that will act as the content view for our scroller, we can go ahead and embed it within a scroll view. Again, you can do this using the Editor menu and choosing Embed in Scroll View.

As we want to scroll the whole view for this screen, next we need to set constraints to bind the scroll view edges to the edges of the top-level view. Then we need to do the same for our content view, setting its edges to the scroll view’s edges.

Fixing the Width

We are almost finished. There is just one problem, as can be seen from the preview; suddenly our content width has just blown right out so the text views are now each a single line! What happened?

As was mentioned earlier, UIScrollView has a complicated relationship with Auto Layout. Although we added constraints to our content view so its edges coincide with the scroll view, the binding is actually to the scroll view’s content area. In other words, the constraints are telling the scroll view its contentSize, not constraining the content.

We need an additional constraint to fix the width but how can we get the actual width of the screen? Here again Auto Layout makes things easy as constraints are not limited to immediate siblings and superviews. We can create a constraint between our content view and the top-level view. Select both views using ⌘Select and then choose “Equal Widths” in the Pin pop-over. Bingo, the preview is back to normal.

And That’s a Wrap

That’s it. No code changes, no fiddling with the scroll view attributes; it just works. On an iPhone 6 Plus, our screen behaves exactly as before, but on the smaller screen of the 6, it magically allows scrolling through the content. And if your app supports landscape, then when rotating the iPhone 6 Plus, the content becomes scrollable or static depending on its layout.

Conclusion

We have demonstrated how Auto Layout can be used to make a screen dynamically scrollable based on layout, but this is just one way in which Auto Layout’s powerful features can deal with many everyday layout issues. If you have any questions or want more information on Auto Layout, feel free to give us a call. We’re always happy to chat.

If you have any questions or want to talk more about navigation drawer tips and tricks, give us a call. We’re always happy to chat!

778-372-2800

info@atimi.com

SIMPLE JSON PARSING WITH SWIFT

Many mobile applications rely on JSON-based web services for their data. For iOS, there has long been ample JSON support through third-party libraries and, since iOS 5, NSJSONSerialization. The typical output of such is a dictionary containing other dictionaries, arrays, numbers and strings, which works very nicely for Objective-C but can present some problems for the strongly typed Swift. However, using Swift’s powerful support for enumerations, this common task can be just as straightforward without compromising good type checking.

The Joy of JSON

JSON is a lightweight data-interchange format that is great for many classes of web service. It allows the transmission of simple object graphs in an easy to read form (both for developers and code).

Here is an example of a contact record for Johnny Appleseed:

{
“type” : “person”,
“first name” : “Johnny”,
“last name” : “Appleseed”,
“nickname” : null,
“age” : 42
“phone numbers” : [
{
“type” : “work”,
“number” : “+1 (555) 555-5555”
},
{
“type” : “home”,
“number” : null
}
],
“work address” : {
“line 1” : “1234 5th Avenue”,
“line 2” : null,
“city” : “Hometown”
},
“home address” : null
}

Whether or not you have seen JSON before, you have probably already figured out the data structure: the name and age are simple attributes; the work and home addresses are objects (though we don’t have his home address); and there is a list of phone numbers, each of which is its own object.

The Previous State of Art

Now, suppose you are writing an application that consumes a web service that returns the JSON example from above. Once the data has been read from the network it can be converted into a dictionary like so:

NSError* error = nil;
NSDictionary* jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];

(Actually, JSONObjectWithData:options:error: returns an ID but the code has been kept simple for illustration.)
With the object parsed, it’s possible to start extracting information of interest:

NSString* firstName = jsonObject[@”first name”];
int age = [jsonObject[@”age”] intValue];
NSString* workCity = jsonObject[@”work address”][@”city”];
NSLog(@”%@ is %d years and works in %@”, firstName, age, workCity);
// Johnny is 42 years and works in Hometown

That looks pretty straight forward but there is a gotcha lurking in the code. Although getting the work city was fine, the same code for Johnny’s home town will throw an exception. To see why it is necessary to understand what actually happens when the expression jsonObject[@“home address”][@“city”] is evaluated. At runtime, this breaks down into the following:

id temp1 = [jsonObject objectForKey:@“home address”];
id temp2 = [temp1 objectForKey:@“city”];
NSString* homeCity = temp2;

Looking back at the sample JSON, “home address” is null, so you might think that temp1 will be set to nil and, as every good Objective-C developer knows, invoking a method on nil returns nil, which means homeCity will be nil, right?

Wrong. The trouble is that NSDictionary does not allow nil as a value so the parser sets the value to the null singleton, [NSNull null]. This is not the same as nil; it is an object, and invoking objectForKey: triggers an “unrecognized selector” exception.

To handle the sample correctly, we need to explicitly test for the missing address:

NSString* homeCity = nil;
id homeAddress = jsonObject[@”home address”];
if ([homeAddress isKindOfClass:[NSDictionary class]])
{
homeCity = homeAddress[@”city”];
}

Unfortunately, this is the tip of quite a large iceberg: what if “city” is null, or “first name”? And what about “age”? Suddenly, three lines of code have become twenty! Well, to be fair, you could condense the checks to keep to three lines but it gets pretty ugly…

NSString* firstName = ([jsonObject[@”first name”] isKindOfClass:[NSString class]] ?
jsonObject[@”first name”] : nil);
int age = ([jsonObject[@”age”] isKindOfClass:[NSNumber class]] ? [jsonObject[@”age”] intValue] : 0);
NSString* workCity = ([jsonObject[@”work address”] isKindOfClass:[NSDictionary class]] ?
([jsonObject[@”work address”][@”city”] isKindOfClass:[NSString class]] ?
jsonObject[@”work address”][@”city”] : nil) : nil);

Enter Swift

How does this same code play out in Swift? First, here is the equivalent of the first Objective-C version.

var error: NSError? = nil;
var jsonObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data!,
options: NSJSONReadingOptions.allZeros, error: &error)
let firstName = (jsonObject as NSDictionary)[“first name”] as String
let age = (jsonObject as NSDictionary)[“age”] as Int
let workCity = ((jsonObject as NSDictionary)[“work address”] as NSDictionary) [“city”] as String

Already you can see the type safety pushing into the frame with the explicit casts to NSDictionary. And in addition to the NSNull issue already highlighted, the Swift code will also fail if any of the JSON elements are plain missing, which would have worked in the Objective-C code. To successfully get the home city requires the following:

var homeCity: String?
if let jsonDict = jsonObject as? NSDictionary {
if let address = jsonDict[“home address”] as? NSDictionary {
if let city = address[“city”] as? String {
homeCity = city
}
}
}

As with Objective-C, the Swift code can be collapsed into a single line, as long as you’re prepared for a very long line full of parentheses and question marks.

Wouldn’t it be good if you could have the compact style of the original Objective-C with all the type safety of Swift. How about something like this?

let jsonObject = JSON.parse(data!)
let firstName = jsonObject?[“first name”]?.string
let age = jsonObject?[“age”]?.int
let workCity = jsonObject?[“work address”]?[“city”]?.string

A Node by Any Other Name

What we want to make this happen is some sort of wrapper around the data that can do all the heavy lifting for us without getting in the way of chaining down the data tree to get at deeply embedded values. It turns out that Swift enumerations are an ideal solution.

Firstly, we want to define an enumeration that can wrap a JSON value. Because Swift enumerations can have associated values, we can neatly package type-dependent values.

public enum JSON : Printable {
case Array([JSON])
case Dictionary([Swift.String: JSON])
case String(Swift.String)
case Number(Float)
case Null
}

Though very neat, it’s not very useful in itself. However, because enumerations are first-class types, we can add code to do all that work we had to previously do by hand. (Note that all the methods that follow belong to the enum – we are just presenting them separately for annotation.)

The first task is to generate a wrapped JSON value. Let’s define a static method to do this:

public static func wrap(json: AnyObject) -> JSON {
if let str = json as? Swift.String {
return .String(str)
}
if let num = json as? NSNumber {
return .Number(num.floatValue)
}
if let dictionary = json as? [Swift.String: AnyObject] {
return .Dictionary(dictionary)
}
if let array = json as? [AnyObject] {
return .Array(array)
}
assert(json is NSNull, “Unsupported Type”)
return .Null
}

The method simply checks the supplied value and returns the appropriate enum with the value attached.

While we’re thinking about wrapping, we might as well define a convenience method to parse JSON data into our enum.

public static func parse(data: NSData) -> JSON? {
var error: NSError?
if let json: AnyObject = NSJSONSerialization.JSONObjectWithData(data as NSData,
options: NSJSONReadingOptions.AllowFragments, error: &error) {
return wrap(json)
}
return nil
}

Pretty straightforward: use NSJSON Serialization to parse the data and, if successful, wrap it in our enum. Of course, for a full implementation you may want some error handling, and probably define other parse methods that take the data in other formats.

Having created a JSON enum, let’s define ways of getting at the data. First, we can define computed properties that provide type-safe access to simple values:

public var string: Swift.String? {
switch self {
case .String(let s):
return s
default:
return nil
}
}

public var int: Int? {
switch self {
case .Number(let d):
return Int(d)
default:
return nil
}
}

public var float: Float? {
switch self {
case .Number(let d):
return d
default:
return nil
}
}

public var bool: Bool? {
switch self {
case .Number(let d):
return (d != 0)
default:
return nil
}
}

Notice that, in each case, the value is returned if it matches the expected type, otherwise the result is nil. Testing for null itself requires a slightly different pattern but the principle is the same.

public var isNull: Bool {
switch self {
case Null:
return true
default:
return false
}
}

For returning dictionaries and arrays, we need to do more work because we need to wrap each value in the collection with a JSON enumeration value.

public var dictionary: [Swift.String: JSON]? {
switch self {
case .Dictionary(let d):
var jsonObject: [Swift.String: JSON] = [:]
for (k,v) in d {
jsonObject[k] = JSON.wrap(v)
}
return jsonObject
default:
return nil
}
}

public var array: [JSON]? {
switch self {
case .Array(let array):
let jsonArray = array.map({ JSON.wrap($0) })
return jsonArray
default:
return nil
}
}

So now it’s possible to do something like

let age2 = jsonObject?.dictionary?[“age”]?.int?

but that’s pretty ugly (not to mention inefficient) so we can go further and eliminate the explicit test for dictionary by defining the subscript methods.

public subscript(index: Swift.String) -> JSON? {
switch self {
case .Dictionary(let dictionary):
if let value: AnyObject = dictionary[index] {
return JSON.wrap(value)
}
fallthrough
default:
return nil
}
}

public subscript(index: Int) -> JSON? {
switch self {
case .Array(let array):
return JSON.wrap(array[index])
default:
return nil
}
}

And that’s it.

The Acid Test

So, let’s go back and check that our example code does what we expect. Here is the code again from above.

let jsonObject = JSON.parse(data!)
let firstName = jsonObject?[“first name”]?.string
let age = jsonObject?[“age”]?.int
let workCity = jsonObject?[“work address”]?[“city”]?.string

Let’s first convert our JSON data (held in an NSData object) into a an optional JSON enumeration. To get the first name:

1. Unwrap the top-level object,

2. Look up the “first name” key, which returns any value as an optional JSON enumeration,

3. Unwrap it, and

4. Read it as an optional String value.

If any step isn’t as expected, the whole expression will simply result in nil.

It is the same pattern for Johnny’s age.

But what about the work city and home town that derailed our simplistic Objective-C in the first place? When we ask for “work address”, the code will return an JSON.Dictionary value and the city lookup will work as expected. In the case of “home address”, the code will return a JSON.Null so the “city” subscript will evaluate to nil (because the value is not JSON.Dictionary), and the optional unwrap will end the expression and return nil. No exception!

Wrapping it Up

Hopefully you will find this little enumeration useful in your own applications and inspire you to find many other great uses for Swift’s feature-rich enumerations. If you have any questions or want more information on Swift, feel free to give us a call. We’re always happy to chat.

778-372-2800

info@atimi.com