Where technology meets something or other

Archive for the ‘Swift’ Category

Applying mutableCopy() to an NSObject returns Any, not the version of the type you’re attempting to make mutable, for example, NSMutableArray, NSMutableParagraphStyle, NSMutableAttributedString or whatever.

Nate asks:

Is is acceptable to use as! with mutableCopy() or is there a better way to do this?

The forced as! cast used in this approach will always succeed (even if using as! makes you want to wash your hands afterwards). But there are other approaches to consider. What do you think of these alternative takes on the question? Here are some other solutions for you to weigh in on.

Yesterday, I was chatting about ways to partition a stream of values. I wanted to collect values into new streams: values that satisfied a predicate, and those that did not. A number of hugely complicated approaches were discussed until Nate Cook brought up a fantastic new Swift 4.0 API. The Dictionary type’s init(grouping:by:) call allows you to convert any sequence to a dictionary by grouping its elements.

Pass the initializer a sequence and a closure, and the initializer creates entries for each value returned by the closure. For a predicate, you end up with two groups: one populated for true predicate values, one for false:

Once partitioned, you can pull values from each collection (true and false) and operate on the members of that particular group:

// Iterate through the even members of this sequence
for number in (grouping[true, default:[]]) { ... }

This example uses Swift’s new default value in its grouping look-up:

grouping[true, default:[]]

If you haven’t started using this new feature, you should really adopt it into your work flow. It’s wonderful. With this call, a dictionary returns the default value when a key is not found. This avoids forced unwraps (dictionary lookups normally return optionals) and acts as an alias for nil coalescing. In this example, the default call is an alias for (grouping[true] ?? []).

Dictionary grouping provides a solid solution for sequence partitioning by predicates. But you can also do a lot more with this API. Let me give you a bunch of examples that showcase the power of this one little call.

This example creates a dictionary of names grouped by first letter. Swift creates an entry for each unique capitalized letter it finds within the name collection:

You could easily expand this example to disregard diacritical marks by stripping them through a StringTransform. (This approach is left as an exercise for the reader.😀 )

In more realistic text-based grouping, the information you want to group on is often a level or two down within a structure. Swift keypaths make it easy to access the information you need for grouping. This next example constructs a keypath to a contact’s last name, and uses that keypath to provide the partition keys for the dictionary.

Grouped dictionaries aren’t limited to strings and numbers. They can be quite helpful when working with interface elements. For example, in a complex user-managed presentation, you might group button views based on their control state:

Although all the examples so far have used sequence data to produce the keys used in grouping, those keys needn’t be pulled directly from the values they categorize. Enumerations make a great Swift choice for categorizing data. This example revisits the even/odd grouping shown in the first example of this write-up but replaces the true/false predicate values with a Parity enumeration.

You can use this same approach with more extensive enumerations and more complicated data. That said, you can take exactly this example, and simplify it enormously by grouping numbers based on a simple function. For example, you can use the direct results of the modulo operator (which returns 1 and 0) as the keys to your grouped dictionary:

let parity2 = Dictionary(grouping: 0 ..< 10) { $0 % 2 }

In the end, it’s up to you on how you want to split your sequence, and the keys you want to represent the subsequences derived from that split. Hopefully this post has given you a few ideas to inspire your own partitioning schemes.

This code doesn’t look too bad, but it’s a pain to write var description = "" and return description over and over, if this is a pattern you commonly use. It’s also quite easy to forget to add \n to each line.

The relatively unknown standard library protocol TextOutputStreamable solves both of these problems for you. Rather than adding a description computed property, all you have to do is write your properties to a TextOutputStream instance:

Foundation’s URLQueryItem is just a stringly-typed key-value pair. You create one with a name and value:

public init(name: String, value: String?)

Since Swift supports literal initialization, you’d think you could use a dictionary to set up a [URLQueryItem] array, right? Well, yes and no.

You can’t just conform Array where Element == URLQueryItem to ExpressibleByDictionaryLiteral. Array extensions with constraints cannot have inheritance clauses. There are several ways around this limitation.

First (and best), you can just map an initializer across a dictionary literal:

Third, you could use some kind of intermediate type to produce a URL query item array using Swift shortcuts. For example, you can set up a struct that builds the query item array and then pull from there:

Starting in Swift Playgrounds 2, you can now use localized strings to guide the narration of your interactive lessons. As the screenshot above demonstrates, you can used localizable markup to provide the most appropriate text for titles, introductory text, and feedback.

However, what you can’t do is localize Swift members. Your French and Chinese consumers must tell Byte to moveForward(), not avancer() or 向前移动().

One of the guiding principles of the Swift language is demonstrated in its embrace of unicode for identifier symbols. This approach accommodates programmers and programming styles from many languages and cultures.

Xcode 9 has introduced major advances in code refactoring. It seems an obvious win to allow that technology to be applied to Swift Playgrounds 2, enabling identifier localization.

That’s because identifiers play such a key role in Swift Playgrounds. Unlike standard development tasks, where it’s unnecessary to create idiomatic APIs like IUContrôleurDeNavigation, the point of Swift Playgrounds is to teach and instruct. It uses small, limited, controlled API exposure, nearly all custom and supporting of the teaching story.

The anthropomorphized Byte character acts as a stand-in for the learner coder. And in doing so, it should communicate with commands that this coder identifies with, turnLeft and moveForward, not incomprehensibleForeignPhrase1 and evenMoreConfusingForeignPhrase2.

I think this is an opportunity waiting to happen, and I can’t imagine it would be all that hard to implement given the expansive identifier suite and the limited API visibility presented in a typical playgroundBook.

What do you think? Is it too much to ask for a localizable.Members.plist?

From Rick Ballard, Swift Package Manager release manager, a status update with regard to Swift 4. Here’s an overview of the proposals that have recently been incorporated into the system:

We’ve implemented a number of evolution proposal[s] this Spring:

• SE-0152 [ https://github.com/apple/swift-evolution/blob/master/proposals/0152-package-manager-tools-version.md ] introduced a “tools version”, stored in a comment at the top of the Package.swift manifest, which allows you to declare what version of the Swift tools your package requires, and to avoid resolving package dependencies against package versions which require newer tools than those you are using. The tools version is also used to control whether to enable new features such as the revised package manifest API, and to determine which Swift language version is used to interpret the manifest.

Xcode 9 lays the groundwork for first-class, native support in Xcode for Swift packages with the preview version of its new build system. This build system provides the flexibility and extensibility needed to allow Xcode to support new build models, such as Swift packages. Additionally, considerable work has gone into the SwiftPM library vended by the SwiftPM project, which will support integrating Swift packages into tools like Xcode.

There are a few features that we originally considered for SwiftPM 4 which are unlikely to be included in this release at this point: performance test support, support for configuration files, support for repositories which contain more than one package, and build settings support. With the possible exception of configuration files, these are likely to be a high priority for the next release. In particular, the core team has done work on a design for build settings which we expect to invite comment and discussion on early in the next release; this is a fairly consequential feature, and we want to make sure to get it right. Since that feature is not landing in SwiftPM 4, we are considering adding some package properties in SwiftPM 4 that will help alleviate some of the biggest pain points here, such as a C++ language version property.

Other features we will likely consider for the next release cycle include support for package resources (such as image assets), license and metadata support, explicit support for handling source control forking, and a generic mechanism for invoking build tools that the package manager doesn’t natively support. Finally, we do anticipate supporting a centralized package index at some point in the future, and we may begin laying the groundwork for that in the upcoming year.

As always, we appreciate the support, feedback, contributions, and adoption we’ve gotten from the package manager community. We’re looking forward to working with you all over the upcoming year to make SwiftPM even better.

This afternoon at WWDC we announced a new refactoring feature in Xcode 9 that supports Swift, C, Objective-C, and C++. We also announced we will be open sourcing the key parts of the engine that support file-level transformations, as well as the compiler pieces for the new index-while-building feature in Xcode.

We will be releasing the sources in stages, likely over the next few weeks:

– For the refactoring support for Swift, there are some cleanups we’d like to do as well as some documentation we’d like to author before we push these sources back. Argyrios Kyrtzidis and his team from Apple will be handling that effort.

– For the refactoring support for C/C++/Objective-C, these are changes we’d like to work with the LLVM community to upstream to the LLVM project. These will likely be first staged to the swift-clang repository on GitHub, but that is not their intended final destination. Duncan Exon Smith and his team from Apple will be handling that effort.

– We’ll also be open sourcing the compiler support for indexing-while-building, which include changes to both Clang and Swift. Argyrios and his team will be driving that effort. For the clang changes they will likely be first staged to swift-clang, and then discussed with the LLVM community to upstream them to mainline Clang.

– Finally, we will be open sourcing the remaining pieces of the Swift migrator. Argyrios and his team will be handling the push back of changes there, and those changes will only be impacting the swift repository.

As usually, we’ll also be pushing back changes to have Swift work with the latest Apple SDKs. We’re expecting that push back to happen early next week. When that happens we will temporarily lock commit access to the repositories. Details about that will be sent out later in a later email. Until then, the downloadable toolchains from Swift.org will continue to work with Xcode 8.3.2. After we do the push back the downloadable toolchains will be moved to be baselined on the Xcode 9.0 betas. This shift is necessary as changes to the overlays depend on the latest SDKs.

Tim discusses using Swift enumeration indirect keywords to build binary tree nodes. Read on to learn more about how reference types and value semantics combine…

Today we’re writing a simple binary search tree in Swift. While binary search trees seem to be very powerful in theory, their performance is rather disappointing in practice. Other, more advanced tree-shaped data structures such as red-black trees and B-trees solve some of the practical problems that binary search trees have, and are subsequently much more useful in performance-critical code. Nevertheless, learning about binary search trees is the first step to getting more familiar with this class of data structures.

Probably the simplest way to represent a binary tree in Swift is by using an indirect enum, like so:

While indirect enums use reference types under the hood, they have value semantics by default. So that’s nice.

From all the standard library’s protocols, SetAlgebra and BidirectionalCollection both seem a good fit for our BinarySearchTree type: SetAlgebra for inserting and removing elements, and BidirectionalCollection for traversing the tree (both forwards and backwards, hence the name). However, for the purpose of this post, we’ll stick to only a couple basic methods.

Let’s start with insertion. Because of the way enums with associated values work, it’s easiest to implement the insert method using an under-the-hood inserting method:

That’s it for now! If you enjoy this kind of stuff, make sure to check out Károly Lőrentey’s brand new book Optimizing Collections in which he in much detail goes through implementing several data structures in Swift, focusing on performance. As of writing this post, it’s 25% off.

Cocoa distinguishes NSArray from NSMutableArray, among many other mutable variations on standard types. In Swift, you var or let a collection and let the compiler handle the rest of the details, whether the outcome is mutable or not. Kotlin follows the Cocoa model. It uses distinct collection types based on mutability.

For example, the listOf function returns a new read-only serializable list of elements.

val myList: List<Double> = listOf(1.0, 2.0, 3.0)

You cannot automatically promote typeless literals the way you can in Swift. In Swift the literal “1” doesn’t have an intrinsic type (although it defaults to Int in the absence of any other context). “1” can represent an integer, a double, a float, and more.

Kotlin does not support literal inference. If you use listOf(1, 2, 3) for the preceding example, Kotlin issues an error: “Type inference failed. Expected type mismatch: inferred type is List<Int> but List<Double> was expected”.

Like Swift, Kotlin’s type inference system permits you to drop the explicit List<Double> type annotation from the myList declaration. The listOf function still produces the expected type, which the compiler assigns to the constant myList. In this declaration, Kotlin’s val is the same as Swift’s let. It produces a constant rather than a (var) variable.

However, the list you produced is not a value type. Switch the list from immutable to mutable, and you’ll still (like an NSMutableArray reference) be able to add new members:

You won’t be able to re-assign myList to a new list, but as a mutable reference type, the underlying instance can be modified because it is a MutableList<T>.

Kotlin also offers dictionaries, which it calls maps. That’s really not a bad name for a type that performs one-to-one mapping, which is all that key-value lookup really does. The underlying types honor that key/value relation. They’re called Map<K, out V> and MutableMap<K, V>.

Like Swift, Kotlin returns a “not there” result for a failed map lookup, but the meaning of null is distinct from Swift’s nil. A type must be nullable (sort of but not entirely like Optional) to store a null reference.

The initial value of string2 is not Optional("hello") or something like that. It feels (at least so far, because I know nothing about Kotlin, see the title of this post) more like the Objective-C nil, that is a null-reference in memory rather than a pointer to a reference type. I’m new to this, so I’m still learning.

Speaking of null, the first string example demonstrates what happens when you assign null to a non-nullable type. You end up with a (more or less) null pointer exception, which is a bad thing.

Getting back to collections, Kotlin also supports sets, both mutable and immutable. All three types: lists (arrays), maps (dictionaries) and sets (sets), inherit from Kotlin Collection, and in turn from Kotlin Iterable. All three types have a way to count the number of elements (or entries), they can be iterated over, and Collection offers many methods that may or may not apply to each type. For example, you don’t use dropWhile on a map/dictionary.

The Collections reference page lists which functions apply to which types. It’s a bit hodgepodge compared to Swift’s cleaner, hierarchical, and protocol-based system. That said, all the things you would expect to do to an array, set, or dictionary in Swift, you can do to a list, set, or map in Kotlin. Have a browse through that Collections page to get a sense of the functionality. It’s all pretty familiar.

If anything, the various subtypes (LongArray, ByteArray, IntArray, etc) feel like overkill and the available functions feel a tiny bit bloated. But that’s me looking at this stuff with Swift-ized eyes.

If you like this series of posts, let me know. Drop a tweet, email, or comment if you’d like me to keep going.

Pick up a copy of Swift Style with a nice discount. The ebook will be 25% off the normal price during WWDC. Use the coupon code Swift_WWDC_2017 at checkout to apply this dub-dub discount to your purchase of the Swift Style ebook at Pragmatic Programmers. (If you encounter any problems during checkout, contact support@pragprog.com.)

Thank you for reading my blog and supporting me and my books!

Update: the discount is already live. You don’t have to wait until next week: