iosdev

Markingbird: A Markdown Processor for Swift

Markingbird is a Markdown processor written in Swift for OS X and iOS. It is a translation/port of the MarkdownSharp processor used by the Stack Overflow website.

(If you have no idea what "Markdown" and "Swift" are, you can just stop reading now.)

F#'s Pipe-Forward Operator in Swift

Note: At WWDC 2015, Apple announced Swift 2, which includes changes and a new feature called "protocol extensions" that render much of the code below either irrelevant or incorrect. This article applies to Swift 1.x.

Apple's new Swift programming language isn't really a functional programming language. However, it does support generic types and functional-programming patterns, so many FP aficionados are implementing their favorite functional idioms and libraries from other programming languages in Swift.

I've been a functional-programming enthusiast for a couple of decades, and I'm playing with this myself. A feature I like in the F# programming language is its pipe-forward operator, |>, which helps to write readable functional code. This article explains what that operator is, why you would want to use it, and how to do it in Swift.

Disclaimer: The code in this article is based upon the versions of the Swift language in Xcode 6.3. Future changes to Swift syntax or its standard library may render all of this incorrect or obsolete.

KJTipCalculator: A Simple iOS Swift App

Screenshot

As an experiment in using Apple's new Swift programming language, I whipped up a simple tip-calculator app for iOS 8.

Yes, the world really needs Yet Another Tip Calculator, and it also really needs Yet Another Swift App Example.

In addition to using Swift, the app also uses an embedded framework, which is a new feature of iOS 8. The framework contains functions and classes for converting between numbers and text, and it might be useful in other apps.

Source is available on GitHub: https://github.com/kristopherjohnson/KJTipCalculator

If you actually want to use this app, you'll have to build it yourself. But if you have iOS 8 on your phone now, you should know how to do that.

Setting Up ArcGIS Runtime SDK for iOS for Xcode Bot

I am working on an iPad app that uses the ArcGIS Runtime SDK for iOS. Esri provides an easy-to-use installer and instructions for setting up the SDK so that it can be used with Xcode.

The installer puts the SDK files in the user’s home directory, and the setup guide recommends using paths like $(HOME)/Library/SDKs/ArcGIS/iOS/ in Xcode projects to find the framework’s headers and libraries. This works fine as long as one is using Xcode as a user who has installed the SDK. However, it causes problems if one wants to set up an Xcode bot to automatically build and test the app. The Xcode service that runs bots executes under the _teamsserver user account, and by default that user’s home directory does not exist, and you can’t log in as that user to run the SDK installer. So attempts to create a bot to build the app just result in “ArcGIS.h not found” compilation errors.

After I bit of Googling and experimentation, I came up with a solution:

  1. Install the SDK in my user account (or another normal account), following Esri’s installer and instructions.
  2. Make my ~/Library directory world-readable:
    chmod 755 ~/Library
  3. Create the /var/teamsserver home directory for the _teamsserver user:
    sudo mkdir /var/teamsserver
  4. Create the /var/teamsserver/Library directory for the _teamsserver user:
    sudo mkdir /var/teamsserver/Library
  5. Set _teamsserver as the owner of the directories:
    sudo chown -R _teamsserver:_teamsserver /var/teamsserver/
  6. Set permissions on the directories:
    sudo chmod -R 770 /var/teamsserver/
  7. Create a symbolic link to the SDK installation:
    sudo ln -s ~/Library/SDKs /var/teamsserver/Library/SDKs

This works. It could be argued that it would be better to set up the symbolic links in some shared location (/Library, /usr/local, etc.) and then use a full path in the Xcode project to find them, but I prefer this solution because it doesn’t require any extra steps for developers who don’t need to set up a bot.

UIColor Category for Specifying Packed RGB Values

iOS's UIColor class makes it pretty easy to specify a color using red, green, blue (RGB) and alpha components:

 // set pale yellow color
 label.textColor = [UIColor colorWithRed:1.0
                                   green:1.0
                                    blue:0.5
                                   alpha:1.0];

However, as with many Cocoa API's, it's pretty verbose. Web developers would specify that color using the hexcode shorthand #ffff80, and many graphics editing tools would generate a hexcode value like that rather than values in the range 0.0–1.0.

So I made a simple category on UIColor that lets one write stuff like this:

#include "UIColor+KDJPackedRGB.h"

// ...

// set pale yellow color
label.textColor = [UIColor colorWithRGB24:0xffff80];

See https://gist.github.com/kristopherjohnson/5606209

iOS and Android Icon Sizes

Every once in a while, I have to tell a graphic designer all the sizes needed for iOS and Android icons. So I'm putting together a summary here for easy reference.

iOS

For more details on requirements and guidelines for iOS app icons, see iOS Human Interface Guidelines: Icons and Image Sizes and Technical Q&A QA1686: App Icons on iPad and iPhone.

All icons must be in PNG format with 24-bit color.

App Icons

For an app for iOS 7 and later, we need icon image files in these sizes:

  • 1024 x 1024
  • 512 x 512
  • 228 x 228
  • 180 x 180
  • 152 x 152
  • 120 x 120
  • 87 x 87
  • 80 x 80
  • 76 x 76
  • 58 x 58
  • 40 x 40
  • 29 x 29
  • 144 x 144 (if supporting iOS 6.1 or earlier)
  • 114 x 114 (if supporting iOS 6.1 or earlier)
  • 100 x 100 (if supporting iOS 6.1 or earlier)
  • 72 x 72 (if supporting iOS 6.1 or earlier)
  • 57 x 57 (if supporting iOS 6.1 or earlier)
  • 50 x 50 (if supporting iOS 6.1 or earlier)

iOS icons are opaque. Note that iOS will automatically round the corners and add the glossy shine effect when it displays the icon. You may want to pre-render the shine effect if you want more control over how it looks.

Toolbar, Navigation Bar, and Tab Bar Icons

  • Use pure white and transparent regions
  • Do not include a drop shadow
  • Use anti-aliasing

For toolbar and navigation bar icons, create images with these sizes:

  • 22 x 22
  • 44 x 44 (high resolution)

For tab bar icons, create images with these sizes:

  • 25 x 25
  • 50 x 50 (high-resolution)

For each toolbar, navigation bar, or tab bar icon, you may provide a single image, which iOS will treat as a template to generate unselected and selected appearances, or you may provide two images: one for the unselected appearance and another for the selected appearance.

Note that the sizes given for toolbar, navigation bar, and tab bar icons here are approximate. Images may be slightly larger or slightly smaller than these sizes. Give all icons in a bar a similar visual weight.

Apple Watch Icons

If the iOS app includes an Apple Watch app, the following icons are needed:

Notification Center Icons

  • 29 x 29 (38mm watch)
  • 36 x 36 (42mm watch)

Long Look Notification Icons

  • 80 x 80 (38mm watch)
  • 88 x 88 (42mm watch)

Home Screen Icon and Short Look Icon

  • 172 x 172 (38mm watch)
  • 196 x 196 (42mm watch)

Menu Icons

  • 70 x 70, with content size 46 x 46 (38mm watch)
  • 80 x 80, with content size 54 x 54 (42mm watch)

Watch Companion Icons

  • 58 x 58
  • 87 x 87

Android

App Icons

For an Android app launcher icon, we need PNG image files in these sizes:

  • 512 x 512 (Google Play)
  • 144 x 144 (xxhdpi)
  • 96 x 96 (xhdpi)
  • 72 x 72 (hdpi)
  • 48 x 48 (mdpi)

Note that Android app icons don't have to be square: the alpha channel can be used to create transparent areas, so an icon should have a distinct silhouette.

If the app generates notifications, then we need a 24 x 24 icon image. Notification icons must be entirely white except for transparent regions.

For more details on requirements and guidelines for Android app icons, see Launcher Icons and Iconography

Action Bar Icons

  • 96 x 96 (xxhdpi)
  • 64 x 64 (xhdpi)
  • 48 x 48 (hdpi)
  • 32 x 32 (mdpi)

Small/Contextual Icons

  • 48 x 48 (xxhdpi)
  • 32 x 32 (xhdpi)
  • 24 x 24 (hdpi)
  • 16 x 16 (mdpi)

Notification Icons

  • 72 x 72 (xxhdpi)
  • 48 x 48 (xhdpi)
  • 36 x 36 (hdpi)
  • 24 x 24 (mdpi)

iOS UI Automation Cheatsheet

I have just learned about Apple's UI Automation testing framework. Unfortunately, I don't have an iOS project to work on at the moment, so I am probably going to forget all about it. This is my cheatsheet. It may not help you at all.

Tutorials

Documentation

Tips

  • Use the Tuneup library: https://github.com/alexvollmer/tuneup_js
  • Assign an accessibilityIdentifier to each UI element.
  • Set UIATarget.onAlert to handle externally generated alerts.
  • Use UIAElement.logElementTree() to figure out how to navigate the visual hierarchy.
  • If a value doesn't change when expected, try adding UIATarget.delay(1);

Distributing a Custom iOS B2B App

I recently went through the process of distributing a free custom B2B app in the App Store. I hit a few snags, and I found very little information about the process, or help in online forums, and Apple Support assistance was very slow. So I'm documenting what I learned here. I hope it helps someone.

Want to Develop iOS Apps? Learn Objective-C.

As an iOS software developer, I am often asked whether "we" (a team I'm working with, or someone I'm advising) should avoid using Objective-C and instead use a higher-level or easier-to-learn programming language. In general, my answer is "No". The rest of this post explains why.

KJSimpleBinding

Mac OS X provides a pretty nice data-binding technology for developers, called Cocoa bindings. Unfortunately, the Cocoa bindings mechanism is not available to iOS developers, so iOS developers have to spend a lot of time writing code to keep user-interface elements and data in sync.

However, while Cocoa Bindings is not available on iOS, the underlying key-value coding (KVC) and key-value observing (KVO) mechanisms are, so it is straightforward to implement your own poor man's data-binding mechanism and eliminate some of the drudgery.

I have done just that. My KJSimpleBinding library is available on GitHub. I hope it is useful to someone, and I hope I have time to make it less simple.

I'm not the only one to try this. Here are a few similar projects I found on GitHub:

Syndicate content