acb's technical journal

Posts matching tags 'swift'

2016/3/21

Functionally generating UIImage in Swift

When developing iOS apps, one often needs a simple UIImage, to use as a background or texture. Traditionally, the facilities for making these on the fly have been minimal to nonexistent, leaving one with two options: either (a) write code which allocates a memory buffer, fills it with pixel values, then does the CoreGraphics dance that turns it into a UIImage, or, more commonly, (b), hacks something up by hand in an image-editing program on one's computer and puts the PNG in the app bundle. The latter has the disadvantage of inflexibility (if the dimensions or colours need to change, it's back to laboriously hand-crafting a replacement image); the former, meanwhile, requires enough work to put one off, unless image generation is a central part of the app's value proposition. However, in the age of Swift, it doesn't have to be this way.

The Swift language, borrowing from functional programming, lends itself nicely to the making of labour-saving abstractions; pieces of code which implement the outline of a process, allowing the caller to provide only the code that does the specific details they want. (This has been, to a lesser extent, possible with Objective C since the addition of blocks, but Swift has further highlighted it.) In which case, it stands to reason that we should be able to do something like:

// make an 8-by-8 black-and-white checkerboard tile
let checkerboard = UIImage(width: 8, height: 8) { (x,y) in return Float(((x/4)+(y/4))%2)  }

Below the cut, I present a UIImage extension which allows you to do exactly this, as well as RGB and RGBI variants.

 [...]

cocoa touch functional programming iOS swift uiimage 0

2016/2/25

swiftemplate: Compile-time HTML templates in Swift

Continuing my experiments with the potential of Swift for server-side web applications, I have recently turned my attention to the question of HTML templates. In any HTML-based web app, it is useful to have a way of programmatically generating HTML with data interpolated, which typically is done through templates; HTML documents with special markup. When a page is requested, the template is processed, with the data being inserted into it, generating a HTML document which is sent back to the browser.

There are two ways a templating system may be implemented in a web application framework. On one hand, the framework itself may embed the template engine; the web app in this case would be deployed with a set of templates, which it would parse into an internal representation; then, whenever the app receives a request, the engine uses the template to generate a HTML page. (This is the approach used by many web frameworks written in dynamic languages such as Python and Ruby.) The other alternative is to do the template processing at build time; a tool compiles the template into source code in the language the web application is written in; it is then included in the app, and called as any other piece of code would be. The advantages of this approach are more compact and efficient compiled applications. It is particularly suited to compiled languages like Swift, which already have a build process.

It is with this in mind that, following on from the Malimbe framework, I have developed swiftemplate, a familiar-looking HTML-oriented templating system that generates Swift code.

The swiftemplate syntax

The syntax of swiftemplate will be familiar to people who have used other web application frameworks. A template file consists of content (typically HTML) interspersed with directives, expressions and inline code blocks. Directives begin with %% and occupy their own lines; they include the familiar for and if/else (which are augmented with closing directives), as well as a template directive which defines a template and its arguments. Inline expressions are enclosed in <%= and %>; they must fit on one line, but may contain characters not permissible in Swift's \() interpolation syntax. Code blocks take up multiple lines, and are enclosed in <% and %> brackets (each of which must be on its own line). An example template (for displaying a page about a user of a web application) might look like like:

%% template showUser(user: User)
<%
let posts = user.posts.prefix(5)
%>
<h1>User \(user.name)</h1>
%% if posts.isEmpty
<p>This user has no posts</p>
%% else
<ul>
%% for post in posts
  <li><%= post.title %></li>
%% endfor
</ul>
%% endif
%% endtemplate

The template compilation process

Swiftemplate templates are compiled to Swift code with the swiftemplate command. One or more template files (each potentially containing one or more templates) may be compiled at a time into a Swift source file; one possible invocation could be to compile all the templates into one source filem prior to compilation of the Swift code, like so:

swiftemplate -o Sources/templates.swift Templates/*.swiftemplate

In the emitted source file, each template is converted to a Swift function, having the same name and arguments as in its %% template directive and returning a String; for example, the user page template above would produce Swift code that (if indented) looked something like:

func showUser(user: User) -> String {
  var _ℜ=[String]()
  let posts = user.posts.prefix(5)
  _ℜ.append("<h1>User \(user.name)</h1>")
  if posts.isEmpty {
    _ℜ.append("<p>This user has no posts</p>")
  } else {
    _ℜ.append("<ul>")
    for post in posts {
        _ℜ.append("<li>")
        _ℜ.append(String(post.title))
        _ℜ.append("</li>")
    }
    _ℜ.append("</ul>")
  }
  return _ℜ.joinWithSeparator(" ")
}

(The variable containing the return result is given the name ‘_ℜ’, which stands for “result” and is also unlikely to be used by the template. Needless to say, don't name your templates or template arguments this.)

Composing templates

Given that swiftemplate input files may contain multiple templates, and that templates, in their compiled form, are just Swift functions returning Strings, it is possible to define templates in a modular fashion. Below is an example, also from the user example, which displays a set of contact details using another template as a macro:

%% template contactDetail(name: String, value: String) 
<dt class="detailName">\(name)</dt> 
<dd class="detailValue">\(value)</dd>
%% endtemplate

%% template showUser(user: User)
<h1>User \(user.name)</h1>
<p>\(user.description)</p>
<h2>Contact details</h2<
<dl>
<%= contactDetail("Phone", user.phone) %>
<%= contactDetail("Email", user.email) %>
<%= contactDetail("Twitter", user.twitter) %>
%% // ... and so on
</dl>
%% endtemplate

The state of Swiftemplate

This is the first version of Swiftemplate, and it may well have bugs. Having said that, there are extensive unit tests (though, at the moment, these only work in Xcode; once testing in the Swift build process on Linux matures, they will work there as well).

Swiftemplate is a lightweight template processor; it parses the parts it understand and passes other parts (such as the expressions following an %% if or a %% for) through to Swift without attempting to enforce correct syntax. Which means that if those parts are nonsense, swiftemplate will not warn you, but you will get a Swift compiler error in the machine-generated .swift file containing your processed templates. Be warned!

Swiftemplate runs under OSX (with Xcode) or Linux (with the command-line build tools, and the Foundation module installed), and does not depend on Malimbe or any other code; it is available on GitHub and is distributed under the Apache Licence (i.e., it may be used freely, as long as acknowledgement is provided).

html swift swiftemplate web 0

2016/2/11

Malimbe: an asynchronous server-side web framework in Swift

Recently, I have been experimenting with the open-source beta of Swift for Linux, and in particular looking into its potential as a language for server-side web applications. As such, I present the first draft of my experimental server-side web framework, Malimbe.

Malimbe (named after several species of African weaver bird) is written in Swift and will build on Linux; no attempt has yet been made to make it work on OSX, though it would certainly be possible. The main influences on Malimbe's design have been various Python/WSGI-based frameworks (mainly Pylons/Pyramid) and the Play framework in Scala (though Malimbe is a lot more minimal at this stage). The key design decisions of Malimbe, as it currently stands, are:

  • The use of Futures (as previously described here) for concurrency. HTTP request handlers do not return a HTTPResponse immediately, but return a Future<HTTPResponse>; i.e., an opaque container to a computation, which, once complete, will yield a HTTPResponse. The Future may refer to an ongoing computation, taking place on a background thread, or (for simple responses) may be created pre-completed. Given that Futures are monadic containers (which may be mapped and flatMapped over), a request handler returning a Future<HTTPRequest> could well just call a function returning a Future of, say, a set of database rows or a JSON object fetched from a remote API, and return that mapped into, say, a page of HTML.
  • Malimbe's request-handling mechanism is a chain of objects implementing the HTTPRequestHandler protocol. This protocol defines only one method, which looks like:
    func handleRequest(request: HTTPRequest) -> Future<HTTPResponse>
    
    The request handler objects are typically instantiated with any configuration information they need; for most of them, this will include a next value, containing the next request handler in the chain. If the request handler cannot completely handle the request itself, it will call this and return its value. (Theoretically, it could also modify its return value with map or flatMap, though none of the ones implemented so far do.)

The main source file of a Malimbe web application, as it stands, constructs the chain of request handler, and creates a HTTPServer object (passing the top of this chain to it); requests propagate down the chain until they are handled; at the bottom is typically the Router request handler, which matches methods and paths, extracting arguments from paths, and calling the appropriate handler for each path. This might well look something like:

func itemPageHandler(request: HTTPRequest, args:[String:String]) -> Future<HTTPResponse> {
    let id = args["id"] ?? ""
    // make the item page here...
}

let router = Router(routes:[
	Router.Get("/items/",    handler:itemsListHandler),
	Router.Get("/items/:id", handler:itemPageHandler),
])

let staticFiles = StaticFileRequestHandler(pathPrefix: "/static/", staticDir:appRelativePath("StaticFiles/"), next:router)

let server = HTTPServer(handler: staticFiles)

do {
    try server.start(9999)
    print("started on 9999")

    while(true) {
        NSRunLoop.mainRunLoop().runUntilDate(NSDate.distantFuture())
    }
} catch {
    print("error: \(error)")
}

Malimbe currently has a few request handlers: the path-matching Router shown above; StaticFileRequestHandler, which can conveniently serve static files (such as stylesheets and JavaScript) from a local directory under a certain path, along with a HTTP Basic Authentication middleware; others will be added in future.

HTMLRenderable

Malimbe also has a simple set of objects for generating HTML in Swift code. This, Swiftily enough, has a protocol at its centre, the HTMLRenderable protocol, which allows objects to return HTML representations of them:

public protocol HTMLRenderable {
    /** Return a HTML representation of this object as a String */
    var asHTML: String { get }
}

The Swift String type has been extended to be HTMLRenderable; a string rendered asHTML will be quoted, with angle brackets replaced with &lt; and &gt; so that its contents are displayed as they are. If you wish to pass HTML markup back, there is a HTMLLiteral object you can wrap it in, which renders without any quoting. However, in most cases, you will want to create tags using the HTMLTag type, a HTMLRenderable representing a single tag and its contents (which may include zero or more HTMLRenderables within the tag), like so:

HTMLTag.DIV([
    HTMLTag.SPAN(HTMLTag.B(self.name), "says:", class:"itemtop"),
    HTMLTag.DIV(self.text, class:"itembody")
], class:"guestbookitem")

(The tag's contents are the first rather than last parameters; this is because of quirks in Swift's handling of variadic arguments.)

Of course, since HTMLRenderable is a protocol, there is every reason to extend your data types to implement it, which then allows you to insert them directly in the markup:

extension Item: HTMLRenderable {
    var asHTML: String {
        return HTMLTag.P(
            "Item ", HTMLTag.B(self.id), "(\(self.name))"
        , class: "item").asHTML
    }
}

The state of the framework

Malimbe is an experimental framework, still in an early stage of development. Many pieces that one would expect in a full stack are missing (notably any support for access to databases or web-based APIs). Some of these may be developed separately as other projects and imported as dependencies into Malimbe-based projects, though ideally, Malimbe would integrate them into its design. (For example, once a database framework exists, it would be the intention for it to be wrapped in an asynchronous interface that returns Futures of results.) Other components (such as session middleware, templating libraries, and a configuration system) are also missing at this stage.

Also, because Swift support on Linux is still immature, Malimbe applications will probably not be performant at this stage. For one, at the time of writing, there was no stable Linux port of libdispatch (Apple's concurrency framework, also known as Grand Central Dispatch); Malimbe uses a workaround from a Swift package named NSLinux which fakes this by spawning a thread for each dispatched block; this is obviously not something one would want on a heavily loaded production server. However, once libdispatch is ready, Malimbe will not require significant changes to use it.

Malimbe is available on GitHub, and is distributed under the Apache Licence (i.e., it may be used freely, as long as acknowledgement is provided).

futures linux malimbe swift web 1

2016/1/18

Futures/Promises in Swift, draft 1.1

With the recent open-sourcing of the Swift language and its availability (albeit piecemeal, and not quite as we know it) on Linux, I have been spending some time playing with Swift on Linux. In my opinion, it holds promise for implementing the sorts of server-side code that often runs on Linux instances; one example would be web applications. With its LLVM-based optimising compiler, strong type system and the ability to minimise the amount of mutable state (more so than, say, Python or JavaScript), it should lend itself to performant server-side code quite well.

In any case, here is the first result of my experiments in Swift on Linux: a proof of concept of Futures/Promises. It's modelled somewhat on Scala's Futures, in that Futures are monadic containers which may be transformed with map, chained with flatMap, and, should you need to go synchronous at some point, awaited.

(For those not familiar with Futures/Promises, they're a different way of organising callbacks. With callbacks, as we know them from, say, JavaScript, Objective C or Swift, if you have a possibly time-consuming process to run, you pass it a function for it to call; it returns nothing immediately, but if all goes well, your callback function gets called with the value it was waiting for. Of course, the downside of this is the building up of a “Pyramid Of Doom”, a monstrous ziggurat of curly braces, like so:

doSomething { (a) -> () in 
   doSomethingElse(a) { (b) -> () in 
     andSomethingElse(b) { (c) -> () in 
        // now handle the value here
   }
}
With Futures/Promises, you don't pass callbacks, but instead receive an opaque container type that is, at some future time, redeemable for the value of whatever computation it represents. While you don't have that value, you can do other things with it, like chain other operations on it, to be completed asynchronously. And so, our pyramid is transformed into something like;
doSomething()
  .flatMap { doSomethingElse($0) }
  .flatMap { andSomethingElse($0) }
  .onCompletion {
    // now handle the value here
  }
Which, for one, looks a bit tidier; it also allows complex chains of interdependent operations to be reasoned about more easily.)

This code is currently only a rough sketch (which is why it is a gist, rather than a repository); for one, Swift on Linux's concurrency handling still leaves a bit to be desired (Apple's libdispatch is still not available, and so this uses NSLinux, which fakes Grand Central Dispatch in a somewhat basic way, spawning a new thread for each block, and having no option of running things on the main thread; needless to say, don't use this in your financial trading app just yet.) Secondly, there is not yet a concept of a failed Promise; they may be either incomplete or successfully completed. (Whether to use a Haskell-style Either/Result value or to somehow eschew that in favour of Swift's throws mechanism is a decision to be considered when implementing the possibility of failed Promises. Also, some way of sequencing/traversing multiple Futures would be useful for nontrivial applications. Finally, there is the small matter that this code defines only a Promise type and has it do double-duty as a Future as well; which makes for simpler code, though doesn't separate the twin concerns quite as elegantly. Update: I have now updated the code to split Futures (the ones you fire off with a block to run in the background) from Promises (the ones you create and fill in yourself, giving a Future to whatever needs the result).

In any case, the typical usage would look something like the following:

// Map over a Future, then do something with its result asynchronously
var f1 = Future<Int>( future: { calculateValue(...) })
var f2 = f1.map { $0 * 2 }
f2.onComplete { doSomethingWith($0) }

// two futures chained with flatMap
var f3 = Future<String>( future: { getUserName() })
    .flatMap { Future<Int>( future: { getShoeSizeOfUser($0) } }
if let value = f3.await(3.0) {
    print("The user's shoe size is \(value)")
}

And if you want to use Promises and do the computation yourself:

func asynchronouslyComputeAFuture() -> Future<Something> {
    // create an empty Promise...
    let p = Promise<Something>()

    // start a background process which will fill the Promise in...
    dispatch_async( myQueue, {
        let result: Something = computeTheResult() // this may take a while...
        p.complete(result)
    })

    // return the Promise's Future
    return p.future()
}

This is not the only implementation of Futures/Promises for Swift, nor even one of the more complete ones. There are two others which look more complete (BrightFutures and FutureKit), though both are only available for iOS and OSX at the moment.

concurrency functional programming futures linux monads promises swift 1

2015/6/19

The case of the crashing Swift compiler

Recently, whilst preparing release 1.1 of the MPDluxe iOS app, I encountered an unwelcome surprise: the app itself had built and worked without problems in Debug mode, but as soon as I tried to Archive it (i.e., building it in Release mode, with compiler optimisations switched on), the Swift compiler would, at some stage, choke on something and die with a segmentation fault:

0  swift                    0x00000001029e82b8 llvm::sys::PrintStackTrace(__sFILE*) + 40
1  swift                    0x00000001029e8794 SignalHandler(int) + 452
2  libsystem_platform.dylib 0x00007fff88c53f1a _sigtramp + 26
3  libsystem_platform.dylib 0x0000000104b06000 _sigtramp + 2079006976
4  swift                    0x0000000102526d5a (anonymous namespace)::DCE::markControllingTerminatorsLive(swift::SILBasicBlock*) + 346
5  swift                    0x0000000102526ae9 (anonymous namespace)::DCE::markValueLive(swift::ValueBase*) + 201
6  swift                    0x00000001025262ff (anonymous namespace)::DCE::run() + 1983
7  swift                    0x00000001024cdf3e swift::SILPassManager::runFunctionPasses(llvm::ArrayRef) + 1310
8  swift                    0x00000001024ce9c9 swift::SILPassManager::runOneIteration() + 633
9  swift                    0x00000001024cd436 swift::runSILOptimizationPasses(swift::SILModule&) + 790
10 swift                    0x00000001022d18e7 frontend_main(llvm::ArrayRef, char const*, void*) + 4695
11 swift                    0x00000001022d04e6 main + 1814
12 libdyld.dylib            0x00007fff90c545c9 start + 1

A web search revealed that others had had similar problems with the compiler, also in the optimisation stage of a release build. Everybody seemed to have their own superstition on which ostensibly legal syntactic feature to avoid to appease the gremlins, mostly involving being more circumspect about optionals; their cases were sufficiently different that there was no one thing to search for and eliminate.

With that in mind, I turned to git bisect. In short, bisect is a subcommand of the git version control system which allows you to specify a last-known-good version of your code, and semi-automates a binary search between then and the current (presumably broken) version, narrowing down on exactly which change coincided with the code breaking. In bisect mode, git checks out a revision from the middle of the as yet unsearched range; you then test it (in my case, getting Xcode to do an Archive build). If it works, you enter the git bisect good command and it skips forward; if not, you enter git bisect bad and it skips backward. Do this for a few steps and soon you will have exactly which commit broke things. Anyway, I ran git bisect between the current HEAD and version 1.0, as below:

% git bisect start
% git bisect bad
% git bisect good v1.0
Bisecting: 51 revisions left to test after this (roughly 6 steps)
[79b5f750178d09e924da572a4d83fb66bc9bed61] Removed redundant output-related methods

It had checked out a version from the middle of the set of check-ins between then and now; I went back into Xcode, did a Clean and an Archive, and, sure enough, Segmentation Fault. So this one's bad, and it's time to skip back halfway to the beginning and try from there:

% git bisect bad
Bisecting: 25 revisions left to test after this (roughly 5 steps)
[b49c1128168bb844f3b944d6e502d98f27e64f14] Added title to Search view controller

I tried building this, and it worked; so this one's good. Now to skip forward, and so on for the next few steps:

% git bisect good                                
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[b112971ad7a21cb6c47358d4e316380df42f006f] Removed dead code
% git bisect good
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[524b442c6c6c3d6ea02edc1d3a56abe82170d213] Hived navigateToContainingFolderOfFile off into MPDNavigationController
% git bisect bad
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[06f9a82e169617aeebeb85122bc5829d3c43b6af] DraggableTableViewCell now has hidden drawer for buttons
% git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[fce75660b3dd40a21abc996c4ed5fc7400d59d49] Navigate to path from playlist now works, modulo tidying up/refactoring/aesthetic grace notes
% git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[eb5ee15b0520e56177d69745f615d8f1afaed930] Implemented “navigate to” hidden button in PlaylistTableViewCell

Surely enough, we had the offending commit soon enough:

% git bisect good
fce75660b3dd40a21abc996c4ed5fc7400d59d49 is the first bad commit
commit fce75660b3dd40a21abc996c4ed5fc7400d59d49
Author: acb 
Date:   Fri Jun 5 17:38:33 2015 +0100
  
    Navigate to path from playlist now works, modulo tidying up/refactoring/aesthetic grace notes

The commit itself was a fairly small one, and (after going back to the latest revision), commenting out parts of the code added in it and trying to build soon found what the Swift optimiser was having trouble with.

The code in question deals with the app's Playlist view, a UITableView which shows a playlist of songs queued up for playing; each of these is represented by a UITableViewCell subclass named PlaylistTableViewCell. One of the added features of the app is a hidden button on the playlist items, allowing the user to go to a view of the directory the song is in (i.e., to browse the rest of the album it's on). This was implemented by having an optional closure on the PlaylistTableViewCell, which would be called when the button was tapped. This closure captured various relevant data (such as the directory path to go to) and was set when the table view cell was filled in; a greatly simplified version looks a little like:

class PlaylistTableViewCell {
   ...
    var onNavTo:(()->())? = nil

    func navToPressed(sender: AnyObject) {
        onNavTo?()
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
 ...

  cell.onNavTo = {
     // code for navigating to item['file']
      if let fpath = item["file"] as? String {
          navigateToContainingFolderOfFile(fpath)
      }
  }

Which is perfectly legal Swift, though, with the Swift 1.2 optimising compiler, that plus £2.80 gets one a cup of coffee. Anyway, to appease the gremlins, I inlined the code, replacing the closure with an optional string:

class PlaylistTableViewCell {
   ...
    var navToPath: String? = nil

    func navToPressed(sender: AnyObject) {
        if let fpath = navToPath {
            navigateToContainingFolderOfFile(fpath)
        }
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
 ...
    cell.navToPath = item["file"] as? String
}

From there onward, the code built and worked without a problem.

The moral of this story is that, while the Swift toolchain is a lot more stable than before, it (as of 1.2, the current production release) still has a few bugs, some of which may appear at various times and, through no fault of one's own, derail an ostensibly perfectly valid project. Working around them is a combination of detective work and making the right offerings to the trickster gods of the toolchain; and that git bisect is your friend.

debugging git ios swift war stories 0

2015/5/29

A popover menu control for iOS 8

In iOS 8, it is possible to present any view controller in a popover. This blog post describes the construction of a UIControl which presents a popover menu of text options. The full code of the control, and an example program, may be found here.

Sometimes, it is useful to have a popup menu in an iOS app; for the user to be able to change a value by tapping or dragging on the value and selecting a new one from a menu. Traditionally, this has been done on the iPhone with UIActionSheet; the idiom was that the user tapping on the button/table cell would trigger a pane of options, which would display from the bottom of the screen. This made sense for small phone screens, as it allowed one-handed operation, but in the age of the phablet, there is no need to stick to it. Hence, as of iOS 8, it is possible to present arbitrary view controllers in a popover on any iOS device, which is quite powerful.

On the iPad, one could present arbitrary view controllers in a popover view for a while. This deliberately did not support the iPhone, and would cause the app to die with a runtime error if one tried using it. In iOS 8, Apple have changed the interface somewhat, and extended it to the iPhone.

Popover view controllers in iOS 8

In iOS, one presents a new view controller by instantiating it, setting it up and calling the current view controller's presentViewController:animated: method. Traditionally, this has been used to push view controllers onto a UINavigationController stack, or to present modal full-screen view controllers. In iOS 8, the same method can be used to present view controllers in a popover container, which appears on the screen with an arrow pointing to the control it launched from.

To do this, one first sets the view controller's modalPresentationStyle to UIModalPresentationStyle.Popover. One then obtains a UIPopoverPresentationController from the view controller's popoverPresentationController property, and uses this to configure the popover's appearance and behaviour; these include the view on which the popover is being displayed, the frame rectangle of the control it is being launched from (to which the arrow will point), and which arrow directions one wishes to use. One also needs to give it a delegate, and to make it work correctly, define the delegate's adaptivePresentationStyleForPresentationController to return .None. Then, once this is done, one presents the view controller using presentViewController:animated:. The controller may be dismissed in the same way modal view controllers are, by calling its dismissViewControllerAnimated: method. The controller will also be dismissed if the user taps outside of the popover; if this happens, the delegate's popoverPresentationControllerDidDismissPopover: method will be called.

Building a pop-up menu/selector control

This is all very well, but we want something more convenient than setting up a view controller every time we want a popover menu. The goal is to have a self-contained control that handles a few common cases of popover menus. We make the following assumptions:

  1. The popover menu will have one or more items, or options, each of which is a string.
  2. The popover menu will be launched when the user taps on a button.
    1. In some cases, the button will display the currently selected option, and the menu will allow the user to change this.
    2. In other cases, the menu will display a fixed prompt, and the menu will be used to trigger one of several actions.

From this, it's obvious that we want something that will be configured with a list of options and construct the popover and its embedded view controller; also, as the set of options is a list of strings which are tappable items, the view controller looks very much like it would be a UITableViewController. Given that we want the mechanism to be triggered by the button, and (in some cases) to change the button's text, why not make the button part of it, with the popover handling wired into it? So, we'd want:

  1. The entire control will be a UIView subclass, which contains a UIButton, and handles displaying and responding to the popover control when the button is tapped.
  2. The control keeps a list of options, and the index of the currently selected option (if present). It also has various configuration options, such as whether the button is to display the selected item title, and text to display if no item is selected, or if the selected item title is not to be shown.
  3. We want the control to send a notification when its value changes; to do this, we make it a subclass of UIControl, and allow the application to set targets to be notified on the ValueChanged control event.

Going from there, a skeleton of the control starts to look something like this:

class KFPopupSelector: UIControl {
    enum Option {
        case Text(text:String)
    }

    /** The options the user has to choose from */
    var options: [Option] = [] 
    
    /** The currently selected value */
    var selectedIndex: Int? = nil

    /** The text to display on the button if no option is selected */
    var unselectedLabelText:String = "--"

    /** if true, replace the button's text with the currently selected item */
    var displaySelectedValueInLabel: Bool = true

    // -------- The TableViewController used internally in the popover
    
    class PopupViewController: UITableViewController {
       //  ...
    }
    
    var currentlyPresentedPopup: PopupViewController? = nil

    // User interface components
    private let button = UIButton.buttonWithType(.System) as! UIButton

    override func intrinsicContentSize() -> CGSize {
        return button.intrinsicContentSize()
    }

    // Handle a button tap
    func buttonPressed(sender: AnyObject?) { ... }
}

There are a few things to note there; rather than storing options as Strings, we have defined an enum named Option (within KFPopupSelector's namespace). Currently it has only one option, which wraps a String, but it will, in future, allow for the addition of options which consist of something other than a string. I have also chosen to define the view controller class, PopupViewController, in the control's internal namespace, rather than in a separate file; this is something possible in Swift, and as the view controller is both intimately tied to the control which launches it and fairly uncomplicated in its functionality, separating it out made little sense. Finally, we define the intrinsicContentSize method, making it return the button's content size; we want the control to hug the button, and if the button dimensions change (due to changes in its label), we want to push that out to any autolayout constraints the button is connected to.

As this control is fairly compact, all of its code is inside the KFPopupSelector class; as such, all other code fragments in this article will be implicitly inside this class.

Setting up the control

When the control is loaded from a storyboard, we need to set up its components and wire up event handlers; the code which does this is the below:

    override func awakeFromNib() {
        button.setTitle(labelDecoration.apply(unselectedLabelText), forState: .Normal)
        self.addSubview(button)
        button.frame = self.bounds
        button.autoresizingMask = .FlexibleHeight | .FlexibleWidth
        
        button.addTarget(self, action: Selector("buttonPressed:"), forControlEvents:.TouchDown)
    }

Note that we call the buttonPressed: method on TouchDown, not TouchUpInside; we want to show the popover when the user touches the button, rather than when they lift their finger from it (as the normal button behaviour is).

(Also, for the purposes of this example, we will assume that the control will always be constructed from a NIB or storyboard; to manually construct one, we would call the same functionality from init(frame:).)

Handling button taps

When the user taps the button, we need to create and display our popover; which happens like so:

    func buttonPressed(sender: AnyObject?) {
        if options.count > 0 {
            let pvc = PopupViewController(style: UITableViewStyle.Plain)
            pvc.options = options
            pvc.itemSelected = { (index:Int) -> () in 
                pvc.dismissViewControllerAnimated(true) { 
                    self.currentlyPresentedPopup = nil 
                    self.selectedIndex = index
                }
            }
            pvc.modalPresentationStyle = .Popover
            currentlyPresentedPopup = pvc
            
            if let pc = pvc.popoverPresentationController {
                pc.sourceView = self
                pc.sourceRect = button.frame
                pc.permittedArrowDirections = .Any
                pc.delegate = self
            
                viewController!.presentViewController(pvc, animated: true) {}
            }
        }
    }

PopupViewController is the UITableViewController subclass we hinted at earlier; here, we allude to it having two instance variables: a copy of the options, and itemSelected, which is a callback function called with the index of whichever item the user has tapped. We fill these, threading through the control's options, and passing a closure which will handle the user having tapped a menu item (i.e., set the selected index and close the popover). We also add a didSet handler to the control's selectedIndex variable, to send out the appropriate notification, and update the button label if necessary:

    var selectedIndex: Int? = nil {
        didSet {
            updateLabel()
            sendActionsForControlEvents(.ValueChanged)
        }
    }

 . . .

    func updateLabel() {
        if selectedIndex != nil && displaySelectedValueInLabel {
            switch (options[selectedIndex!]) {
            case .Text(let text): buttonText = text
            }
        } else {
            buttonText = unselectedLabelText
        }
    }

(buttonText is another variable getter/setter, which, for convenience, wraps UIButton's setTitle:forState:, and also handles different title decoration options; for more information, see the source code.)

Finding the view controller

One thing you may have noticed in the buttonPressed method is the last line, reading:

    viewController!.presentViewController(pvc, animated: true) {}

We have not defined what viewController is. However, we know that, to present a view controller, we need to do so by calling a method on the current view controller. Which is easy to do if we're doing so from within the view controller, but a tad trickier when the code is encapsulated into a UIView subclass. View controllers are a higher level of abstraction than views; while views deal with concrete interface elements, view controllers deal with the aggregation of those into specific screens or tasks; and normally, there is no reason for views to know about view controllers. However, this is one of those exceptions, in which a view needs to reach up to the higher level to present a temporary view controller. So how do we obtain this?

A naïve solution may be to make it an instance variable, and require the application to fill it in, either by linking it in the storyboard or providing it at view controller setup time. However, this is messy and cumbersome. There is a better way; it is possible to find the current view controller by walking up the responder chain. As such, we can define a magic viewController variable which gives us the view controller, like so:

    private var viewController: UIViewController? {
        for var next:UIView? = self.superview; next != nil; next = next?.superview {
            let responder = next?.nextResponder()
            if let vc = responder as? UIViewController {
                return vc
            }
        }
        return nil
    }

More on PopupViewController

Until now, we have mostly glossed over PopupViewController, the view controller that sits in the popover. And, for the most part, it is fairly straightforward; if you've ever worked with table views in iOS, you'll find it familiar. There are a few details worthy of remark, and below is an abridged version of PopupViewController highlighting them. (I have omitted the usual UITableViewDataSource methods, as those are fairly straightforward.)

    class PopupViewController: UITableViewController {
        let minWidth: CGFloat = 40.0
        var optionsWidth: CGFloat = 40.0
        
        private let tableViewFont = UIFont.systemFontOfSize(15.0)

        var options: [Option] = [] {
            didSet {
                optionsWidth = options.map { 
                    $0.intrinsicWidthWithFont(self.tableViewFont) 
                }.reduce(minWidth) { max($0, $1) }
            }
        }

        var itemSelected: ((Int)->())? = nil
        
        override var preferredContentSize: CGSize { 
            get {
                tableView.layoutIfNeeded()
                return CGSize(width:optionsWidth+32, height:tableView.contentSize.height)
            }
            set {
                println("Cannot set preferredContentSize of this view controller!")
            }
        }
        
        override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
            tableView.scrollEnabled = (tableView.contentSize.height > tableView.frame.size.height)
        }
        
        override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            itemSelected?(indexPath.row)
        }
    }

The main things to note have to do with dealing with the view controller's size. As it is presented in a variable-sized popover, iOS queries our view controller's preferredContentSize for an ideal size. We obtain this size by a two-step process: the height is calculated by making the table view lay itself out and getting the height of its internal scrollable area. We calculate the width is calculated when the list of options is set, by finding the widest option (using map and reduce); we then add 32 to this (as there are 16 points on each side of the label in a standard UITableViewCell). To assist in calculating the width, we add an intrinsicWidthWithFont method to the Option enum, like so:

    enum Option {
        case Text(text:String)
        
        func intrinsicWidthWithFont(font: UIFont) -> CGFloat {
            switch(self) {
            case Text(let t): return NSString(string:t).boundingRectWithSize(
                    CGSize(width:1000, height:1000), 
                    options:.allZeros, 
                    attributes:[NSFontAttributeName: font], 
                    context:nil
                ).width
            }
        }
    }

In the viewWillAppear method, we check if the table view's contents fit within its screen space, and if so, disable scrolling (having the menu move as the user touches it would look a tad disconcerting). If the menu is too big for the popover, scrolling is enabled.

Finally, when the user selects a cell, we just call the callback which was passed.

Making it draggable

So now we have the basics of the popup selector control working; when the user taps the button, it shows a menu in the popover. They can then tap an item, which will close it, set the control's selectedItem, and send out a valueChanged control event. Which is almost what we want. One more thing we'd like to have would be to allow the user to select an item with one gesture; rather than tapping the button and then tapping the item, the user should be able to put their finger on the button, drag to the item in the newly opened popover and release their finger, selecting it. As UITableView doesn't handle drags originating from outside its bounds (not to mention before it was created), we will need to do this manually; and the way we will do so is by attaching a UIPanGestureRecognizer to the control.

We add one line to awakeFromNib:

    override func awakeFromNib() {
.....
        self.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: Selector("dragged:")))
    }

And define the drag handler as follows:

    func dragged(sender: UIPanGestureRecognizer!) {
        if let tableView = currentlyPresentedPopup?.tableView {
            switch(sender.state) {
            case .Changed:
                if let popupContainer = tableView.superview {
                    let pos = sender.locationInView(tableView)
                    if let ip = tableView.indexPathForRowAtPoint(pos) {
                        tableView.selectRowAtIndexPath(ip, animated: false, scrollPosition:.None)
                    }
                }
            case .Ended:
                if let ip = tableView.indexPathForSelectedRow() {
                    currentlyPresentedPopup!.dismissViewControllerAnimated(true) { 
                        self.currentlyPresentedPopup = nil
                        selectedIndex = ip.row
                    }
                }
            default: break
            }
        }
    }

When the drag position moves, it checks if it hits a table row, and if so, selects it; when it ends, if a row has been selected, it stores its value in the control, and closes the popover.

Further steps

The KFPopupSelector control, as described here, performs a simple case of wrapping a popover menu into a control; however, there is plenty of room for expansion.

One obvious place to expand would be to allow options for values other than strings; images would be one possibility, or colours from a palette. This would involve adding cases to the Option enum, like so:

    enum Option {
        case Text(text:String)
        case Image(img: UIImage)
    }

...and, of course, making the appropriate changes in table view cell creation, width estimation and such.

Another possibility would be to replace UITableView with UIContainerView, allowing non-vertical layouts. This would be handy if the options are images or colours, which may be laid out on a grid, or for doing horizontal menus of short pieces of text, as seen in the iOS cut/paste popover.

cocoa touch ios swift uipopoverpresentationcontroller uitableview 0

2015/5/12

Towards a more functional Swift

Swift came into the world as an interesting chimera; fully formed, with a list of interesting and innovative language features not seen before in the Objective C world, borrowed from other languages. Refreshingly, a few of these borrowings were from the world of functional programming. This is not entirely new to Objective C; since the arrival of the block syntax, some basic functional programming has been part of Objective C, at least with add-ons like BlocksKit; Swift, however, took it half a step further; borrowing from the likes of Haskell and Scala, it introduced concepts such as Optional types and pattern-matching. And then, as if not to scare the horses imperative-OO programmers, it stopped short, leaving the minority of seasoned monad-wranglers a little frustrated.

In a sense, one could see the rationale behind this; the iOS and OSX developer ecosystem is an overwhelmingly Objective C-based one, i.e., one grounded in Smalltalk-style object-oriented programming underpinned by the veritable C language (a language developed in the 1970s as a more portable, and higher-level, alternative to assembly language). Functional concepts have made it in slowly, in the form of blocks and closures; filtering into the Cocoa developer mind-set, at first as a variant of that old warhorse, the C callback function, with moderately functional semantics gradually seeping in from JavaScript (i.e., variable-capturing closures) and Python (map, filter and reduce). Then came along Swift, introduced at WWDC 2014, with its own learning curve, and alongside the usual raft of new iOS and OSX technologies. This was a lot to digest in one go, and throwing in category theory would have only confused things.

Gradually, though, awareness of functional programming techniques has spread throughout the Swift community; at developer meetups and in blogs, the denials of the necessity of such new-fangled ideas, and defences of perfectly good object-oriented techniques have given way to exploration of functional ways of doing things. The language has moved forward as well; when 1.2 came out a few months ago, for example, it brought with it the flatMap function, a key building block of various kinds of chainable operations. However, there is still some way to go. Which is why I have written this post as a plausible, and somewhat subjective, roadmap for some of the ways in which Swift could (and, in my opinion, should) develop.

The ideas here are influenced by languages I have worked with; in particular, there is a fair amount of Scala influence here (as Scala's treatment of functional concepts maps reasonably cleanly onto Swift's way of doing things in many cases) and, to a lesser extent, Python.

if let ... as a comprehension

Optionals (i.e., typed containers containing either nothing or one value of a type) are a key part of the Swift way of doing things. Being containers, they may, of course, be mapped over, and Swift provides ways of chaining optionals, following a sequence of operations, each of which may or may not return a non-empty value, and breaking the sequence at the first empty operation. One of these is the if let sequence; i.e.,

func maybeDoSomething(maybeA: Int?, maybeB: String?) -> String? {
  if let a = maybeA, 
    b = maybeB {
      return doSomething(a,b) // returns a String
  }
}

Given that the two Optionals, maybeA and maybeB, are containers which may be mapped (and flatMapped) over, this looks like it ought to be equivalent to the following:

func maybeDoSomething(maybeA: Int?, maybeB: String?) -> String? {
  return maybeA.flatMap { (a:Int) -> String? in 
    return maybeB.map { (b:String)->String in 
      doSomething(a, b) 
    }
  }
}

Seeing it written out this way, though, raises the tantalising possibility of applying it to other mon containers one can map over, such as Arrays; were the two forms equivalent, one could do something like this:

let arr1: [Int] = [1,2,3]
let arr2: [Int] = [5,6]

if let a = arr1, b = arr2 {
  println("\(a*b)")
}
/* prints 5, 6, 10, 12, 15, 18 */

Though one cannot; this is not valid Swift syntax. (And even if it were, may be argued that if let value = array would be rather odd syntax.)

Of course, there is a similar syntax for arrays and sequences with generators; the for _ in _ syntax, familiar from Objective C; which would look slightly less weird if extended to Optionals; we can already do things like:

func doSomeThings(arr: [Int], opt: Int?) {
  for a in arr {
    if let b = opt {
      doSomething(a, b)
    }
  }
}

By extending Generator semantics to Optionals and expanding the for...in statement, one could unify this into:

func doSomeThings(arr: [Int], opt: Int?) {
  for a in arr, b in opt {
    doSomething(a, b)
  }
}

Given that, in this hypothetical parallel-universe Swift, the enhanced, unified version of for..in has usurped a lot of the functionality of if let, it would make sense to go the whole hog and add the where clause to its syntax, allowing arrays to be filtered upon iteration, like so:

func doSomeThings(arr: [Int], opt: Int?) {
  for a in arr where a%2==0, b in opt {
    doSomething(a, b)
  }
}

(Of course, there is no reason why this syntax should work only on Optionals and Arrays; technically, it would apply to anything that's a monad, which, given a well-crafted library, would allow it to be used on, for example, values representing deferred computations (i.e., futures/promises).)

The missing piece

Eagle-eyed readers will have noticed a particular ugliness in the examples above: the inner block in the loop is hideously imperative; in each example, it either calls a hypothetical function (presumably with a side-effect) or printlns the output to the console. This is because Swift's if let and for...in are imperative statements, rather than functional expressions.

Of course, one can do things in a purely functional way if one dispenses with the pseudo-comprehension syntactic sugar of if let and/or for..in and rewrites everything in terms of map, filter and flatMap:

let arr:[Int] = ...
let opt: Int? = ...
  
let result = arr.flatMap { (a:Int)->Int? in 
  return opt.map { (b:Int)->Int in return a+b } 
}

It would be nice to not have to do this; to have a comprehension-style syntax which would let us specify the arrays and options we wish to go through and would assemble the result for us; perhaps it would look something like:

let result = for a in arr, b in opt { 
  return a+b 
}

(The use of the keyword return may be somewhat contentious, as (especially coming from a C background), one might expect it to return from whatever function contains the enclosing code. An alternative, as used in both Python and Scala, may be the keyword yield. But for now, in the interests of diverging as little as possible from Swift as it is, let's stick to return.)

Statements as expressions

Of course, by the time we have gotten here, we not only have functional for-comprehensions à la Scala, but we have, along the way, violated the implicit taboo against turning statements (such as for) into value-returning expressions. Once this is permissible, a wealth of possibilities are opened up. The pattern-matching switch statement, for example, starts to feel more powerful:

let description = switch(object) {
  case .User(let name): return "User '\(name)'"
  case .Group(let name, let members): return "Group '\(name) with \(members.count) members'"
}

Specifically, this would let us get rid of one ugly wart in the Swift language, i.e., initially undefined immutable values of this sort:

let description:String
switch(object) {
  case .User(let name): description = "User '\(name)'"
  case .Group(let name, let members): description = "Group '\(name) with \(members.count) members'"
}

An ugly workaround which, whilst comprehensible on a small scale, has the potential to become unwieldy.

Meanwhile, the C-style for loop could be pressed into service to generate arrays (or sequence types of some sort) on demand:

let squares: [Int] = for var i = 1; i < 5; i += 1 { 
  return i*i 
}

(Were one to omit the [Int] in the return value declaration, the result could be a lazy generator, which would evaluate the loop once for each value that is desired, which would lend itself to all kinds of lazy functional algorithms.)

And, of course, there is if, which would be merely a more verbose of the old C ? : operator:

let v1 = if a == 1 then "foo" else "bar"
let v2 = (a==1) ? "foo" : "bar"

In short, Swift as it stands (at version 1.2) is a few pieces of syntactic sugar away from being a much more elegant (and functional) language.

functional programming monads swift 2

2015/3/15

Swift snippets: flatMap and layout constraints

Since version 6, iOS has had a constraint-based layout engine for laying out views The constraint-based layout engine in iOS is considerably more powerful than the old system of auto-layout hints, allowing reasonably sophisticated flexible layouts to be specified purely as systems of constraints. However, it can be cumbersome to set up if creating all constraints individually; any reasonably complicated layout will soon have dozens of NSLayoutConstraint(item:attribute:relatedBy:toItem:attribute:multiplier:constant:) lines padding out its construction code, making one wonder why not just cut the Gordian knot and write code to manually lay out the view, as in the old days?

Fortunately, Apple provide a shortcut: the NSLayoutConstraint.withVisualFormat method; which takes a string describing the relationships between elements in an ASCII-art-style syntax known as the Visual Format Language, a few options and a dictionary of elements and emits a list of NSLayoutConstraints, as so:

let viewsDict:[NSObject:AnyObject] = [
    "lBtn" : leftButton,
    "rBtn" : rightBtn,
    "title" : titleLabel
]
let constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-12-[lBtn(30)]-6-[title]-6-[rBtn(30)]-12-|", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict)
myView.addConstraints(constraints)

As implied, each constraintsWithVisualFormat call takes a line of visual format language and produces an array of zero or more constraints; the line above, for example, would produce six; four distance constraints and two size constraints. However, one such line is rarely enough to unambiguously specify the constraints for a view and its contents; most layouts would require more than one line of visual format language to specify their constraints. The above, for example, covers only horizontal constraints; adding vertical ones to the mix would involve a second line, like so:

let constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-12-[lBtn(30)]-6-[title]-6-[rBtn(30)]-|", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict) + 
    NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[title(20)]", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict)
myView.addConstraints(constraints)
Which gives two more constraints on the title label view: a distance from the top edge of the superview and a height. But what about the buttons?
let constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-12-[lBtn(30)]-6-[title]-6-[rBtn(30)]-|", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict) + 
    NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[title(20)]", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict) +
    NSLayoutConstraint.constraintsWithVisualFormat("V:|-5-[lBtn(30)]", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict) +
    NSLayoutConstraint.constraintsWithVisualFormat("V:|-5-[rBtn(30)]", 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict)
myView.addConstraints(constraints)
All of which soon starts to get somewhat unwieldy; there's a lot of repeated boilerplate there, which suggests that one could refactor it.

We could minimise the boilerplate by putting the visual format strings in an array of strings and mapping over them with constraintsWithVisualFormat. That would give us an array of arrays of constraints, which we could then flatten using reduce, like so:

let visualConstraints = [
  "H:|-12-[lBtn(30)]-6-[title]-6-[rBtn(30)]-|",
  "V:|-10-[title(20)]", ...
]
let constraints = visualConstraints.map { 
  NSLayoutConstraint.constraintsWithVisualFormat($0, 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict)
}.reduce([], { $0 + $1 })
myView.addConstraints(constraints)
Which is somewhat better, though it can be improved. As of Xcode 6.3, arrays (and optionals) in Swift will have a new operation named flatMap, which combines the map and flatten steps. In short, where a map takes a container of some values of type A and a function that converts an A to a B and returns a container of the same number of values of type B, flatMap takes the same array and a function that converts an A to a container of zero or more Bs, and returns a container of some number of Bs. In any case, with flatMap, the above code reduces to:
let visualConstraints = [
  "H:|-12-[lBtn(30)]-6-[title]-6-[rBtn(30)]-|",
  "V:|-10-[title(20)]", ...
]
let constraints = visualConstraints.flatMap { 
  NSLayoutConstraint.constraintsWithVisualFormat($0, 
        options:NSLayoutFormatOptions(0), metrics:nil, views:viewsDict)
}
myView.addConstraints(constraints)
flatMap is a useful operation, and one whose uses one can see in many places. In general, whenever a process produces zero or more items of output for each input, one wants to use a flatMap to handle them. Swift is also introducing flatMap on Optionals (which, of course, may be seen as a container holding zero or one items of a type), where it can be used for chaining a number of functions which may or may not yield a value:
func getCurrentUserIcon(session: Session?) -> UIImage? {
  return getUser(session).flatMap { getIconForUser($0) }
}
This is a little like Swift's optional chaining, with the key difference that, while optional chaining is limited to calling the underlying objects' methods, flatMap can apply any expression yielding an Optional; a move away from the object-oriented paradigm of objects and methods towards more functional techniques.

Unsurprisingly, flatMap is much more common in functional programming. The presence of a flatMap operation is one of the defining criteria of a pattern known as the monad, which, in a functional paradigm, can be used to define everything from container types to asynchronous operations to ways of compartmentalising state in functions without side-effects, in a way that follows consistent laws. Languages like Haskell and Scala use monads extensively, defining the relevant types in a consistently monadic fashion. And while Swift is not a functional language per se, it has been speculated for a while that it may be moving in an increasingly functional direction (albeit perhaps sufficiently gradually as not to alienate old Objective C hands); the arrival of flatMap could be more grist to this mill.

autolayout functional programming ios monads swift 0

This will be the comment popup.
Post a reply
Display name:

Your comment:


Please enter the text in the image above here: